高级控制定时器(TIM1和TIM8):
组成:由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动;这个计数器可以向上计数、向下计数或者向上向下双向计数 。
用途:它们都能提供3通道的带死区的互补输出,对于用在多通道控制的PWM开关电源以及电机驱动方面都具有极大的便利。
包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。
高级控制定时器与通用定时器,区别多出了BRK、DTG两个结构,因而具有了死区时间的控制功能。
总结一下高级定时器溢出中断配置的步骤:
1,时钟使能,定时器1通道对应引脚的配置
2,配置预分频、自动重装值和重复计数值
3.定时器计数的模式
4.清除中断标志位(否则会先进一次中断)
5,使能TIM1中断,选择中断源
6,输出通道1,2,3的配置
a.选择PWM模式
b.TIM1输出使能
c.设定电平跳变值
d. 设定PWM信号的极性
e.使能TIM1 信号通道
7.死区时间的设置
8.设置中断优先级
9,使能TIM1比较寄存器CCRX重载,使能TIM1重载寄存器ARR ,使能TIM1计数器。
下面附上我用库函数写的TIM1溢出中断配置程序代码:
//定时器1中断优先级设置
static void TIME_NVIC_Configuration1(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM1_PWMConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//////////////////////////////////////////
//定时器1设置
//////////////////////////////////////////
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; //timer1 ch1 ch2 ch3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //timer1 ch1n ch2n ch3n
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
TIM_TimeBaseInitStructure.TIM_Period=900 - 1;//这里是设置周期,可以自己项目需求设置
TIM_TimeBaseInitStructure.TIM_Prescaler=2-1;//设置预分频值
TIM_TimeBaseInitStructure.TIM_ClockDivision=0;//设置时钟分割
TIM_TimeBaseInitStructure.TIM_CounterMode= TIM_CounterMode_CenterAligned1; //向上计数方式
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数设置为0
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清楚中断标志位
TIM_ITConfig(TIM1, TIM_IT_Update | TIM_IT_Trigger, ENABLE ); //中断触发源的选择及使能中断
//ch1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//pwm模式 1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出通道使能
TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse =100; //主要是用来调节输出脉冲的占空比,根据上面的周期计数是900 ,这里是100,可以知道占空比为1/9
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //极性的选择 高有效
TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); //比较寄存器(TIM1->CCR1)重装载值使能
//ch2
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse =200;//占空比2/9
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM1,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
//ch3
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse =300; //占空比3/9
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC3Init(TIM1,&TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);
//deadtime
TIM_BDTRInitStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;//主动输出使能
TIM_BDTRInitStructure.TIM_Break=TIM_Break_Disable;//禁止刹车输入
TIM_BDTRInitStructure.TIM_BreakPolarity=TIM_BreakPolarity_High;//刹车输入极性
TIM_BDTRInitStructure.TIM_DeadTime=28; //死区寄存器存放的数值为28
TIM_BDTRInitStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;//锁定关闭,寄存器无写保护
TIM_BDTRInitStructure.TIM_OSSIState=TIM_OSSIState_Disable;
TIM_BDTRInitStructure.TIM_OSSRState=TIM_OSSRState_Disable;
TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
TIM_ARRPreloadConfig(TIM1,ENABLE); //定时器1重装载使能
TIM_CtrlPWMOutputs(TIM1,ENABLE);//pwm输出使能
TIME_NVIC_Configuration1();//中断优先级函数
TIM_Cmd(TIM1,ENABLE); //定时器1使能
}
void TIM1_UP_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)//检测是否产生中断标志位
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清楚中断标志位
/*******************************/
//这里可以加入中断的内容
/*******************************/
}
}
这里提一下死区时间的计算:
上面程序的死区时间寄存器的数值为28,也就是符合0xx,因为内部时钟72Mhz,定时器1为内部时钟2分频即36Mhz(TDTS = 1/36MHZ),时钟死区时间=28/36Mhz=0.777us
高级定时器1与8配置是一样的,稍微改改把上述定时器1配置改为定时器8即可。由于篇幅的太长我就不写了。如果实在没写出来
可以找我要资料。上面实验是设置输出的为占空比固定的 PWM 波,若想利用定时器输出 SPWM 波,则可以在中断函数中采用
TIM_SetCompare() 查表修改比较寄存器中的值(即脉冲宽)来达到目的。