【摘要】 1、高级定时器带死区初始化流程 <1>定时器IO口配置。 <2>配置时基结构体:TIM_TimeBaseInitTypeDef <4>配置输出比较结构体:TIM_OCInitTypeDef <5>配置断路和死区结构体:TIM_BDTRInitTypeDef <6>启动定时器,输出使能。
2、高级定时器结构体
定时器基本初始化结构体 >> TIM_TimeBaseIn…
1、高级定时器带死区初始化流程
<1>定时器IO口配置。
<2>配置时基结构体:TIM_TimeBaseInitTypeDef
<4>配置输出比较结构体:TIM_OCInitTypeDef
<5>配置断路和死区结构体:TIM_BDTRInitTypeDef
<6>启动定时器,输出使能。
2、高级定时器结构体
- 定时器基本初始化结构体 >> TIM_TimeBaseInitTypeDef
typedef struct
{
uint16_t TIM_Prescaler; /*定时器预分频设置。 value:(0~0xFFFF)*/ uint16_t TIM_CounterMode;/*选择了计数器模式。Value:
#define TIM_CounterMode_Up ((uint16_t)0x0000) //TIM 向上计数模式
#define TIM_CounterMode_Down ((uint16_t)0x0010) //TIM 向下计数模式
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) //TIM 中央对齐模式 1 计数模式
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) //TIM 中央对齐模式 2 计数模式*/ uint16_t TIM_Period; /*设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。value:0x0000~0xFFFF*/ uint16_t TIM_ClockDivision; /*设置定时器时钟CK_INT频率与死区发生器以及数字滤波器采样时钟频率分频化。Value:
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)*/ uint8_t TIM_RepetitionCounter; /*是否使用重复定时器,当该值不为0的时候,计数器计数值达到周期数时,该值减1,计数器重新计数,当该值减到0的时候才会产生事件。*/
} TIM_TimeBaseInitTypeDef;
备注:
若是主频72MHz、TIM_Prescaler的值设置为(72-1),则定时器时钟频率=72MHz/72=1MHz。知道频率就可以算周期了,用1/1MHz
乘以TIM_Period的值就是定时的时间(周期),如果加入了重复定时器,那么还要乘以TIM_RepetitionCounter的值才是定时的时间(周期)。
- 定时器比较输出初始化结构体 >> TIM_OCInitTypeDef
typedef struct
{
uint16_t TIM_OCMode;/*比较输出模式选择,共8种。value:
#define TIM_OCMode_Timing ((uint16_t)0x0000) // TIM 输出比较时间模式
#define TIM_OCMode_Active ((uint16_t)0x0010) //TIM 输出比较主动模式
#define TIM_OCMode_Inactive ((uint16_t)0x0020) //TIM 输出比较非主动模式
#define TIM_OCMode_Toggle ((uint16_t)0x0030) //TIM 输出比较触发模式
#define TIM_OCMode_PWM1 ((uint16_t)0x0060) //TIM 脉冲宽度调制模式 1
#define TIM_OCMode_PWM2 ((uint16_t)0x0070) //TIM 脉冲宽度调制模式 2*/ uint16_t TIM_OutputState;/*比较输出使能,决定信号是否通过外部引脚输出。value:0(Disable)、1(Enable)。 */ uint16_t TIM_OutputNState; /*比较互补输出使能,决定互补信号是否通过外部引脚输出。value:0(Disable)、1(Enable)。*/ uint16_t TIM_Pulse; /*比较输出的脉冲宽度,设置占空比。Value:0x0000~0xFFFF*/ uint16_t TIM_OCPolarity; /*比较输出极性,决定定时器通道有效电平的极性。Value:
#define TIM_OCPolarity_High ((uint16_t)0x0000)
#define TIM_OCPolarity_Low ((uint16_t)0x0002)*/ uint16_t TIM_OCNPolarity; /*比较互补输出极性,可选高电平有效、低电平有效。Value:
#define TIM_OCNPolarity_High ((uint16_t)0x0000)
#define TIM_OCNPolarity_Low ((uint16_t)0x0008)*/ uint16_t TIM_OCIdleState; /*空闲状态时通道输出电平设置,可选高电平、低电平。Value:
#define TIM_OCNPolarity_High ((uint16_t)0x0000)
#define TIM_OCNPolarity_Low ((uint16_t)0x0008)*/ uint16_t TIM_OCNIdleState; /*空闲状态时互补通道输出电平设置,可选高电平、低电平,设定值必须跟TIM_OCIdleState相反。Value:
#define TIM_OCNIdleState_Set ((uint16_t)0x0200)
#define TIM_OCNIdleState_Reset ((uint16_t)0x0000)*/
} TIM_OCInitTypeDef;
备注:设置TIM_Pulse的值就可以改变输出波形的占空比了,如果不使用重复定时器,那么占空比=(TIM_Pulse+1)/(TIM_Period+1)x100%。
- 定时器输入捕获初始化结构体 >> TIM_ICInitTypeDef
typedef struct
{
uint16_t TIM_Channel; /*输入通道选择,共4个通道。Value:
#define TIM_Channel_1 ((uint16_t)0x0000) //使用 TIM 通道 1
#define TIM_Channel_2 ((uint16_t)0x0004) //使用 TIM 通道 2
#define TIM_Channel_3 ((uint16_t)0x0008) //使用 TIM 通道 3
#define TIM_Channel_4 ((uint16_t)0x000C) //使用 TIM 通道 4*/ uint16_t TIM_ICPolarity; /*输入捕获边沿触发选择,可选上升沿触发、下降沿触发。Value:
#define TIM_ICPolarity_Rising ((uint16_t)0x0000) //TIM 输入捕获上升沿
#define TIM_ICPolarity_Falling ((uint16_t)0x0002) //TIM 输入捕获下降沿*/ uint16_t TIM_ICSelection; /*输入通道选择,共3个通道。Value:
#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) //TIM 输入 2,3 或 4 选择对应地与 IC1 或 IC2 或IC3 或 IC4 相连 #define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) //TIM 输入 2,3 或 4 选择对应地与 IC2 或 IC1 或IC4 或 IC3 相连
#define TIM_ICSelection_TRC ((uint16_t)0x0003) //TIM 输入 2,3 或 4 选择与 TRC 相连*/ uint16_t TIM_ICPrescaler; /*输入捕获通道预分频,共(1、2、4、8)种。Value:
#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) //TIM 捕获在捕获输入上每探测到一个边沿执行一次
#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) // TIM 捕获每 2 个事件执行一次
#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) //TIM 捕获每 4 个事件执行一次
#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) //TIM 捕获每 8 个事件执行一次*/ uint16_t TIM_ICFilter; /*输入捕获滤波器设置,value:0x0~0x0F。一般不用,设置为0*/
} TIM_ICInitTypeDef;
备注:定时器捕获信号,可以测量输入信号的脉宽和测量PWM输入信号的频率和占空比;信号的来源可以来自其他的定时器或者外部引脚;滤波器的作用是排除高频的干扰,采样的频率必须大于等于两倍的输入信号。
- 断路和死区初始化结构体 >>TIM_BDTRInitTypeDef
typedef struct
{
uint16_t TIM_OSSRState;/*运行模式下关闭状态选择。Value:
#define TIM_OSSRState_Enable ((uint16_t)0x0800)
#define TIM_OSSRState_Disable ((uint16_t)0x0000)*/ uint16_t TIM_OSSIState;/*空闲模式下关闭状态选择。Value:
#define TIM_OSSIState_Enable ((uint16_t)0x0400)
#define TIM_OSSIState_Disable ((uint16_t)0x0000)*/ uint16_t TIM_LOCKLevel;/*锁定配置。Value:
#define TIM_LOCKLevel_OFF ((uint16_t)0x0000)
#define TIM_LOCKLevel_1 ((uint16_t)0x0100)
#define TIM_LOCKLevel_2 ((uint16_t)0x0200)
#define TIM_LOCKLevel_3 ((uint16_t)0x0300)*/ uint16_t TIM_DeadTime;/*死区时间。Vlaue:0x0~0xFF*/ uint16_t TIM_Break;/*短路输入使能控制。Value:
#define TIM_Break_Enable ((uint16_t)0x1000)
#define TIM_Break_Disable ((uint16_t)0x0000)*/ uint16_t TIM_BreakPolarity;/*断路输出极性。Value:
#define TIM_BreakPolarity_Low ((uint16_t)0x0000)
#define TIM_BreakPolarity_High ((uint16_t)0x2000)*/ uint16_t TIM_AutomaticOutput;/*自动输出使能。Value:
#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000)
#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000)*/
} TIM_BDTRInitTypeDef;
3、高级定时器带死区初始化例程
双通道互补PWM,带死区和刹车功能。
周期:100ms 占空比:通道一为25%,通道二为60%
死区持续时间:12.8ms
void GPIO_Configuration(void)
{ /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA| \ RCC_APB2Periph_GPIOC, ENABLE);//开启GPIOC的外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置引脚模式为通用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; GPIO_Init(GPIOB, &GPIO_InitStructure); //调用库函数,初始化GPIOC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStructure); //调用库函数,初始化GPIOC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_Init(GPIOB, &GPIO_InitStructure); //调用库函数,初始化GPIOC GPIO_SetBits(GPIOB,GPIO_Pin_12);
}
#define ADVANCE_TIM TIM1
void TIME_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //开启TIM1时钟
//时基结构体配置
TIM_TimeBaseStructure.TIM_Period = 1000-1; //从0开始计数 一个周期1000次
TIM_TimeBaseStructure.TIM_Prescaler =(7200-1); //计数器频率为10kHz 定时器时钟:72MHz/7200=10kHz 周期:(1/10kHz)*1000=100ms
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不需要分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方式 向上计数
TIM_TimeBaseStructure.TIM_RepetitionCounter=0; //重复计数器
TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure); //调用库函数,初始化TIM1
//输出比较结构体配置
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;
//初始化TIM1的通道一
TIM_OCInitStructure.TIM_Pulse = 250-1; //占空比=250/1000=25%
TIM_OC1Init(ADVANCE_TIM,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(ADVANCE_TIM,TIM_OCPreload_Enable);
//初始化TIM1通道二
TIM_OCInitStructure.TIM_Pulse = 600-1; //占空比=600/1000=60%
TIM_OC2Init(ADVANCE_TIM,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(ADVANCE_TIM,TIM_OCPreload_Enable);
//死区和短路结构体配置
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 0x80;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;//低电平有效,如果引脚检测到高电平则会停止PWM的输出,不会产生任何波形
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(ADVANCE_TIM,&TIM_BDTRInitStructure);
//使能定时器,计数器开始计数
TIM_Cmd(ADVANCE_TIM, ENABLE);
//主动输出使能
TIM_CtrlPWMOutputs(ADVANCE_TIM,ENABLE);
}
死区时间是根据与输出信号相连接的器件及其特性来调整的,为了避免OCx和OCxN同时改变时,造成外部器来不及反应所造成的短路问题。
一个高级定时器可以输出多路PWM,但是他们的周期是一样的,占空比可以不一样,在运行过程中每个通道的占空比是可以通过调用函数来改变。通用定时器跟高级定时器的区别是前者没有死区和断路功能,其他都是一样。
文章来源: blog.csdn.net,作者:云-生,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/yunshengbixiao/article/details/116379588