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

【经验分享】STM32F103输出互补PWM波

[复制链接]
STMCU小助手 发布时间:2022-3-22 13:00
STM32F103单片机定时器自带互补PWM波形输出功能,利用定时器输出比较模式,不仅可以输出互补的 PWM波,还可以设置输出方波的起始相位和死区时间。

       下面就总结一下如何实现PWM互补输出。


  1. void TIM1_PWM_DeadtimeInit( u16 arr, u16 psc, u16 ccr1, u16 ccr2, u16 deadtime )
  2. {
  3.     GPIO_InitTypeDef GPIO_InitSturcture;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitStructure;
  6.     TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

  7.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE );
  8.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );

  9.     //TIM1 互补PWM CH1->PA8  CH2->PA9  CH1N->PB13  CH2N->PB14
  10.     GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  11.     GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
  12.     GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
  13.     GPIO_Init( GPIOA, &GPIO_InitSturcture );

  14.     GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
  15.     GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
  16.     GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
  17.     GPIO_Init( GPIOB, &GPIO_InitSturcture );
  18.     //定时器设置
  19.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  20.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  21.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  22.     TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x00;
  23.     TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
  24.     TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure );
  25.     //通道1 捕获比较模式设置
  26.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;                                 //翻转,当 TIMx_CCR1=TIMx_CNT时,翻转OC1REF的电平
  27.     TIM_OCInitStructure.TIM_Pulse = ccr1;                                                        //100
  28.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                //CCER的CC1P,输入/捕获输出极性
  29.     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
  30.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //CER的CC1N,输入/捕获输出使能
  31.     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  32.     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;        //OIS1位
  33.     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;  //CR2的OIS1N位,当MOE位0时,输出空闲状态位OIS1N.
  34.     TIM_OC1Init( TIM1, &TIM_OCInitStructure );
  35.     //通道2 设置
  36.     TIM_OCInitStructure.TIM_Pulse = ccr2;                                                        //316
  37.     TIM_OC2Init( TIM1, &TIM_OCInitStructure );
  38.     //刹车和死区设置
  39.     TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;         //OSSR:运行模式下“关闭状态”选择
  40.     TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;         //OSSI:空闲模式下“关闭状态”选择
  41.     TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;                         //锁定设 置,级别为1
  42.     TIM_BDTRInitStructure.TIM_DeadTime = deadtime;                                        //死区延时时间
  43.     TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;                        //禁止刹车输 入
  44.     TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;                 //刹车输入极性
  45.     TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能
  46.     TIM_BDTRConfig( TIM1, &TIM_BDTRInitStructure );

  47.     TIM_CtrlPWMOutputs( TIM1, ENABLE );
  48.     TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Enable );
  49.     TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Enable );
  50.     TIM_ARRPreloadConfig( TIM1, ENABLE );
  51.     TIM_Cmd( TIM1, ENABLE );
  52. }
复制代码


首先初始化IO口,这里使用的是定时器1的通道1和通道2。

FDVE[VTF`WT2(]]2O~QY8YT.png

PA8为定时器1通道1输出口,PB13为定时器1通道1互补输出口。

PA9为定时器1通道2输出口, PB14为定时器1通道2互补输出口。

下来初始化定时器,参数arr设置输出PWM波频率,psc设置定时器时钟分频系数。定时器初始化之后,设置定时器工作模式为输出比较模式,其中参数 ccr1 设置通道1的输出方波起始相位,参数cc2设置通道2输出方波起始相位。参数 deadtime 设置互补PWM波形的死区时间。初始化结束后启动定时器。

关于输出比较模式的详细说明参考STM32输出比较模式和PWM模式 比较这篇文章。

下面看主函数设置

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "pwm_ch_chn.h"
  6. // LED0  PA8  LED1 PD2
  7. int main(void)
  8. {
  9.     delay_init();       //延时函数初始化
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  11.     LED_Init();
  12.     LED0 = 1;
  13.     LED1 = 1;
  14.     delay_ms(500);
  15.     LED0 = 0;
  16.     LED1 = 0;
  17.     // Tout=(719+1)*(0+1)/72M=10us   72M/720=0.1M=100K        
  18.     TIM1_PWM_DeadtimeInit(719,0,0,0,72);//50KHz
  19.     while(1)
  20.     {
  21.                
  22.     }
  23. }
复制代码


主函数中设置自动装载值为 720,分频系数为0,那么输出方波频率为 72MHz / 720 = 0.1MHz,也就是输出波形频率为100K,由于此处用的是定时器的输出比较模式,所以输出频率为计算值的一半,所以实际输出方波频率为50KHz。ccr1值设置为0,也就是定时器1通道1的输出波形起始相位为0,ccr2的值为0,所以起始相位也为0。死区时间设置为72,为周期数的1/10,也就是2us。

下面看一下输出波形

FKKWZY1O@QDH7@)UJKK6I3C.png

黄色为 TIM1_CH1波形,绿色为TIM1_CH1N波形,这两个波形是通道1互补波形。

蓝色为 TIM1_CH2波形,粉色为TIM1_CH2N波形,这两个波形是通道2互补波形。

黄色和蓝色波形起始相位相同。

Y0)Z[WR$NZ0J7QK[B@4FC6P.png

原波形和互补波形死区时间为1us,刚才计算的死区时间是2us,这里为什么是1us?因为死区时间是上升沿时间差+下降沿时间差,是两个对称的区间。这里只测了一个区间,所以为总时间的一半。

下来同时改变ccr1和ccr2的初始值,看看输出波形相位有没有发生变化。
  1.         TIM1_PWM_DeadtimeInit(719,0,72,144,72);//50KHz
复制代码

输出波形为

OYC(ZM1SZKGD(1J`9XI0NGU.png

蓝色波形下降沿比黄色波形下降沿滞后了一点,说明起始相位已经发生了改变。

W10PLLMS`L}JDW0ZOO5[FLU.png

放大波形后可以看到,下降沿滞后的时间为1us,和死区时间相同。


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

举报

0个回答

所属标签

相似分享

官网相关资源

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