GD32与STM32 PWM中断:中央对齐模式
需求:
有时候需要在PWM的一个(每个)脉冲后做某些事情,就会要配置PWM中断。这里主要讲中央对齐计数模式的配置(可能也没理解对)。
关于PWM的理解:
常规的PWM(即边沿模式):配置好一个往复运行的时钟,例如从0到1000,按照升计数;设一个比较值如200;则计数值在0-200是一种电平,200到1000是另一种电平。
中央对齐PWM:计数从0到1000,再从1000到0,以此往复运行;假设一个比较值200,;当计数大于200是一种电平,小于200是另外一种电平;
现在想在到计数器的数值到达比较值的时候触发中断,即最后一种CAM=2b11;例如0-200,到200时刻触发中断,计数继续升,升到1000后,往下降,降到200,再次触发中断。
有2个地方需要注意:
1、设置TIMER_COUNTER_CENTER_BOTH 计数模式
为啥是BOTH,因为它才会把CAM配为11;
2、开启CH0中断
如下代码:可以在中断里面打断点,查看 中断触发的时候时钟计数值是多少。
uint16_t ledPWMduty = 200;
void initPWMGPIO(void)
{
/* TIMER2 configuration: generate PWM signals with different duty cycles:
TIMER2CLK = SystemCoreClock / 108 = 1MHz */
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
nvic_irq_enable(TIMER2_IRQn, 0, 2);
rcu_periph_clock_enable(RCU_AF);//复用时钟
rcu_periph_clock_enable(RCU_TIMER2);//定时器时钟
rcu_periph_clock_enable(PWMPortCLK);//引脚时钟
//gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);//PB4 默认是NJTRST 这样做 只是PB4解脱了 PA15 PB3又作为JTAG 在GPIO的初始化那里已经处理好了
gpio_pin_remap_config(GPIO_TIMER2_PARTIAL_REMAP,ENABLE);
/*Configure PB4(TIMER2_CH0) as alternate function*/
gpio_init(PWMPort, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWMCtlLight_PIN);
//------------------------------------------------------------------------
timer_deinit(TIMER2);
/* TIMER0 configuration */
timer_initpara.prescaler = 3600-1; // 108/3600 = 30 000
timer_initpara.alignedmode = TIMER_COUNTER_CENTER_BOTH;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 1000-1; //数100下 为一个周期 30 hZ
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2,&timer_initpara);
/* CH0 configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER2,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,ledPWMduty);//200
timer_channel_output_mode_config(TIMER2,TIMER_CH_0,TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(TIMER2,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
/* clear channel 0 interrupt bit */
timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0);
/* channel 0 interrupt enable */
timer_interrupt_enable(TIMER2,TIMER_INT_CH0);
timer_primary_output_config(TIMER2,ENABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER2);
timer_enable(TIMER2);
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,ledPWMduty);
}
void TIMER2_IRQHandler(void)
{
uint32_t cnt1;
if(SET == timer_interrupt_flag_get(TIMER2,TIMER_INT_CH0)){
/* clear channel 0 interrupt bit */
cnt1 = timer_counter_read(TIMER2);
timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0);
}
}
作者:外道幻想