【WB32库开发】第10章 TIM1高级定时器——PWM互补输出

在上一章的输出多路PWM的基础上,本章主要讲述如何配置WB32上的高级定时器TIM1完成PWM互补输出。

对PWM互补输出的概括放到10.3节中,请大家先跟随10.1节了解PWM互补输出如何配置,再结合10.2节实验现象对10.3节PWM互补输出概述进行参照,相信大家对PWM互补输出会有一个更清晰的认知。

本章节我们需要使用到固件库例程中TIM_ComplementarySignals工程,来讲解如何配置TIM1来完成PWM互补输出,需要注意PWM互补输出只能使用高级定时器来配置。

10.1 高级定时器PWM互补输出配置

本例程中我们使用到高级定时器TIM1,使用其中三个通道(TIM_CH1、TIM_CH2、TIM_CH3)和三个互补通道(TIM_CH1N、TIM_CH2N、TIM_CH3N),还有一个用来检测“刹车信号”的引脚(TIM1_BKIN)。
结合例程,根据WB32F103查表可知,使用到的引脚依次为PA8(TIM_CH1)、PA9(TIM_CH2)、PA10(TIM_CH3)、PB13(TIM_CH1N)、PB4(TIM_CH2N)、PB15(TIM_CH3N)和PA6(TIM1_BKIN)。

10.1.1开启对应端口和功能时钟

void RCC_Configuration(void)
{
  /* 使能TIM1 GPIOA GPIOB AFIO 时钟 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |
                         RCC_APB1Periph_TIM1 | 
                         RCC_APB1Periph_GPIOA | 
                         RCC_APB1Periph_GPIOB | 
                         RCC_APB1Periph_AFIO , 
                         ENABLE);
}

10.1.2初始化端口引脚

void GPIO_Configuration(void)
{
  /*GPIOA 初始化: TIM1_CH1, TIM1_CH2, TIM1_CH3 and TIM1_BKIN */
  GPIO_Init(GPIOA, GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10, GPIO_MODE_AF | GPIO_AF1);
  /*GPIOB 初始化: TIM1_CH1N, TIM1_CH2N, TIM1_CH3N*/
  GPIO_Init(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15, GPIO_MODE_AF | GPIO_AF1);
}

10.1.3定时器基本结构体配置

   /* 初始化定时器参数 */
  TIM_TimeBaseStructure.TIM_Prescaler = 0;                     //配置预分频器为0。             
  															   //驱动CNT计数器的时钟CK_CNT = CK_INT /(TIM_Prescaler+1)
  															   //例:本例程中 CK_CNT = 72M/(0+1) = 72M
  															   
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //配置定时器计数模式为向上计数
  
  TIM_TimeBaseStructure.TIM_Period = TimerPeriod;              //配置定时器周期为0xFFFF,即65535,可设置范围为0x00000~oxFFFFF。
                                                               //自动重装载寄存器(ARR)的值累计TIM_Period个频率后产生一个更新或中断。
                                                               
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;				   //配置时钟分频因子为0。
  
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;             //配置重复计数器为0

  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);              //初始化定时器基本结构体
  

注意:
1)此处例程中结构体成员TIM_Period的值被赋值为TimerPeriod。关于TimerPeriod的值,在使用uint16_t TimerPeriod = 0;将其初始化为0后,接着在主函数中通过TimerPeriod = 0xFFFF;将其赋值为0xFFFF。
2)关于输出的PWM周期与频率计算公式与方法请查看上章内容,本章节不再赘述。

10.1.4定时器输出比较结构体配置

  /* 配置Channel 1, 2 and 3 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                 //比较输出模式选择为PWM2 
           
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     //比较输出使能
  
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;   //比较互补输出使能
  
  TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;                    //脉冲宽度设置为Channel1Pulse。此处决定着PWM的占空比。
  
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;         //配置比较输出极性为高电平有效。(亦可设置为低电平有效,                 
                                                                    //使用示波器查看与配置为高电平输出有何不同)
  
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;       //配置比较互补输出极性为高电平有效。(亦可设置为低电平有效,                 
                                                                    //使用示波器查看与配置为高电平输出有何不同)
  
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;        //空闲状态下输出电平设置为高,即在空闲状态时,经过死区时间后
                                                                    //定时器通道输出高电平或低电平。
                                                                    
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;     //空闲状态下互补输出电平设置为低,即在空闲状态时,经过死区时
                                                                    //间后定时器互补通道输出高电平或低电平,设定值必须与 
                                                                    //TIM_OCIdleState相反。

  TIM_OC1Init(TIM1, &TIM_OCInitStructure);                          //TIM通道1输出比较结构体初始化

  TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;                    //脉冲宽度设置为Channel2Pulse。此处决定着PWM的占空比。
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);                          //TIM通道2输出比较结构体初始化

  TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;                    //脉冲宽度设置为Channel3Pulse。此处决定着PWM的占空比。
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);                          //TIM通道3输出比较结构体初始化

注意
1)在配置输出比较结构体成员TIM_OCMode时,可以注意到与上一章中的配置不同,本章选择配置为PWM2模式,两种模式用法相近,具体区别见下表:
【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第1张图片

2)在配置输出比较结构体成员TIM_Pulse时,将其配置为Channel1Pulse,这个变量具体的值可以通过代码Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);计算得来。
例:Channel1Pulse = 5*(65535-1)/10 = 32767 ,根据上一章的占空比计算可得TIM1通道1输出的PWM占空比为50%,另外,TIM1通道1输出的互补PWM的占空比亦是50%。
Channel2Pulse与Channel3Pulse的计算方法相同。

3)相较于上一章,本章完成PWM互补输出需要相关的结构体成员,配置方式在注释中。
需要注意结构体成员TIM_OCIdleState和TIM_OCNIdleState的配置,现在读不明白注释的请阅读完10.2节和10.3节后再思考。

10.1.4刹车和死区结构体配置

  /* 断路和死区结构体配置*/
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;              //使能运行模式下的关闭状态
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;              //使能空闲模式下的关闭状态
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;                   //配置锁定级别为1
  TIM_BDTRInitStructure.TIM_DeadTime = 11;                                 //定义死区持续时间为152ns。设置范围为 0x0 至 0xFF。
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;                      //使能断路输入功能。
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;        //配置断路输入通道 BRK 极性为高。
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;  //自动输出使能,可选使能或禁止

  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);                            //初始化断路和死区结构体

注意:
1)关于此结构体配置,主要了解如何配置死区时间即可,其他结构体成员配置主要为开启TIM输出的断路(“刹车”)功能。

2)死区时间配置可参考WB32中文参考手册TIM1高级控制定时器的刹车和死区寄存器(TIMx_BDTR)部分。
【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第2张图片
关于此部分配置我们会单出一篇文章进行详解。

10.1.4使能输出PWM配置

  TIM_Cmd(TIM1, ENABLE);                        //使能TIM1计数器。

  TIM_CtrlPWMOutputs(TIM1, ENABLE);            //主输出使能。

10.2 实验现象

本例仅观察TIM1通道1(TIM_CH1)与TIM1互补通道1(TIM_CH1N)的现象,其余两个通道请自行观察学习。

将示波器探头通道1接在PA8上,探头通道2接在PB13上,即可观察到如下波形:
【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第3张图片

大家可以观察到,PA8与PB13输出的波形是互补的,当PA8输出高电平时,PB13输出低电平,反之亦然。

但设置的死区时间在哪里?注意图片中用红框标注的地方,此时的200us代表示波器横坐标的1格的时间尺度。
我们在程序中设置的死区时间为153ns,所以在200us为时间单位的坐标中自然不能看清,接下来我们将时间尺度继续缩小:
【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第4张图片
【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第5张图片

可以看到,当示波器中1格的时间达到50.0ns时,即可在电平转换的边沿观察到死区时间,且PA8与PB13输出的PWM总是不同时为高电平。

另外,还有一项“断路(刹车)”功能,此时我们使用杜邦线将PA6与板载3.3V供电相连接,可以看到:

此时不再产生任何波形,就像对我们的WB32踩下“刹车”一样。

我们本节课的PWM互补输出配置讲解就到此为止,那么学会配置PWM互补输出到底是什么?用来干什么?请阅读10.3节。

注意:
1)当PA6断开与3.3V的连接后PWM会照常输出。

10.3PWM互补输出概述

简单的讲,互补的意思就是当PWM1是高电平时,PWM2是低电平,如果PWM1是低电平时PWM2是高电平,总之PWM1和PWM2不会同时变高或变低,总是不一样的。

需要知道,PWM互补输出多用在驱动器和逆变器等方面。

一般这样的PWM输出用于控制由两个MOS管组成的在电源和地之间的桥,由于两个同时接通的话会导致桥臂短路电源和地引起烧毁,所以采用互补的波形来避免同时导通的情况出现。

但是,由于两个MOS管的参数不一定完全相同,关断速度也不一定相同,可能出现第一个MOS管还差几us或几ms关闭但第二个MOS管已经打开,造成了两个MOS都短暂导通,进而烧毁驱动电路的现象。

因此,本章引入“死区时间”概念:即在PWM1变为低电平时,等待一段时间后,PWM2再从低电平变为高电平;或PWM2从高电平变为低电平时,等待一段时间后,PWM1从低电平变到高电平。这段等待的时间就是“死区时间”。

【WB32库开发】第10章 TIM1高级定时器——PWM互补输出_第6张图片

你可能感兴趣的:(技术教学,产品分享,学习心得,单片机,stm32,嵌入式硬件)