gd32定时器使用总结
本次项目中较多模块使用了定时器,对定时器的不同使用方法进行总结补充。
模块一: 回充红外 通过定时器的计数器模块记录红外发射出来的脉冲宽度
void ir_timer_init(uint16_t prescaler, uint16_t period)
{
timer_parameter_struct TIMER_PARAMETER_STRUCTURE;
rcu_periph_clock_enable(IR_TIMER_CLK);
timer_deinit(IR_TIMER);
TIMER_PARAMETER_STRUCTURE.prescaler = prescaler - 1;
TIMER_PARAMETER_STRUCTURE.clockdivision = TIMER_CKDIV_DIV1;
TIMER_PARAMETER_STRUCTURE.alignedmode = TIMER_COUNTER_EDGE;
TIMER_PARAMETER_STRUCTURE.counterdirection = TIMER_COUNTER_UP;
TIMER_PARAMETER_STRUCTURE.period = period - 1;
TIMER_PARAMETER_STRUCTURE.repetitioncounter = 0;
timer_init(IR_TIMER, &TIMER_PARAMETER_STRUCTURE);
timer_enable(IR_TIMER);
}
使用总结:只用到了定时器的计数模块,计数模式为向上计数,通过计数器计算两个上升沿之间的时间来进行数据解析
模块二:两路边刷及一个滚刷、 使用了一个高级定时器的三个通道,通过设置定时器为输出pwm模式
来实现对电机的调速
void ezbsp_Timer0_Init(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER0);
rcu_periph_clock_enable(RCU_GPIOE);
gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_9); // PE9 CH0 SIDE_BRUSH_CTL
gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_11); // PE11 CH1 SIDE_BRUSH_PWM_B
gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_14); // PE14 CH3 MOTOR_RO_CTL
timer_deinit(TIMER0);
timer_initpara.prescaler = TIM0_PRESCALER - 1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = TIM0_PERIOD - 1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0, &timer_initpara);
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_primary_output_config(TIMER0, ENABLE);
timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);
timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocintpara);
timer_channel_output_config(TIMER0, TIMER_CH_3, &timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 0);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, 0);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_3, 0);//设置占空比值
timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER0, TIMER_CH_3, TIMER_OC_MODE_PWM0);//输出模式设置为pwm0模式
timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_config(TIMER0, TIMER_CH_2, &timer_ocintpara);
timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM1);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, TIM0_PERIOD / 4);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);
/*auto-reload preload enable*/
timer_auto_reload_shadow_enable(TIMER0);
timer_disable(TIMER0);
}
模块三:滚轮 使用了一个定时器的四个通道
/**
* @name: ezbsp_Timer3_Init
* @msg: tim3初始化 4路PWM
* CH0 MOTOR_L_PWM
* CH1 MOTOR_L_CTL
* CH2 MOTOR_R_PWM
* CH3 MOTOR_R_CTL
* @param {*}
* @return {*}
*/
void ezbsp_Timer3_Init(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_TIMER3);
rcu_periph_clock_enable(RCU_GPIOD);
gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_12); //PD12 CH0 MOTOR_L_PWM
gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_13); //PD13 CH1 MOTOR_L_CTL
gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_14); //PD14 CH2 MOTOR_R_PWM
gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_15); //PD15 CH3 MOTOR_R_CTL
gpio_pin_remap_config(GPIO_TIMER3_REMAP, ENABLE);
timer_initpara.prescaler = TIM3_PRESCALER - 1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = TIM3_PERIOD - 1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER3, &timer_initpara);
/*configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW;
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(TIMER3, TIMER_CH_0, &timer_ocintpara);
timer_channel_output_config(TIMER3, TIMER_CH_1, &timer_ocintpara);
timer_channel_output_config(TIMER3, TIMER_CH_2, &timer_ocintpara);
timer_channel_output_config(TIMER3, TIMER_CH_3, &timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, 0);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_1, 0);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, 0);
timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_3, 0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_2, TIMER_OC_MODE_PWM0);
timer_channel_output_mode_config(TIMER3, TIMER_CH_3, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);
timer_channel_output_shadow_config(TIMER3, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
/*auto-reload preload enable*/
timer_auto_reload_shadow_enable(TIMER3);
timer_disable(TIMER3);
}
控制滚轮方向
/**
* @name:
* @msg:
* @param {ENUM_MOTOR_TYPE} motor
* @param {u8} duty
* @return {*}
*/
void ezbsp_Set_Motor_Forward(ENUM_MOTOR_TYPE motor, u16 duty)
{
switch (motor)
{
case MOTOR_RIGHT:
/*encode timer count by rising*/
TIMER_CHCTL2(MOTOR_RIGHT_ENCODE) &= 0xFFF0;
/*pwm output timer set PWM mode*/
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_RIGHT_PWM_CHANNEL, 0);
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_RIGHT_CTL_CHANNEL, duty);
break;
case MOTOR_LEFT:
/*encode timer count by rising*/
TIMER_CHCTL2(MOTOR_LEFT_ENCODE) &= 0xFFF0;
/*pwm output timer set PWM mode*/
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_LEFT_PWM_CHANNEL, 0);
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_LEFT_CTL_CHANNEL, duty);
break;
default:
break;
}
}
/**
* @name:
* @msg:
* @param {ENUM_MOTOR_TYPE} motor
* @param {u8} duty
* @return {*}
*/
void ezbsp_Set_Motor_Back(ENUM_MOTOR_TYPE motor, u16 duty)
{
switch (motor)
{
case MOTOR_RIGHT:
// /*encode timer count by faling*/
TIMER_CHCTL2(MOTOR_RIGHT_ENCODE) |= TIMER_CHCTL2_CH0P;
// /*pwm output timer set PWM mode*/
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_RIGHT_CTL_CHANNEL, 0);
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_RIGHT_PWM_CHANNEL, duty);
break;
case MOTOR_LEFT:
// /*encode timer count by faling*/
TIMER_CHCTL2(MOTOR_LEFT_ENCODE) |= TIMER_CHCTL2_CH0P;
// /*pwm output timer set PWM mode*/
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_LEFT_CTL_CHANNEL, 0);
ezbsp_Timer_PWM_Change_Duty(MOTOR_PWM_TIMER, MOTOR_LEFT_PWM_CHANNEL, duty);
break;
default:
break;
}
}
控制速度则是通过改变占空比来设置