如何精确控制PWM波的输出个数以及出现周期
看这篇博客之前,读者需要有PWM脉宽调制、定时器中断计时的基础。本人采用STM32RCT8开发板讲解,已经亲测,首先放上测试结果图。
要求是1s之内产生10个波,即PWM波的周期设置为100ms,然后间隔2s继续产生10个波,如此循环。总结起来就是产生1s的PWM波,间隔2s继续产生,循环下去。
基本的思路其实很简单,设置PWM的周期为t,需要产生的PWM波的个数是N,那么产生该数量PWM波的总时间T=N*t。因此需要用到两个定时器,一个定时器用于产生PWM波,另一个定时器用于计时。
本人采用通用定时器TIM3的通道CH4来产生PWM波,通用定时器TIM2来中断计时。两个定时器的初始化函数为(函数内容就不过多展示了,和正点原子例程的一样,但是建议先把两个定时器使能先关掉,在主程序中再打开;如果更换定时器的话稍微修改一下就可以了)
void TIM2_Int_Init(u16 arr,u16 psc);
void TIM3_PWM_Init(u16 arr,u16 psc);
主函数中的初始化是这样的
TIM3_PWM_Init(1000-1,7200-1); //周期设置为100ms
TIM2_Int_Init(1000-1,72-1); //周期设置为1ms,每隔1ms进入一次中断
本程序中最关键的地方是TIM2中断函数中的程序逻辑,下面我来展示我的中断函数程序逻辑:
u8 flag=0;
u16 count1=0,count2=0;
void TIM2_IRQHandler(void) //TIM3中断
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if(flag==0){//有波
count1++;
if(count1==1000){ //PWM输出1s时间到
TIM_Cmd(TIM3,DISABLE);//关闭PWM
count1=0;
flag=1;//PWM输出结束,转换为间隔状态
}
}
else if(flag==1){//没波
count2++;
if(count2==2000){ //间隔2s时间到
TIM_Cmd(TIM3,ENABLE);//打开PWM
flag=0;//间隔结束,转换为PWM输出状态
count2=0;
}
}
}
}
主程序内容如下:
int main(void)
{
delay_init();
TIM3_PWM_Init(1000-1,7200-1);
TIM2_Int_Init(1000-1,72-1);
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM2,ENABLE);
while(1);
}
count1:用来为产生PWM波的时间计时
count2:用来为间隔(不产生PWM)的时间计时
采用两个变量独立计时是为了使程序逻辑更清楚
flag:0代表正处于输出PWM状态,1代表正处于间隔状态
flag的作用:由于整个循环中有两个状态,一个是产生PWM波,一个不产生,所以每一次进入TIM2中断首先判断一下当前处于什么状态,然后进行相应处理。