全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 处理器/DSP >

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

时间:2023-07-21 16:26

人气:

作者:admin

标签: 三路  STM32  互补  基于  芯片 

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

硬件: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

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信