stm32高级定时器1&高级定时器8,3通道带死区互补输出配置

时间:2022-11-07 23:34:03

高级控制定时器(TIM1和TIM8):

组成:由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动;这个计数器可以向上计数、向下计数或者向上向下双向计数 。

用途:它们都能提供3通道的带死区的互补输出,对于用在多通道控制的PWM开关电源以及电机驱动方面都具有极大的便利。

包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。


stm32高级定时器1&高级定时器8,3通道带死区互补输出配置


stm32高级定时器1&高级定时器8,3通道带死区互补输出配置

高级控制定时器与通用定时器,区别多出了BRKDTG两个结构,因而具有了死区时间的控制功能。


总结一下高级定时器溢出中断配置的步骤:

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


stm32高级定时器1&高级定时器8,3通道带死区互补输出配置




stm32高级定时器1&高级定时器8,3通道带死区互补输出配置

软件仿真的结果:
stm32高级定时器1&高级定时器8,3通道带死区互补输出配置


stm32高级定时器1&高级定时器8,3通道带死区互补输出配置


高级定时器1与8配置是一样的,稍微改改把上述定时器1配置改为定时器8即可。由于篇幅的太长我就不写了。如果实在没写出来

可以找我要资料。上面实验是设置输出的为占空比固定的 PWM 波,若想利用定时器输出 SPWM 波,则可以在中断函数中采用
TIM_SetCompare() 查表修改比较寄存器中的值(即脉冲宽)来达到目的。