打印
[研电赛技术支持]

GD32F303RC关于三相霍尔传感器的HALL的使用方式

[复制链接]
163|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

108

帖子

0

粉丝