当前位置: 首页 > 工具软件 > Timer > 使用案例 >

GD32 定时器Timer0 PWM驱动无感无刷电机

潘灵均
2023-12-01

 特点1:Timer0输出6路PWM信号  三组CH0 CH1 CH2每组输出2路互补信号  

特点2: 加入死区设置(保证互补波形不会同时输出高电平)

特点3: 加入刹车保护:设置刹车保护脚BKIN-PB12 默认上拉,当被拉到GND后立即停止说要PWM输出,当释放BKIN脚后(高电平) PWM立刻重新输出PWM

步骤1:IO口配置

void gpio_config(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);

    /*Configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8);
    gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_9);
    gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_10);

    /*Configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);

    gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_13);
    gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_14);
    gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_15);
    
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_12);//设置刹车信号 默认上拉  如果出现低电平则刹车 停止PWM输出
    gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_12);
}

1 PB12 设置AF2模式,默认上拉

2 PA8 PA9 PA10 为上管的驱动,PB13 PB14 PB15 作为下管驱动   PA8-PB13互补,PA9-PB14互补,PA10-PB15互补

步骤2:定时器配置,只有高级定时器才有死区和刹车设置

void timer_config(void)
{

    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;
    timer_break_parameter_struct timer_Breakinitpara;
    rcu_periph_clock_enable(RCU_TIMER0);

    timer_deinit(TIMER0);

    /* TIMER0 configuration */
    timer_initpara.prescaler         = 0;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 9999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);

     /* CH1,CH2 and CH3 configuration in PWM mode 0 */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;//TIMER_OC_POLARITY_LOW TIMER_OC_POLARITY_HIGH
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;// TIMER_OCN_POLARITY_LOW TIMER_OCN_POLARITY_HIGH
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

    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,4999);
    timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);
    //timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);

    timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, 4999);
    timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);
    //timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);

    timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, 4999);
    timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0);
    //timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);

    
    
    timer_Breakinitpara.runoffstate=TIMER_ROS_STATE_ENABLE;
    timer_Breakinitpara.ideloffstate=TIMER_IOS_STATE_ENABLE;
    timer_Breakinitpara.deadtime=255;
    timer_Breakinitpara.breakpolarity=TIMER_BREAK_POLARITY_LOW;
    timer_Breakinitpara.outputautostate=TIMER_OUTAUTO_ENABLE;
    timer_Breakinitpara.protectmode=TIMER_CCHP_PROT_OFF;
    timer_Breakinitpara.breakstate=TIMER_BREAK_ENABLE;
    
    timer_break_config(TIMER0,&timer_Breakinitpara);
    
    timer_primary_output_config(TIMER0, ENABLE);
    /* auto-reload preload enable */
   // timer_auto_reload_shadow_enable(TIMER0);
    //timer_channel_control_shadow_config(TIMER0,ENABLE);
    timer_enable(TIMER0);
}

注意点1:

timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;为高占空比和函数timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0,4999);设定的值才能对应,否则相反

timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;

如果 一个LOW 一个HIGH则 两个波形变为一致不会互补。

注意点2:

timer_Breakinitpara.breakstate=TIMER_BREAK_ENABLE; 死区和刹车功能使能

注意点3:

timer_Breakinitpara.runoffstate=TIMER_ROS_STATE_ENABLE;使能可以使PWM被DISABLE后

timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE); IO口电瓶保持低电平,如果不开刹车功能或者runoffstate DISABLE 此时IO口电瓶处于悬浮状态。

注意点4:

timer_Breakinitpara.breakpolarity=TIMER_BREAK_POLARITY_LOW; LOW表示刹车信号为低电平时会触发刹车PWM停止输出。

注意点5:

timer_Breakinitpara.deadtime=255; 死区时间 范围0-255

步骤3:换向函数

void BLDC_Convet(uint8_t phase)
{                             
    switch(phase)   //
    {
        case 0x00: //AB ---- Q1 Q5  
        {
            /*  Channel1 configuration */
            
            timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);

            /*  Channel2 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);

            /*  Channel3 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0);
                
            timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);

        }
        break;
        case 0x01: //AB ---- Q1 Q5  
        {
            /*  Channel1 configuration */
            
            timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);

            /*  Channel2 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_HIGH);

            /*  Channel3 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_LOW);
                
            timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);
        }
        break;
        case 0x10://0x01: //AC ---- Q1 Q6 
        {
            /*  Channel1 configuration */
            
            timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);

            /*  Channel2 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_LOW);

            /*  Channel3 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_HIGH);
                
            timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);  
        }                
        break;
        case 0x02: //BC ---- Q2 Q6 
        {  

            /*  Channel2 configuration */
 timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);

            /*  Channel1 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_LOW);

            /*  Channel3 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_HIGH);
                
            timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);  
        }            
        break;
        case 0x03: //BA ---- Q2 Q4 
        { 
            /*  Channel2 configuration */
            
            timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);

            

            /*  Channel3 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_LOW);
            
            /*  Channel1 configuration */
            timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_HIGH);
                
            timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);  
        }
        break;
        case 0x04: //CA ---- Q3 Q4 
        {
        
        }
        break;                            
        case 0x05: //CB ---- Q3 Q5 
        {

        }                
        break;

        default:break;
    }  
}

注意点1:

case 1 只开了AB通道 即 CH0的上管PWM输出 CH1的下管输出高电平 其余4通道全为低电平

注意点2:

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);//CC1NE 此处关上管
            timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);  此处配置PWM0模式 没换一次相都必须要重新配置一次模式 

注意点3:

timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);//CC1E
            timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);//CC1NE
            timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_HIGH);

强行输出高电平 但CH1的上管通道被DISABLE  所以上管不影响还是低电平

注意点4:

timer_event_software_generate(TIMER0,TIMER_SWEVG_CMTG);通道重新配置后更新寄存器

 类似资料: