基于STM32芯片三路互补PWM输出的设计实现

发布时间:2024-09-02  

硬件:Stm32f103c8t6最小系统。

开发平台:MDK-Arm。

目的:使用Stm32高级定时器TIM1。配置中心对齐模式输出三路互补PWM。

(1)Stm32的高级定时器:

Stm32f103c8t6有一个高级定时器TIM1。STM32的高级定时器比通用定时器增加了可编程死区互补输出,重复计数器,带刹车(短路)功能。这些功能为电机控制提供了便利。其中重复计数器下篇文章单独讲。

TIM1的IO分配:

1.jpg

(2)高级定时器框图分析:

图片

图1

图1高级定时器框图,可分为6部分,①时钟源选择,②控制器,③时基单元,④输入捕获,⑤输出比较,⑥刹车断路。

①时钟选择:

时钟源有:内部时钟(CK_INT),外部时钟模式1,外部时钟模式2,内部触发输入(ITRx)。具体可以看TIMx_SMCR寄存器SMS位和ECE位这里我们使用内部时钟64MHz(没使用外部晶振,系统时钟是64MHz)。

②控制器

控制器部分包含触发控制器,从模式控制器,编码器接口。触发控制器可以为片内外设提供触发信号。

③⑤时基单元和输出比较

时基单元的计数模式选中心对齐模式和比较输出的比较模式选PWM模式来讲解。

首先时钟源通过预分频寄存器PSC分频得到CK_CNT,得到计数器CNT计数频率,计数器开始从0向上计数,每计一次,和CCR比较一次,当CRR>CNT, 输出高电平,反之输出低电平,计数器CNT继续计数,当计数器等于ARR值时,计数器向下计数,当计数器CNT>CCR时,输出低电平,反之输出高电平。计数器周而复始向上向下计数并不断的和CRR值比较,参考图2。

图片

图2

实际此过程我们可以看成一个比较器,CRR作为参考电压,接到比较器同相输入端,CNT作为信号电压,接到比较器反相输入端,这样根据比较输出PWM。反之把CNT和CRR调换位置,会输出相反极性的PWM,参考图2.

计数器计数模式有:向上计数,向下计数,中心对齐计数。

比较输出比较模式:冻结,匹配时设置通道x为有效电平,匹配时设置通道x为无效电平,翻转,强制为无效电平,强制为有效电平,PWM1,PWM2。

死区发生器:

通过寄存器BDTR的位UTG[7:0]来配置死区时间,关于死区时间设置可以这篇文章:

⑥短路功能

断路功能用于电控的刹车功能,可以通过寄存器BDTR的BKE位使能断路功能,BKP位设置断路输入引脚的有效电平

④输入捕获

输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输 入信号的脉宽和测量 PWM 输入信号的频率和占空比这两种。

输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存 到捕获寄存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我 们需要做额外的处理。

(3)程序设计

程序使用ST官方固件库,编程步骤:

①GPIO初始化;

②时基结构体TIM_TimeBaseInitTypeDef 初始化;

③比较结构体 TIM_OCInitTypeDef 初始化;

④刹车和死区结构体 TIM_BDTRInitTypeDef 初始化。


程序分析:


①宏定义:


#define   RCC_TIMGPIO_CLK      RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB

#define   TIM_CHxGPIO_Pinx     GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11

#define   TIM_CHxGPIOx         GPIOA

#define   TIM_CHxNGPIO_Pinx    GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15

#define   TIM_CHxNGPIOx        GPIOB

#define   TIM_BKINGPIO_Pinx    GPIO_Pin_2

#define   TIM_BKINGPIOx        GPIOB

//TIM1 macro definition


/ PWM频率和死区时间计算 */


//电机控制载波频率一般配置在15-20KHz,频率配置低了电机噪声大,配置高了,对MOS


//管开关频率要求高,且开关损耗大,这里载波配置为20KHz。


//计数器频率计算CK_CNT = 64MHz/(PSC+1) = 64MHz/1=64MHz


