你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 PWM输出

[复制链接]
STMCU 发布时间:2020-9-10 10:18
01 PWM介绍
PWM定义:脉冲宽度调制(PulseWidthModulation,PWM)简称脉宽调制。通俗讲,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。

电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。

占空比定义:占空比就是高电平所占整个周期的时间,如下图所示:

1.png

第一个PWM波,周期为10ms,高电平的时间为4ms,所以占空比为40%,同理第二个PWM波为60%,第三个为80%。

PWM的频率: PWM的频率的整个周期的倒数,所以说上图PWM的周期为1/0.01,也就是100HZ。改变PWM的频率是通过改变整个的周期实现的。所以通过改变高低电平总共的时间、改变高电平占总周期的比例就可以实现任意频率、任意占空比的PWM波。

PWM的用途和优点:电机调速、功率调制、PID调节、通信等等,配置简单、抗干扰能力强,从处理器到被控系统信号都是数字形式的,无需进行数模转换。并且让信号保持为数字形式可将噪声影响降到最小,噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响,这是PWM用于通信的主要原因。

02 STM32的管脚复用
STM32没有专门的PWM引脚,所以使用IO口的复用模式。首先确认PWM功能的输出管脚,使用定时器9。从下面的框图中得知,timer9只有两个输出通道,所以timer9只能输出两路PWM。

2.png

在STM32F207数据手册中的Alternatefunction mapping图片中,timer9的两个通道分别可以复用为PA2,PA3,PE5和PE6。

3.png
03 STM32输出PWM原理
下图中的①部分,在《[color=var(--weui-LINK)]STM32基础定时器详解》讲解过了,关于影子寄存器,也在《[color=var(--weui-LINK)]STM32影子寄存器》中讲述,下文不再赘述了。本文将重点在②部分,捕获/对比通道讲解,其中STM32的PWM就是利用对比通道实现的。

4.png

Pulse Width Modulation mode allows you to generate a signal with afrequency determined by the value of the TIMx_ARR register and a dutycycle determined by the value of the TIMx_CCRx register。
节选自STM32F207 Reference manual手册


脉冲宽度调制模式可以生成一个信号,该信号频率由TIMx_ARR 寄存器值决定,其占空比则由TIMx_CCRx 寄存器值决定。

从下图可以看出,当CCR寄存器和CNT计数器数值一样时,会产生动作(改变通道对应的GPIO电平)。由于CNT溢出时,重载值由TIMx_ARR寄存器值决定的。所以说TIMx_ARR寄存器值决定周期,而TIMx_CCRx寄存器值决定CNT溢出时,经过多久会产生动作(改变通道对应的GPIO电平),也就是决定了占空比。

5.png

以向上计数为例,重载值为ARR,比较值为CRRx


6.png

上图可以看出:

  • 0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平。
  • t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平。


当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程至此一个PWM周期完成。

上图更加形象的说明了
  • 信号频率由 TIMx_ARR 寄存器值决定。
  • 占空比则由 TIMx_CCRx 寄存器值决定。



STM32输出PWM的过程:
1、首先配置GPIO,配置定时器,具体参考一下代码。定时器配置参考《STM32基础定时器详解》。
2、捕获/比较通道使能比较通道。

7.png

上图看到,①寄存器名字为:Capture/Compare1register。可以选择从②处输入捕获,也可以选择从从③中输出,也就是我们需要的PWM输出功能。选择捕获通道,还是选择比较通道,在框图中没有找到具体的说明,但在TIMx_CCMR1寄存器CC1S[1:0]控制位使能。

8.png

3、使能完输出,就要配置PWM输出了

9.png

①TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器

110:PWM模式1,111:PWM模式2。


②计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平。


OC1REF=0 无效电平,OC1REF=1无效电平。

③通过输出模式控制器产生的信号。TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性。

0:高电平有效,1:低电平有效。

④TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚。

0:关闭,1:打开。

首先对PWM模式1和PWM模式2进行介绍:
01 模式1
在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向上计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
02 模式2
在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

PWM输出高低电平由TIMx_CCMR1:OC1M位和TIMx_CCER:CC1P位共同决定。

总结下来:

模式1:

    CNT<CCR为有效电平//(OC1REF =1)
    CNT>CCR为无效电平//(OC1REF =0)

模式2:

    CNT<CCR为无效电平//(OC1REF =0)
    CNT>CCR为有效电平//(OC1REF =1)

CC1P:
    0:高电平有效
    1:低电平有效

04 STM32输出PWM配置

分析了原理,那么下面就分析STM32生成PWM的过程。

1、首先要将GPIO设置为复用输出


  1. /* GPIOE clock enable */
  2. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);

  3. /* GPIOE Configuration: TIM9 CH2(PE6)*/
  4. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_6;
  5. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;
  6. GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz;
  7. GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
  8. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  9. GPIO_Init(GPIOE, &GPIO_InitStructure);

  10. /*Connect TIM9 pins to AF3 */  
  11. GPIO_PinAFConfig(GPIOE,GPIO_PinSource5, GPIO_AF_TIM9);
  12. GPIO_PinAFConfig(GPIOE,GPIO_PinSource6, GPIO_AF_TIM9);
复制代码

2、配置定时器向上计数,配置定时器频率



  1. /* TIM9 clock enable */
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE);

  3. /* Compute the prescaler value */
  4. PrescalerValue= (uint16_t) ((SystemCoreClock) / 2000000) - 1;

  5. /* Timebase configuration */
  6. TIM_TimeBaseStructure.TIM_Period =1000-1;
  7. TIM_TimeBaseStructure.TIM_Prescaler =PrescalerValue;
  8. TIM_TimeBaseStructure.TIM_ClockDivision =0;
  9. TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;

  10. TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);
复制代码





3、配置PWM输出上面分析过程较为麻烦,ST提供了标准外设库,我们只需要配置TIM_OCInitTypeDef结构体即可。

  1. TIM_OCInitTypeDef  TIM_OCInitStructure;

  2. /* PWM Modeconfiguration: Channel1 */
  3. TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM1;
  4. TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;
  5. TIM_OCInitStructure.TIM_Pulse =100-1;
  6. TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;

  7. TIM_OC1Init(TIM9,&TIM_OCInitStructure);
  8. TIM_OC1PreloadConfig(TIM9,TIM_OCPreload_Enable);
复制代码



TIM_OCInitTypeDef结构体解析


  1. typedef struct
  2. {
  3.   uint16_t TIM_OCMode;      //PWM模式1或者模式2
  4. uint16_t TIM_OutputState; // 输出使能OR失能
  5. uint16_t TIM_OutputNState;  // PWM输出不需要
  6. uint32_t TIM_Pulse; // 比较值
  7. uint16_t TIM_OCPolarity;// 比较输出极性
  8.   uint16_t TIM_OCNPolarity;   // PWM输出不需要
  9.   uint16_t TIM_OCIdleState;// PWM输出不需要
  10. uint16_t TIM_OCNIdleState; // PWM输出不需要
  11. }TIM_OCInitTypeDef;
复制代码

其中TIM_Pulse可以在初始化时设置,设置完毕后,也可以通过以下接口再次更新。


  1. void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1)
复制代码


4、使能定时器


  1. TIM_ARRPreloadConfig(TIM9, ENABLE);

  2. /* TIM9 enable counter*/
  3. TIM_Cmd(TIM9, ENABLE);
复制代码

使用timer9输出PWM的波形。
10.png



1 收藏 2 评论0 发布时间:2020-9-10 10:18

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版