在MCU驱动直流无刷电机BLDC六歩换相时,首先就要检测三个霍尔传感器的状态信息,然后根据三个霍尔传感器状态组成的时序码来驱动对于的6个桥臂的开关。
过程: 霍尔中断->读取IO->换相
在霍尔检测中断的方式中,有2种通用简单的方式,方式1:普通IO的输入中断 。方式2:定时器的输入捕获方式。
主要介绍的是定时器的输入捕获方式,使用的是GD32F303RC,这是一款M4内核性价比比较高的MCU。
这是GD32F303RC的定时器资源,可以看到,高级定时器和通用L0定时器都有4个输入捕获通道。
BLDC霍尔输入检测使用定时器输入捕获通道的方式也有两种简单的方式
方式1:使用定时器的通用的输入捕获通道
使用TIMER2的通道0,1,2为例
timer_parameter_struct timer_initpara;
timer_ic_parameter_struct timer_icinitpara;
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_TIMER2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ, GPIO_PIN_6 );
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_0 );
timer_deinit(TIMER2);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 60-1; //
timer_initpara.period = 0xffff-1;
timer_initpara.counterdirection=TIMER_COUNTER_UP;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2, &timer_initpara);
timer_channel_input_struct_para_init(&timer_icinitpara);
timer_icinitpara.icfilter = 0xf; // 输入滤波
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING; // 下降沿
timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; // 不分频,捕获每个触发边沿
timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; //
timer_input_capture_config(TIMER2, TIMER_CH_0, &timer_icinitpara);
timer_input_capture_config(TIMER2, TIMER_CH_1, &timer_icinitpara);
timer_input_capture_config(TIMER2, TIMER_CH_2, &timer_icinitpara);
timer_interrupt_enable(TIMER2,TIMER_INT_CH0|TIMER_INT_CH1|TIMER_INT_CH2); timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH0|TIMER_INT_FLAG_CH1|TIMER_INT_FLAG_CH2);
nvic_irq_enable(TIMER2_IRQn, 1, 1);
timer_enable(TIMER2);
然后在中断里检测
void TIMER2_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0) != RESET)
{
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH0);
printf("0\r\n");
}
if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH1) != RESET)
{
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH1);
printf("1\r\n");
}
if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH2) != RESET)
{
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH2);
printf("2\r\n");
}
}
方式2 使用定时器的异或模式,也就是霍尔传感器模式
在这个模式中,使用L0定时器+高级定时器的互补输出模式,就能驱动BLDC电机了,这里主要配置霍尔传感器的输入检测配置,就是使用定时器的异或门功能。
关于GD32F303RC关于异或门的介绍很少,可以参考STM32的
stm32关于异或门的信息比较多一点。
void bldc_motor_hall_init(void)
{
timer_parameter_struct timer_initpara;
timer_ic_parameter_struct timer_icinitpara;
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_TIMER2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ, GPIO_PIN_6 );
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_0 );
timer_deinit(TIMER2);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 60-1; //
timer_initpara.period = 0xffff-1;
timer_initpara.counterdirection=TIMER_COUNTER_UP;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2, &timer_initpara);
/* 配置霍尔传感器接口模式 */
timer_hall_mode_config(TIMER2, TIMER_HALLINTERFACE_ENABLE);
timer_input_trigger_source_select(TIMER2, TIMER_SMCFG_TRGSEL_CI0F_ED);
timer_slave_mode_select(TIMER2,TIMER_SLAVE_MODE_RESTART);//复位模式
timer_channel_input_struct_para_init(&timer_icinitpara);
timer_icinitpara.icfilter = 0xf; // 输入滤波
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING; // 上升沿
timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; // 不分频,捕获每个触发边沿
timer_icinitpara.icselection = TIMER_IC_SELECTION_ITS; // 模式TIMER_IC_SELECTION_DIRECTTI
timer_input_capture_config(TIMER2, TIMER_CH_0, &timer_icinitpara);
timer_interrupt_enable(TIMER2,TIMER_INT_TRG);
timer_interrupt_flag_clear(TIMER2,TIMER_INT_TRG); // 清除中断标志
timer_auto_reload_shadow_enable(TIMER2);//自动重载
nvic_irq_enable(TIMER2_IRQn, 1, 1);
timer_enable(TIMER2);
}
void TIMER2_IRQHandler(void)
{
if(timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_TRG) != RESET){
//获取三个传感器IO
//六歩换相
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_TRG); // 清除更新中断标志
}
}
这样就配置完成。
硬件上,霍尔传感器接口需要做上下拉,滤波,过压保护
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/fqm0_0/article/details/147780640
|
|