GD32或STM32PWM的中断:中央对齐模式

本文讲述了如何在PWM的中央对齐计数模式下配置中断,以便在计数器达到预设值时触发。涉及TIMER2初始化、中断处理和GPIO设置的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

有时候需要在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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值