STM32的TIM1之PWM互补输出_死区时间和刹车配置

STM32的TIM1之PWM互补输出_死区时间和刹车配置

1、定时器1的PWM输出通道

STM32高级定时器TIM1在用作PWM互补输出时,共有4个输出通道,其中有3个是互补输出通道,如下:

通道1:TIM1_CH1对应PA8引脚,TIM1_CH1N对应PB13引脚;

通道2:TIM1_CH2对应PA9引脚,TIM1_CH2N对应PB14引脚;

通道3:TIM1_CH3对应PA10引脚,TIM1_CH3N对应PB15引脚;

通道4:TIM1_CH4对应PA11引脚;

STM32高级定时器TIM1的PWM刹车引脚TIM1_BKIN对应PB12引脚;

2、PWM互补输出的意义

在使用互补输出时,通常需要考虑死区时间,防止互补引脚控制的功率管同时而导通引起烧坏。见下图:

如果死区Deadtime>0,则在TIM1_CH1和TIM1_CH1N输出波形中插入“死区时间”,可防止TIM1_CH1和TIM1_CH1N控制的功率管同时导通。

3、互补输出

如果死区Deadtime=0,则TIM1_CH1N的输出波形是TIM1_CH1的反相;当死区时间为0,且没有收到刹车信号时,如果TIM1_CH1输出高电平,则TIM1_CH1N一定会输出低电平,我们称之为互补输出。

4、PWM刹车

PWM刹车,就是停止PWM输出波形。

5、PWM的“有效电平”和“无效电平”定义:

在PWM模式1中

1)、在向上计数时,一旦TIMx_CNT<TIMx_CCR1时,通道1引脚输出“有效电平”,否则输出“无效电平”;

2)、在向下计数时,一旦TIMx_CNT>TIMx_CCR1时,通道1引脚输出“无效电平”(OC1REF=0),否则输出“有效电平”(OC1REF=1)。

在PWM模式2中

1)、在向上计数时,一旦TIMx_CNT<TIMx_CCR1时,通道1引脚输出“无效电平”,否则输出“有效电平”;

2)、在向下计数时,一旦TIMx_CNT>TIMx_CCR1时,通道1引脚输出“有效电平”,否则输出“无效电平”。

6、PWM在死区期间输出的电平

1)、若配置了死区时间,则在死区期间,通道1引脚输出的电平和其“无效电平”保持一致。

2)、将“死区期间和无效电平期间”的TIM1_CH1和TIM1_CH1N配置输出为低电平:

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

//TIM1_CH1引脚输出有效电平为高电平,则在死区期间和无效电平期间均为低电平

TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

// TIM1_CH1N引脚输出有效电平为高电平,则在死区期间和无效电平期间均为低电平

3)、死区时间

  TIM_BDTRInitStructure.TIM_DeadTime = 11;

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

  //DTG[7:5]=0xx => DT=DTG[7:0]*tdtg,这里的tdtg=tDTS.

  //DTG[7:5]=10x => DT=(64+DTG[5:0])*tdtg,这里的Tdtg=2*tDTS.

  //DTG[7:5]=110 => DT=(32+DTG[4:0])*tdtg,这里的Tdtg=8*tDTS.

  //DTG[7:5]=111 => DT=(32+DTG[4:0])*tdtg,这里的Tdtg=16*tDTS.

  //tDTS=tCKINT=1/72000000=13.8ns,11*13.8=152.7ns

  //这里配置的死区时间为152ns

7、PWM空闲电平极性配置和PWM刹车的关系

TIM1_CH1和TIM1_CH1N引脚的“空闲电平极性”指的是在“刹车”时TIM1_CH1和TIM1_CH1N引脚输出的极性。

刹车输出配置:

1)、TIM1_CH1和TIM1_CH1N输出配置为互异电平,可能会导致无法刹车;

TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

2)、TIM1_CH1和TIM1_CH1N输出同时配置为低电平,当刹车信号到来时,会执行有效刹车;

TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

3)、TIM1_CH1和TIM1_CH1N输出同时配置为高电平,当刹车信号到来时,会执行有效刹车;

TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

8、TIM1之PWM程序举例:

void TIM1_GPIO_Config(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

/// TIM1_CH1引脚初始化///

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    //使能PA口时钟

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;

  //PA8为TIM1_CH1通道,TIM1输出比较通道

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  //设置引脚为复用推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  //设置引脚的最高输出速率为50MHz

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 /// TIM1_CH1N引脚初始化///

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13;

  //PB13为TIM1_CH1N通道,TIM1输出比较通道的互补通道

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  //设置引脚为复用推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  //设置引脚的最高输出速率为50MHz

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  //TIM1_BKIN刹车引脚初始化/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12;

   //PB12对应TIM1_BKIN,为PWM刹车引脚

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

   //设置引脚为浮空输入 

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  //设置引脚的最高输出速率为50MHz

  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void TIM1_Mode_Config(void)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; //时基结构体

    TIM_OCInitTypeDef  TIM_OCInitStructure;         //输出比较结构体

    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;      //刹车结构体

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);

    //使能TIM1时钟,即内部时钟CK_INT=72M

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

    TIM_TimeBaseStructure.TIM_Period=(8-1);//周期ARR

