**最近项目上有捕获脉冲宽度的需求,需要使用到定时器的脉宽捕获功能,根据以往学习单片机的时候首先想到的
肯定是定时器的捕获功能,所有学习资料例程中讲解的都是先设置定时器通道为上升沿捕获,然后记录定时器时间,
再设置定时器通道为下降沿捕获,用当前定时器事件减去上升沿产生时间计算出脉冲宽度。这种方式也没有问题,
但是定时器还有一个PWM捕获的功能可以更高效的实现脉冲捕获功能。**
还是直接上代码:
/* timer1 gpio init */
void timer1_ic0_gpio_config()
{
rcu_periph_clock_enable(RCU_GPIOA);
/* configure TIMER1 CH0 as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_15);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_15);
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_15);
}
/**
\brief configure the TIMER peripheral
\param[in] none
\param[out] none
\retval none
*/
void timer1_config(void)
{
/* TIMER1 configuration: generate PWM signals with different duty cycles:
TIMER1CLK = SystemCoreClock / 64 = 1MHz */
timer_ic_parameter_struct timer_icintpara;
timer_parameter_struct timer_initpara;
timer1_ic0_gpio_config();
rcu_periph_clock_enable(RCU_TIMER1);
timer_deinit(TIMER1);
/* TIMER1 configuration */
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 63;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xffff;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER1, &timer_initpara);
/* initialize the channel input parameter struct member with the default value */
timer_channel_input_struct_para_init(&timer_icintpara);
timer_icintpara.icpolarity = TIMER_IC_POLARITY_RISING;
timer_icintpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_icintpara.icprescaler = TIMER_IC_PSC_DIV1;
timer_icintpara.icfilter = 0U;
// timer_input_capture_config(TIMER1, TIMER_CH_0, &timer_icintpara);
timer_input_pwm_capture_config(TIMER1, TIMER_CH_0, &timer_icintpara);
/* TIMER master and slave mode */
/* select TIMER input trigger source */
timer_input_trigger_source_select(TIMER1, TIMER_SMCFG_TRGSEL_CI0FE0);
/* select TIMER slave mode */
timer_slave_mode_select(TIMER1, TIMER_SLAVE_MODE_RESTART);
/* configure TIMER master slave mode */
timer_master_slave_mode_config(TIMER1, TIMER_MASTER_SLAVE_MODE_ENABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER1);
nvic_irq_enable(TIMER1_IRQn, 1);
timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH0);
timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1);
// timer_interrupt_enable(TIMER1, TIMER_INT_CH0);
timer_interrupt_enable(TIMER1, TIMER_INT_CH1);
/* TIMER enable */
timer_enable(TIMER1);
}
void TIMER1_IRQHandler(void)
{
uint16_t TimeCnt;
if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH1))
{
/* clear channel 0 interrupt bit */
timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1);
TimeCnt = TIMER_CH1CV(TIMER1) + 1;
if(CntProcess != 0)
CntProcess(TimeCnt);
}
}
中断服务函数中读取通道1的值即为脉冲宽度!
希望对大家有所帮助,少走弯路!保住头发!