利用STM32的定时器输出PWM方波

发布于:2024-07-02 ⋅ 阅读:(18) ⋅ 点赞:(0)
        脉冲宽度调制 (PWM) ,是英文“ Pulse Width Modulation ”的缩写,简称脉宽调制,是利用
微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽
度的控制。
       
        图中,我们假定定时器工作在向上计数 PWM 模式,且当 CNT<CCRx 时,输出 0 ,当 CNT>=CCRx 时输出 1 。那么就可以得到如上的 PWM 示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平 (0) ,当 CNT 值大于等于 CCRx 的时候,IO 输出高电平 (1) ,当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。 改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。(PS:操作寄存器请大家自行查阅手册,我这里还是只演示CubeMX+HAL库函数)。
      下面来操作CubeMX输出PWM,首先还是选择外部晶振开启总线调试接口;接下来有个关键点,配置挂载tim的时钟总线频率,我这里统一用了72M;
      然后是第二个关键点,选择时钟模式,时钟源选择Internal Clock,然后开启对应的通道并选择PWM生成模式。
       最后一个配置要点参数设置,首先明确一点,一组高低电平组成的PWM波形的周期计算公式如下:T=\frac{(Prescaler+1)*(Counter Period+1)}{Ftim},其中Prescaler是预分频系数,Counter Period是自动重装载寄存器里存储的计数周期,Ftim是挂载TIM的时钟总线上的时钟信号频率。计数模式一般习惯性选择向上计数(Count Mode选择UP),内部时钟预分频不用,影子寄存器可以使能一下。

       触发输出参数选择中触发事件选择复位Reset,主从模式选择disable。

       最后的PWM生成参数,PWM模式选择模式1,两者的区别是

  1. PWM mode 1
    • 在向上计数中,当计数值小于CCR(捕获/比较寄存器)值时,PWM输出高电平;当计数值大于CCR值时,PWM输出低电平。
    • 在向下计数中(如果存在中心对齐模式),当计数值小于CCR值时,PWM输出低电平;当计数值大于CCR值时,PWM输出高电平。
    • 这种模式下,PWM信号的输出逻辑在低电平和高电平之间切换,以控制PWM的占空比。
  2. PWM mode 2
    • 在向上计数中,当计数值小于CCR值时,PWM输出低电平;当计数值大于CCR值时,PWM输出高电平。
    • 在向下计数中(如果存在中心对齐模式),当计数值小于CCR值时,PWM输出高电平;当计数值大于CCR值时,PWM输出低电平。
    • 与PWM mode 1相反,这种模式下PWM信号的输出逻辑在高电平和低电平之间切换,以控制PWM的占空比。
     我们可以先试着用CubeMX配置固定占空比的PWM方波,这种需求只需要一行hal库代码就能实现。主要精力放在填写参数上,首先将预分频系数设置为7199,计数周期为4999,挂载在一个72Mhz的时钟线上,所以理论上一对高低电平组成的周期为0.5s。然后将PWM Generation Channel4中的Pulse设置为2000(理论占空比为2000/5000=0.4),极性设置为低(我的开发板上的LED灯低电平点亮),随后生成代码。
在TIM初始化函数中直接开启PWM。
  /* USER CODE BEGIN TIM3_Init 2 */
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
  /* USER CODE END TIM3_Init 2 */

观察示波器波形,可以看到高低电平周期为500ms,其中300ms输出高电平,200ms输出低电平,和理论值相符合。LED灯只是不停地闪烁,并没有实现呼吸灯效果。

当然更多时候占空比需要可调,我来演示一下pluse占空比选择0,输出比较预装载寄存器需要使能,快速模式可以关闭,极性选择高。

生成代码至IDE开始调参。
①命名一个占空比变量
  /* USER CODE BEGIN 1 */
  uint16_t pwm=0;      //调控占空比
  /* USER CODE END 1 */

②主循环里写逻辑功能

    /* USER CODE BEGIN 3 */
		while(pwm<499)
	  {
		  pwm++;
		  __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_4, pwm);    //通过修改比较值来改变占空比
	  }
	  while(pwm)
	  {
		  pwm--;
		  __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_4, pwm);    //通过修改比较值来改变占空比
		  HAL_Delay(1);
	  }
	  HAL_Delay(200);
  }
  /* USER CODE END 3 */

观察示波器波形论证结果

宏观来讲,每个循环最后延时200ms已经实现。

每个高低电平组成的周期实测500us,理论值(71+1)*(499+1)/72000000=0.0005s基本符合。

占空比大致为80%,输出400us低电平之后输出100us高电平,也符合理论范围。占空比调制成功实现了呼吸灯效果。