本实验采用STM32MP157A
头文件:
#ifndef __PWM_H__
#define __PWM_H__#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_tim.h"
#include "stm32mp1xx_rcc.h"
//仨头文件里是别人封装好的地址结构体和宏定义//初始化
void pwm_init();//风扇
void fen_init();//马达
void mada_init();
#endif
功能函数
原理上大同小异,本文以风扇为例。(PF9引脚)
一: 首先是RCC寄存器使能GPIOE和TIM1
查芯片手册可知,GPIOF为AHB4总线,TIM1为APB2总线
//RCC PE9使能(GPIOE)RCC->MP_AHB4ENSETR |= (0x1 << 4);//TIM1使能 [0] = 1RCC->MP_APB2ENSETR |= (0x1 << 0);
二. GPIO初始化
设置引脚复用模式
查手册知,输出模式为AFRH[7:4] = 0x1000
/*********GPIO章节初始化**************///设置引脚复用模式 GPIOE[19:18] = 0x01GPIOE->MODER &= (~(0x3 << 18));GPIOE->MODER |= (0x2 << 18);//设置为AF1:0001 ,AFRH[7:4]GPIOE->AFRH &= (~(0xf << 4));GPIOE->AFRH |= (0x1 << 4);
三 TIM1设置
根据系统处理图,
1. 先设置分频器 系统提供时钟源 209MHz 209
TIM1->PSC &= ~(0xffff);
TIM1->PSC |= 0xd0; //208
2.设置PWM方波最终周期1000Hz 对自动重载计数器进行赋值 1000
TIM1->ARR &= ~(0xffff);
TIM1->ARR |= (0x3E8); //1000
3.设置PWM方波占空比 对比较/捕获寄存器进行赋值 700
TIM1->CCR1 &= (~(0xffff));TIM1->CCR1 |= (0x2bc);
4.设置TIM1_CH1通道为PWM1模式
设置pwm1模式TIM4_CCMR1的16、[6:4] = 0110
TIM1->CCMR1 &= (~(0x1 << 16)); //16位置0
TIM1->CCMR1 &= (~(0x7 << 4)); //6~4位清零
TIM1->CCMR1 |= (0x6 << 4); //置为110
5.设置TIM1_CH1通道预加载使能
TIM1->CCMR1 |= (0x1 << 3);
6.设置TIM1_CH1通道为输出模式
TIM1->CCMR1 &= (~(0x3 << 0));
7.设置TIM1_CH1通道输出模式极性高电平
TIM1->CCER &= (~(0x1 << 1));
8.设置TIM1_CH1通道比较捕获寄存器输出使能
TIM1->CCER |= (0x1 << 0);
9~12步
//9.设置TIM1_CH1通道自动重载计数器预加载使能
TIM1->CR1 |= (0x1 << 7);//10.设置TIM1_CH1通道采用边沿对其方式
TIM1->CR1 &= (~(0x3) << 5);//11.设置TIM1_CH1通道采用递减计数方式
TIM1->CR1 |= (0x1 << 4);//12.设置TIM1_CH1通道计数器使能
TIM1->CR1 |= (0x1 << 0);
*13.TIM1_BDTR,注意,此为风扇和马达特有的寄存器,蜂鸣器没有
TIM1->BDTR |= (0x1 << 15);
另外俩元件,TIMx寄存器设置方式相同,只是TIMx寄存器编号不同。而RCC寄存器使能和GPIO寄存器设置,则因为三个元件的引脚所在总线和引脚号的区别,导致都完全不同,要查表写。
以下附上完整代码,注意,因为不同芯片的引脚、总线可能不尽相同,此代码仅供参考,切勿照抄
#include "pwm.h"void pwm_init()
{
/***********RCC初始化**************///使能GPIOBRCC->MP_AHB4ENSETR = (0x1 << 1);RCC->MP_APB1ENSETR = (0x1 << 2); /*****GPIO章节初始化*****/GPIOB->AFRL &= (~(0xf << 24));GPIOB->AFRL |= (0x2 << 24);//设置PB6引脚为输出模式//GPIOB_MODER[13:12] = 0b01GPIOB->MODER &= (~(0x3 << 12));GPIOB->MODER |= (0x2 << 12);/***********TMI4寄存器**************///TIM4_PSC寄存器TIM4->PSC &= ~(0xffff);TIM4->PSC |= 0xd0; //208//TIM4_ARR寄存器 自动重载寄存器TIM4->ARR &= ~(0xffff);TIM4->ARR |= (0x3E8); //1000//TIM4_CCMR1寄存器//设置pwm1模式TIM4_CCMR1 16 [6:4] = 0110TIM4->CCMR1 &= (~(0x1 << 16)); //16位置0TIM4->CCMR1 &= (~(0x7 << 4)); //6~4位清零TIM4->CCMR1 |= (0x6 << 4); //置为110//设置预加载使能TIM4_CCMR1[3] = 1TIM4->CCMR1 |= (0x1 << 3);//设置为输出模式 TIM4_CCMR1[1:0] = 00TIM4->CCMR1 &= (~(0x3 << 0));//TIM4_CCER寄存器//设置为输出模式
// TIM4->CCER |= (0x1 << 3);//设置起始位高电平TIM4->CCER &= (~(0x1 << 1));//配置输出使能TIM4->CCER |= (0x1 << 0);//TIME4_CCR1TIM4->CCR1 &= (~(0xffff));TIM4->CCR1 |= (0x12c);//TIM4_CR1寄存器//自动承载计数器预加载使能TIM4->CR1 |= (0x1 << 7);//设置边沿对齐模式TIM4->CR1 &= (~(0x3) << 5);//设置递减计数器TIM4->CR1 |= (0x1 << 4);//设置计数器使能TIM4->CR1 |= (0x1 << 0);
}void fen_init()
{//RCC PE9使能(GPIOE)RCC->MP_AHB4ENSETR |= (0x1 << 4);//TIM1使能 [0] = 1RCC->MP_APB2ENSETR |= (0x1 << 0);/*********GPIO章节初始化**************///设置引脚复用模式 GPIOE[19:18] = 01GPIOE->MODER &= (~(0x3 << 18));GPIOE->MODER |= (0x2 << 18);//设置为AF1:0001 ,AFRH[7:4]GPIOE->AFRH &= (~(0xf << 4));GPIOE->AFRH |= (0x1 << 4);/***********TMI1寄存器***************///1.设置分频器 系统提供时钟源 209MHz 209TIM1->PSC &= ~(0xffff);TIM1->PSC |= 0xd0; //208//2.设置PWM方波最终周期1000Hz 对自动重载计数器进行赋值 1000TIM1->ARR &= ~(0xffff);TIM1->ARR |= (0x3E8); //1000//3.设置PWM方波占空比 对比较/捕获寄存器进行赋值 700TIM1->CCR1 &= (~(0xffff));TIM1->CCR1 |= (0x2bc);//4.设置TIM1_CH1通道为PWM1模式//设置pwm1模式TIM4_CCMR1 16 [6:4] = 0110TIM1->CCMR1 &= (~(0x1 << 16)); //16位置0TIM1->CCMR1 &= (~(0x7 << 4)); //6~4位清零TIM1->CCMR1 |= (0x6 << 4); //置为110//5.设置TIM1_CH1通道预加载使能TIM1->CCMR1 |= (0x1 << 3);//6.设置TIM1_CH1通道为输出模式TIM1->CCMR1 &= (~(0x3 << 0));//7.设置TIM1_CH1通道输出模式极性高电平TIM1->CCER &= (~(0x1 << 1)); //8.设置TIM1_CH1通道比较捕获寄存器输出使能TIM1->CCER |= (0x1 << 0);//9.设置TIM1_CH1通道自动重载计数器预加载使能TIM1->CR1 |= (0x1 << 7);//10.设置TIM1_CH1通道采用边沿对其方式TIM1->CR1 &= (~(0x3) << 5);//11.设置TIM1_CH1通道采用递减计数方式TIM1->CR1 |= (0x1 << 4);//12.设置TIM1_CH1通道计数器使能TIM1->CR1 |= (0x1 << 0);//13.TIM1_BDTR TIM1->BDTR |= (0x1 << 15);
}void mada_init()
{//RCC PF6使能(GPIOE)RCC->MP_AHB4ENSETR |= (0x1 << 5);//TIM16使能 [0] = 1RCC->MP_APB2ENSETR |= (0x1 << 3);/*********GPIO章节初始化**************///设置引脚复用模式 GPIOE[13:12] = 01GPIOF->MODER &= (~(0x3 << 12));GPIOF->MODER |= (0x2 << 12);//设置为AF1:0001 ,AFRH[27:24]GPIOF->AFRL &= (~(0xf << 24));GPIOF->AFRL |= (0x1 << 24);/***********TMI1寄存器***************///1.设置分频器 系统提供时钟源 209MHz 209TIM16->PSC &= ~(0xffff);TIM16->PSC |= 0xd0; //208//2.设置PWM方波最终周期1000Hz 对自动重载计数器进行赋值 1000TIM16->ARR &= ~(0xffff);TIM16->ARR |= (0x3E8); //1000//3.设置PWM方波占空比 对比较/捕获寄存器进行赋值 300TIM16->CCR1 &= (~(0xffff));TIM16->CCR1 |= (0x2bc);//4.设置TIM1_CH1通道为PWM1模式//设置pwm1模式TIM4_CCMR1 16 [6:4] = 0110TIM16->CCMR1 &= (~(0x1 << 16)); //16位置0TIM16->CCMR1 &= (~(0x7 << 4)); //6~4位清零TIM16->CCMR1 |= (0x6 << 4); //置为110//5.设置TIM1_CH1通道预加载使能TIM16->CCMR1 |= (0x1 << 3);//6.设置TIM1_CH1通道为输出模式TIM16->CCMR1 &= (~(0x3 << 0));//7.设置TIM1_CH1通道输出模式极性高电平TIM16->CCER &= (~(0x1 << 1)); //8.设置TIM1_CH1通道比较捕获寄存器输出使能TIM16->CCER |= (0x1 << 0);//9.设置TIM1_CH1通道自动重载计数器预加载使能TIM16->CR1 |= (0x1 << 7);//10.设置TIM1_CH1通道采用边沿对其方式TIM16->CR1 &= (~(0x3) << 5);//11.设置TIM1_CH1通道采用递减计数方式TIM16->CR1 |= (0x1 << 4);//12.设置TIM1_CH1通道计数器使能TIM16->CR1 |= (0x1 << 0);//13.TIM1_BDTR TIM16->BDTR |= (0x1 << 15);
}