打印

GD32F450高级定时器六步换相测试

[复制链接]
2050|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zeshoufx|  楼主 | 2022-11-11 22:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
GD32F450的高级定时器很适合用来驱动电机,比如直流无刷和永磁同步。六步换相在直流无刷驱动里运用广泛。

定时器设置函数:
#include "six_step.h"

vu32 step = 1;

void six_step_init(void)
{
        timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;
    timer_break_parameter_struct timer_breakpara;
         
        rcu_periph_clock_enable(RCU_GPIOE);
        rcu_periph_clock_enable(RCU_TIMER0);
        rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_8);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_8);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_9);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_9);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_9);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_10);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_10);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_10);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_11);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_11);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_11);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_12);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_12);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_12);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_13);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_13);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_13);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_14);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_14);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_14);
       
        gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_15);
        gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_15);
        gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_15);
       
        timer_initpara.alignedmode=TIMER_COUNTER_EDGE;
        timer_initpara.clockdivision=TIMER_CKDIV_DIV1;
        timer_initpara.counterdirection=TIMER_COUNTER_UP;
        timer_initpara.period=599;
        timer_initpara.prescaler=199;
        timer_initpara.repetitioncounter=0;
        timer_init(TIMER0,&timer_initpara);
       
        timer_ocintpara.ocidlestate=TIMER_OC_IDLE_STATE_HIGH;
        timer_ocintpara.ocnidlestate=TIMER_OCN_IDLE_STATE_HIGH;
        timer_ocintpara.ocpolarity=TIMER_OC_POLARITY_HIGH;
        timer_ocintpara.ocnpolarity=TIMER_OCN_POLARITY_HIGH;
        timer_ocintpara.outputstate=TIMER_CCX_ENABLE;
        timer_ocintpara.outputnstate=TIMER_CCXN_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_2,&timer_ocintpara);
       
        timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,299);
    timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_TIMING);
    timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);

    timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,299);
    timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_TIMING);
    timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);

    timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,299);
    timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_TIMING);
    timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
       
        timer_breakpara.runoffstate= TIMER_ROS_STATE_ENABLE;
    timer_breakpara.ideloffstate= TIMER_IOS_STATE_ENABLE ;
    timer_breakpara.deadtime= 164;
    timer_breakpara.breakpolarity= TIMER_BREAK_POLARITY_LOW;
    timer_breakpara.outputautostate= TIMER_OUTAUTO_ENABLE;
    timer_breakpara.protectmode= TIMER_CCHP_PROT_OFF;
    timer_breakpara.breakstate= TIMER_BREAK_ENABLE;
    timer_break_config(TIMER0,&timer_breakpara);
       
        timer_primary_output_config(TIMER0,ENABLE);
       
        timer_interrupt_enable(TIMER0,TIMER_INT_CMT);
        timer_interrupt_disable(TIMER0,TIMER_INT_BRK);
        nvic_irq_enable(TIMER0_TRG_CMT_TIMER10_IRQn,1,1);
       
        timer_enable(TIMER0);
}


void TIMER0_TRG_CMT_TIMER10_IRQHandler(void)
{
    /* clear TIMER interrupt flag */
    timer_interrupt_flag_clear(TIMER0,TIMER_INT_CMT);

    switch(step){
    /* next step: step 2 configuration .A-C` breakover---------------------------- */
    case 1:
        /*  channel0 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);

        /*  channel1 configuration */
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);

        /*  channel2 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);

        step++;
        break;

    /* next step: step 3 configuration .B-C` breakover---------------------------- */
    case 2:
        /*  channel0 configuration */
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);

        /*  channel1 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);

        /*  channel2 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);

        step++;
        break;

    /* next step: step 4 configuration .B-A` breakover---------------------------- */
    case 3:
        /*  channel0 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);

        /*  channel1 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);

        /*  channel2 configuration */
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);

        step++;
        break;

    /* next step: step 5 configuration .C-A` breakover---------------------------- */
    case 4:
        /*  channel0 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);

        /*  channel1 configuration */      
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);

        /*  channel2 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);

        step++;
        break;

    /* next step: step 6 configuration .C-B` breakover---------------------------- */
    case 5:
        /*  channel0 configuration */
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);

        /*  channel1 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);

        /*  channel2 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);

        step++;
        break;
  
    /* next step: step 1 configuration .A-B` breakover---------------------------- */        
    case 6:
        /*  channel0 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);

        /*  channel1 configuration */
        timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
        timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);

        /*  channel2 configuration */
        timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
        timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);

        step = 1;
        break;
    }
}

static u32 delay;

