所用工具: 1、芯片:STM32F407ZET6/ STM32F103ZET6 2、STM32CubeMx软件 3、IDE:MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 知识概括: 通过本文您将学到:
什么是PWM脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。 PWM工作原理SMT32F1系列共有8个定时器: 高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。 SMT32F4系列共有15个定时器: 高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5、TIM9~TIM14);基本定时器(TIM6、TIM7)。 STM32的每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。 STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可以同时产生7路PWM输出。 原理讲解: 下图为向上计数模式:
PWM的一个周期:
总结:每个定时器有四个通道,每一个通道都有一个捕获比较寄存器, 将寄存器值和计数器值比较,通过比较结果输出高低电平,便可以实现脉冲宽度调制模式(PWM信号)。TIMx_ARR寄存器确定PWM频率,TIMx_CCRx寄存器确定占空比。 若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。 而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。 PWM的工作模式:
设置寄存器TIMx_CCMR1的OC1M[2:0]位来确定PWM的输出模式:
在两种模式下TIMx_CNT(计数器当前值)与TIMx_CCR1(捕获/比较值) 只是决定是有效电平还是无效电平。有效电平可以是高电平也可以是低电平,这需要结合CCER寄存器的CC1P位的值来确定。 PWM的工作过程 1、CCR1寄存器:捕获/比较值寄存器:设置比较值。 计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平。
2、TIMx_CCMR1寄存器:OC1M[2:0]位:用于设置PWM模式。
3、CCER寄存器:CC1P位:输入/捕获1输出极性。
4、CCER寄存器:CC1E位:输入/捕获1输出使能。
5、输出电平信号。 TIM定时器的四路通道TIMx_CHx输出PWM摘自:《STM32中文参考手册》254页 通用定时器框图 附:STM32定时器输出通道引脚具体不同定时器对应引脚在对应芯片数据手册的引脚说明(pin description) 中查看,这里我们以TIM3_CH1 PA6作为讲解。 工程创建过程1.设置RCC 设置高速外部时钟HSE 选择外部时钟源 2.设置定时器
Channel1~4 就是设置定时器通道的功能:
在 Parameter Settings 页配置预分频系数为 71,计数周期(自动加载值)为 499,定时器溢出频率,即PWM的周期,就是 72MHz/(71 1)/(499 1) = 2kHz。 PWM频率: Fpwm =Tclk / ((arr 1)*(psc 1))(单位:Hz) arr 是计数器值 psc 是预分频值 占空比:
比如: 定时器频率Tclk = 72Mhz,arr=499,psc=71,那么PWM频率就是720000/500/72= 2000Hz,即2KHz。 如果arr=499,TIM3->CCR1=250,则pwm的占空比为50%。改CCR1可以修改占空比,修改arr可以修改频率。 3.时钟源设置 32的时钟树框图 如果不懂的话请看《【STM32】系统时钟RCC详解(超详细,超全面)》
4.项目文件设置
5.创建工程文件 点击GENERATE CODE 创建工程。 新建的工程所有配置都是默认的 我们需要自行选择下载模式,勾选上下载后复位运行。 例程 这里我们创建一个呼吸灯的例程 定义变量: /* USER CODE BEGIN 1 */ uint16_t pwmVal=0; //PWM占空比 uint8_t dir=1; /* USER CODE END 1 */ 使能TIM3的PWM Channel1 输出: /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); /* USER CODE END 2 */ 在while循环中添加代码: while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
while (pwmVal< 500) { pwmVal ; __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 // TIM3->CCR1 = pwmVal; 与上方相同 HAL_Delay(1); } while (pwmVal) { pwmVal--; __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 // TIM3->CCR1 = pwmVal; 与上方相同 HAL_Delay(1); } HAL_Delay(200);
/* USER CODE END 3 */ } 或者直接修改CCRx寄存器的值: htim3.Instance->CCR1 = 300; //通过 htim3.Instance->即可访问与定时器相关寄存器 实验现象如下: |
|