//自动重装载寄存器的值,累计(TIM_Period+1)个"分频时钟"后产生一个更新或者中断

    TIM_TimeBaseStructure.TIM_Prescaler= (9-1);

    //TIM1时钟分频因子PSC

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

    //时钟分频因子 = 1,tDTS=tCKINT

    //PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}

    //72000000/(8*9)=1000000Hz=1MHz

    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

    //计数器计数模式,设置为向上计数

    TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

    //重复计数器的值,没用到不用管

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

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

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    //配置为PWM模式1

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    //PWM输出使能

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

    //互补输出使能

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  //TIM1_CH1引脚输出有效电平为高电平,则在死区期间和无效期间均为低电平

  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

  //TIM1_CH1N引脚输出有效电平为高电平,则在死区期间和无效空闲期间均为低电平

//TIM1_CH1和TIM1_CH1N输出配置为互异电平,导致会无法刹车,死区期间的输出电平这个设置无关/

//  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

//刹车时,TIM1_CH1引脚为高电平

//  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

//刹车时,互补输出TIM1_CH1N引脚为低电平

//TIM1_CH1和TIM1_CH1N输出同时配置为低电平,当刹车信号到来时,会执行有效刹车/

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

    //刹车时,TIM1_CH1引脚为低电平

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

    //刹车时,互补输出TIM1_CH1N引脚为低电平

//TIM1_CH1和TIM1_CH1N输出同时配置为高电平,当刹车信号到来时,会执行有效刹车/

//  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

//刹车时,TIM1_CH1引脚为高电平

//  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

//刹车时,TIM1_CH1N引脚为高电平

    TIM_OCInitStructure.TIM_Pulse = (5-1); //占空比 = 4 / 8 = 50%

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);//初始化PWM输出通道1

    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

    //开启通道1预装载,在更新时间后才会重新装载数值

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

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

  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;

  //运行模式下“关闭模式”选择 = 1

  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

  //空闲模式下“关闭模式”选择 = 1

  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;

  //锁定级别1,见参考手册

  TIM_BDTRInitStructure.TIM_DeadTime = 11;

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

  //DTG[7:5]=0xx => DT=DTG[7:0]*tdtg,这里的tdtg=tDTS.

  //DTG[7:5]=10x => DT=(64+DTG[5:0])*tdtg,这里的Tdtg=2*tDTS.

  //DTG[7:5]=110 => DT=(32+DTG[4:0])*tdtg,这里的Tdtg=8*tDTS.

  //DTG[7:5]=111 => DT=(32+DTG[4:0])*tdtg,这里的Tdtg=16*tDTS.

    //tDTS=tCKINT=1/72000000=13.8ns,11*13.8=152.7ns

    //这里配置的死区时间为152ns

  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;//开启刹车功能

  TIM_BDTRInitStructure.TIM_BreakPolarity =TIM_BreakPolarity_Low;

  //PWM刹车时,输入低电平有效,则不会产生任何PWM输出波形

  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

  //开启自动输出

  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

    TIM_Cmd(TIM1, ENABLE);//使能定时器,计数器开始计数  

    TIM_CtrlPWMOutputs(TIM1, ENABLE);

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

}

void TIM1_PWM_Init(void)

{

    TIM1_GPIO_Config();

    TIM1_Mode_Config();

}

9、测试结果

PWM刹车实验

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32的高级定时器中,可以通过配置定时器的输出比较模式来实现PWM输出。而互补输出则是指使用两个定时器通道来实现互补输出,其中一个通道输出PWM波的高电平部分,另一个通道输出PWM波的低电平部分,从而实现互补输出的效果。同时,为了避免MOS管同时导通,可以设置死区时间来控制两个通道的输出时间间隔。 以下是一个简单的代码示例,实现了使用TIM1作为高级定时器,PA8和PA9作为互补输出通道,同时设置了死区时间为100个时钟周期: ```c #include "stm32f4xx.h" void TIM1_PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 8399; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 4199; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 4199; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 100; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_Cmd(TIM1, ENABLE); } ``` 在该代码中,首先开启了TIM1和GPIOA的时钟,然后配置了PA8和PA9为复用输出模式,并将它们的复用引脚分别与TIM1的通道1和通道2相连。接着,配置TIM1的计数器周期为8399,即定时器频率为84MHz/8400=10kHz。通道1和通道2都选择了PWM模式1,输出极性为高电平,占空比均为50%。最后,通过TIM_BDTRInitStructure结构体设置了死区时间为100个时钟周期,并启用了自动输出功能。 需要注意的是,该例程中使用的是STM32F407VG开发板,所以使用的是TIM1定时器。如果使用其他型号的开发板,需要根据具体情况修改代码中使用的定时器和GPIO引脚。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值