//中心对齐PWM频率=CK_INT/2(ARR+1)=64M/2(1599+1)=20KHz。


//死区时间配置为2us


//64M/(CKD+1)/ UTG = 500KHz,换算成时间位2us


// TIMx_CR1寄存器CKD 位,TIMx_BDTR寄存器UTG位。


#define   TIMx                 TIM1

#define   RCC_TIM_CLK          RCC_APB2Periph_TIM1

#define   TIM_ARR              1599

#define   TIM_CK_PSC           0

#define   TIM_RCR              0

#define   TIM_CCRx             799

#define   PWM_DeadTime         128

②GPIO初始化:


static void GPIO_TIM_Config(void){

   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_TIMGPIO_CLK, ENABLE);

   //TIM1_PA8CH1 PA9CH2 PA10CH3 PA11CH4

   GPIO_InitStructure.GPIO_Pin =  TIM_CHxGPIO_Pinx;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOA, &GPIO_InitStructure);

   //PB13CH1N PB14CH2N PB15CH3N PB12BKIN      

   GPIO_InitStructure.GPIO_Pin =  TIM_CHxNGPIO_Pinx; 

   GPIO_Init(TIM_CHxNGPIOx, &GPIO_InitStructure);      

   //PB12BKIN

   GPIO_InitStructure.GPIO_Pin =  TIM_BKINGPIO_Pinx; 

   GPIO_Init(TIM_BKINGPIOx, &GPIO_InitStructure);          

   GPIO_ResetBits(TIM_BKINGPIOx,TIM_BKINGPIO_Pinx);//刹车

}

③定时器时基单元,输出比较,刹车死区初始化:


static void AdvanceTIM1_Config(void){

  //开启定时器时钟,即内部时钟CK_INT=64MHz

  RCC_APB2PeriphClockCmd(RCC_TIM_CLK,ENABLE);

/*--------------------时基结构体初始化-------------------------*/

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     

  TIM_TimeBaseStructure.TIM_Period = TIM_ARR;   //自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断      

  TIM_TimeBaseStructure.TIM_Prescaler = TIM_CK_PSC;   //驱动CNT计数器的时钟 = Fck_int/(psc+1)

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //时钟分频因子 ,配置死区时间时需要用到             

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; //中心对齐1             

  TIM_TimeBaseStructure.TIM_RepetitionCounter = TIM_RCR;  //重复计数器的值,没用到不用管      

  TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);  //初始化定时器

/*--------------------输出比较结构体初始化-------------------*/             

  TIM_OCInitTypeDef  TIM_OCInitStructure;     

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                //PWM1模式

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    //输出使能

  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;  //互补输出使能       

  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_OCNIdleState_Reset;   //互补输出通道空闲电平极性配置                  

  TIM_OCInitStructure.TIM_Pulse = TIM_CCRx;                        //设置占空比大小    

  TIM_OC1Init(TIMx, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);

  TIM_OC2Init(TIMx, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable); 

  TIM_OC3Init(TIMx, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);               

/*-------------------刹车和死区结构体初始化-------------------*/

  //有关刹车和死区结构体的成员具体可参考BDTR寄存器的描述

  TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;

  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;

  //输出比较信号死区时间配置,具体如何计算可参考 BDTR:UTG[7:0]的描述

  //这里配置的死区时间为2uS

  TIM_BDTRInitStructure.TIM_DeadTime = 128;

  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;

  //当BKIN引脚检测到高电平的时候,输出比较信号被禁止,就好像是刹车一样

  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;

  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

  TIM_BDTRConfig(TIMx, &TIM_BDTRInitStructure);

  TIM_Cmd(TIMx, ENABLE);      

  //主输出使能,当使用的是通用定时器时,这句不需要

  TIM_CtrlPWMOutputs(TIMx, ENABLE);                  

}


(4)程序烧录验证:图3是一对PWM互补输出波形。

图片

图3


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>