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);
    }
}

作者:外道幻想

物联沃分享整理
物联沃-IOTWORD物联网 » GD32与STM32 PWM中断:中央对齐模式

发表回复