void systick_config(void)
{
    /* setup systick timer for 1000Hz interrupts */
    if (SysTick_Config(SystemCoreClock / 100U)){
        /* capture error */
        while (1){
        }
    }
    /* configure the systick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0x00U);
}

/*!
    \brief      delay a time in milliseconds
    \param[in]  count: count in milliseconds
    \param[out] none
    \retval     none
*/
void delay_1ms(uint32_t count)
{
    delay = count;

    while(0U != delay){
    }
}

/*!
    \brief      delay decrement
    \param[in]  none
    \param[out] none
    \retval     none
*/
void delay_decrement(void)
{
    if (0U != delay){
        delay--;
    }
}

void SysTick_Handler(void)
{
    timer_event_software_generate(TIMER0,TIMER_EVENT_SRC_CMTG);
}
主函数:

#include "bitband.h"
#include "usart.h"
#include "systick.h"
#include "led.h"
#include "six_step.h"

/*!
    \brief    main function
    \param[in]  none
    \param[out] none
    \retval     none
*/




int main(void)
{
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
//        systick_set(200);
//        usart_init(9600);
//        led_init();
//        printf("hello c language...\r\n");
        systick_config();
        six_step_init();
    while(1)
        {
//                printf("hello gd32...\r\n");
//                led_toggle();
//                delay_ms(750);
    }
}


结果:




DSView-3.png (86.41 KB )

1

1

DSView-2.png (92.72 KB )

2

2

DSView-1.png (95.55 KB )

3

3

使用特权

评论回复
沙发
豌豆爹| | 2022-11-15 13:31 | 只看该作者
这个高级定时器挺厉害的

使用特权

评论回复
板凳
zeshoufx|  楼主 | 2022-11-16 09:04 | 只看该作者
豌豆爹 发表于 2022-11-15 13:31
这个高级定时器挺厉害的

可以的

使用特权

评论回复
地板
chenqianqian| | 2022-11-19 11:18 | 只看该作者
这个效果看起来不错啊

使用特权

评论回复
5
daichaodai| | 2022-11-19 17:37 | 只看该作者
实际测试效果如何,稳不稳?

使用特权

评论回复
6
zeshoufx|  楼主 | 2022-11-20 13:55 | 只看该作者
chenqianqian 发表于 2022-11-19 11:18
这个效果看起来不错啊

是的

使用特权

评论回复
7
zeshoufx|  楼主 | 2022-11-20 13:56 | 只看该作者
daichaodai 发表于 2022-11-19 17:37
实际测试效果如何,稳不稳?

还没正式测试,,

使用特权

评论回复
8
OKAKAKO| | 2022-11-24 21:35 | 只看该作者
这个高级定时器效果非常好,各个波形也稳定

使用特权

评论回复
9
zeshoufx|  楼主 | 2022-11-25 16:57 | 只看该作者
OKAKAKO 发表于 2022-11-24 21:35
这个高级定时器效果非常好,各个波形也稳定

你们也在测试吗

使用特权

评论回复
10
OKAKAKO| | 2022-11-25 21:19 | 只看该作者

看你的波形输出确实挺稳定,以前做过类似的

使用特权

评论回复
11
zeshoufx|  楼主 | 2022-11-26 19:58 | 只看该作者
OKAKAKO 发表于 2022-11-25 21:19
看你的波形输出确实挺稳定,以前做过类似的

哦哦,,你们主要是做电机控制这块吗

使用特权

评论回复
12
OKAKAKO| | 2022-11-27 10:47 | 只看该作者
zeshoufx 发表于 2022-11-26 19:58
哦哦,,你们主要是做电机控制这块吗

我不是这个方向的,参与过类似的项目而已

使用特权

评论回复
13
tpgf| | 2022-12-5 09:56 | 只看该作者
请问六步换相是一种什么方式呢 适用于什么种类的电机呢

使用特权

评论回复
14
qcliu| | 2022-12-5 11:06 | 只看该作者
tpgf 发表于 2022-12-5 09:56
请问六步换相是一种什么方式呢 适用于什么种类的电机呢

电子换相无刷电机要对转子永磁体位置进行精确检测,并用电子开关切换不同绕组通电以获得持续向前的动力,在目前的绝大多数电动车三相无刷电机中均使用三个开关式的霍尔传感器检测永磁体相对于定子线圈的位置,控制器跟据三个霍尔传感器输出的六种不同信号输出相应的控制信号驱动电子开关向马达供电。这就是所谓六步换相法

使用特权

评论回复
15
drer| | 2022-12-5 12:03 | 只看该作者
从电机原理可以看出,换相必须及时,否则会导致电机失步,从而使电机噪音增大,效率降低

使用特权

评论回复
16
coshi| | 2022-12-5 13:05 | 只看该作者
为什么只有高级定时器适合呢   需要特殊的控制吗

使用特权

评论回复
17
kxsi| | 2022-12-5 14:12 | 只看该作者
coshi 发表于 2022-12-5 13:05
为什么只有高级定时器适合呢   需要特殊的控制吗

普通的定时器应该不能输出pwm波

使用特权

评论回复
18
wiba| | 2022-12-5 14:25 | 只看该作者
OKAKAKO 发表于 2022-11-24 21:35
这个高级定时器效果非常好,各个波形也稳定

有没有测试过抗干扰能力呢  另外和频率挂钩吗

使用特权

评论回复
19
zeshoufx|  楼主 | 2022-12-5 14:43 | 只看该作者
coshi 发表于 2022-12-5 13:05
为什么只有高级定时器适合呢   需要特殊的控制吗

高级定时器可以输出互补的PWM,方便设置死区,刹车

使用特权

评论回复
20
zeshoufx|  楼主 | 2022-12-5 14:43 | 只看该作者
drer 发表于 2022-12-5 12:03
从电机原理可以看出,换相必须及时,否则会导致电机失步,从而使电机噪音增大,效率降低 ...

是的,,,

使用特权

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

本版积分规则

67

主题

1962

帖子

14

粉丝