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

【经验分享】STM32F103单片机输出相位可调PWM波

[复制链接]
STMCU小助手 发布时间:2022-3-22 13:00
    STM32定时器功能如下

52$J_79[6$$(RR7JO[WOOTL.png

通常使用的是PWM模式,可以通过PWM功能可以生成频率和占空比可调的方波信号,有时候需要生成初始相位可调的方波,PWM功能就就不能满足要求了。可以通过输出比较模式来实现。

HN%AV0YN~2M)LNJIE)%O_(Q.png

输出比较模式是将计数器CNT的值和捕获比较寄存器CCR的对比,当CNT值等于CCR的值时,翻转输出电平。

J](5%US0ANS_5{9_O%Y@X8V.png

通过捕获比较寄存器CCMR模式设置位的描述可以看出,输出比较模式只有当 CCR = CNT时,输出电平才会翻转。而PWM模式下 CNT < CCR 时输出一个电平,CNT > CCR时输出相反的电平。

通过一个示意图来看看PWM输出模式

G%`VCHPTCNWR3V83]P}Q$]1.png

上图中是PWM输出的示意图,可以看出CNT的值从变化范围是 0---ARR,之间,CNT的值在CCR值左边时输出一个电平,CNT值在CCR右边时,输出相反电平。这样改变CCR值就可以改变输出PWM的占空比。

下面在看看输出比较模式

)TC`0`W7EKLQ]07WTXJN9EM.png

输出比较模式下不关心CNT比 CCR值大还是小,只关心CNT和CCR值什么时候相等,两个值相等时,就翻转输出电平。在PWM模式下,CNT值从0增加到ARR一个周期内输出电平有两次变化,而在输出比较模式下时CNT值从0增加到ARR一个周期内输出电平只有一次变化。所以输出比较模式下,定时器输出方波的频率为PWM模式下定时器输出方波频率的一半。

下面就看看代码如何实现

  1. // arr 自动装载值  psc 分频系数
  2. void TIM3_CMP_Init( u16 arr, u16 psc )
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStructure;
  5.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  6.     TIM_OCInitTypeDef TIM_OCInitStructure;

  7.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );        //使能定时器3时钟  36M
  8.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE );        //使能GPIOC时钟

  9.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  10.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  11.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  13.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  14.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  15.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  17.     //初始化TIM3
  18.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  19.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  20.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  21.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  22.     TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStructure );

  23.     //初始化TIM3 比较 模式  输出比较翻转触发模式(当计数值与比较/捕获寄存器值相同时,翻转输出引脚的电平)   
  24.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  25.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  26.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  27.     TIM_OC1Init( TIM3, &TIM_OCInitStructure );
  28.     TIM_OC2Init( TIM3, &TIM_OCInitStructure );
  29.     TIM_OC3Init( TIM3, &TIM_OCInitStructure );
  30.     TIM_OC4Init( TIM3, &TIM_OCInitStructure );

  31.     TIM_OC1PreloadConfig( TIM3, TIM_OCPreload_Enable );
  32.     TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Enable );
  33.     TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Enable );
  34.     TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Enable );

  35.     //使能TIM3
  36.     TIM_Cmd( TIM3, ENABLE );
  37. }
复制代码


这里用的是定时器3,定时器3的4个通道全部设置为输出比较模式。

定时器初始化代码,输出比较模式设置方法和PWM模式设置方法只有模式设置这一行代码不同。

  1. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
复制代码

将输出模式由TIM_OCMode_PWM1 改为  TIM_OCMode_Toggle 就可以了。

下面看主函数代码

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "pwm.h"
  6. // LED0  PA8  LED1 PD2
  7. int main( void )
  8. {
  9.     u16 led_pwm_val = 0;
  10.     u8 dir = 1;
  11.     delay_init();       //延时函数初始化
  12.     NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 );
  13.     LED_Init();

  14.     LED0 = 1;
  15.     LED1 = 1;
  16.     delay_ms( 500 );
  17.     LED0 = 0;
  18.     LED1 = 0;
  19.     //比较输出模式下:  ARR 决定输出频率  CCRx 决定每个通道的初始相位
  20.     //PWM模式:                   ARR 决定输出频率  CCRx 决定输出 的高电平时长

  21.     //比较翻转模式,一个周期只翻转一次,所以频率为 1/2
  22.     TIM3_CMP_Init( 1000 - 1, 36 - 1 );                        //1K
  23.     TIM_SetCompare1( TIM3, 0 );
  24.     TIM_SetCompare2( TIM3, 200 );
  25.     TIM_SetCompare3( TIM3, 400 );
  26.     TIM_SetCompare4( TIM3, 600 );
  27.     while( 1 )
  28.     {
  29.         delay_ms( 200 );
  30.         LED0 = !LED0;
  31.     }
  32. }
复制代码

        定时器3时钟为72MHz,36分频后为2MHz,自动装载值为1000-1,输出频率为 2M / 1000 = 2KHz。输出比较模式的频率要在减一半,所以输出方波信号频率为 2K / 2 = 1KHz.

        下来分别设置4个通道输出的初始相位,通道1相位设置为0,通道2延迟1/5周期,通道3延迟2/5周期,通道4延迟3/5周期。

~1[C$UHUQX2O7{UTXTO`L.png

4个通道的输出频率都是1KHz,周期为1000us。

1O%K1PF0]E5FV1ZXHI8)0I7.png

通过输出波形可以看出来,起始相位依次滞后,通道1为0起点的话,通道2滞后100us,通道3滞后200us,通道4滞后300us。

上面计算的通道2滞后1/5周期,周期为1000us,1/5周期应该为200us,实际测出来为100us,说明相位计算的理论值也要减半。

这样利用定时器输出比较模式,通过设置改变定时器CCR寄存器的值,就可以控制输出方波的起始相位了。


收藏 评论0 发布时间:2022-3-22 13:00

举报

0个回答

所属标签

相似分享

官网相关资源

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