GD32F303RCT6PWM及SPWM配置

文章目录


前言

最近在使用GD32F303的芯片替换STM32F303,自己也在网上查阅了资料但关于具体实现的描述还是较少,希望下面的东西可以帮到大家。

一、原理介绍

在这里不做具体的介绍SPWM实现原理,网上资料很多,简单描述一下控制实现。

硬件:两个高频管,两个工频管。
软件:两个互补定时器通道控制PWM的周期和高频管、工频管的关断方式实现SPWM(正弦波)。

二、代码

1.GD32F303RCT6的PWM配置

代码如下:

void TIM3_Int_Init(u16 arr,u16 psc)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER3);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);
    
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

    timer_deinit(TIMER3);

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

    /* CH1 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

    timer_channel_output_config(TIMER3,TIMER_CH_1,&timer_ocintpara);
 
    /* CH1 configuration in PWM mode1,duty cycle 25% */
    timer_channel_output_pulse_value_config(TIMER3,TIMER_CH_1,2500);
    timer_channel_output_mode_config(TIMER3,TIMER_CH_1,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER3,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);

    timer_primary_output_config(TIMER3,ENABLE);
    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER3);
    /* auto-reload preload enable */
    timer_enable(TIMER3);

  
}

2.GD32F303RCT6的SPWM配置

代码如下:

const unsigned int spwm[200]={
0,117,235,353,470,588,705,823,939,1056,1173,1289,1405,1520,1636,1750,
1865,1979,2092,2205,2317,2429,2540,2651,2760,2870,2978,3086,3193,3299,3404,3509,
3613,3715,3817,3918,4018,4117,4215,4312,4408,4503,4596,4689,4780,4870,4959,5047,
5134,5219,5303,5385,5467,5547,5625,5703,5778,5853,5926,5997,6067,6136,6203,6268,
6332,6394,6455,6514,6572,6628,6682,6735,6786,6835,6883,6929,6973,7015,7056,7095,
7132,7168,7202,7234,7264,7292,7319,7344,7367,7388,7407,7425,7440,7454,7466,7476,
7485,7491,7496,7499,7500,7499,7496,7491,7485,7476,7466,7454,7440,7425,7407,7388,
7367,7344,7319,7292,7264,7234,7202,7168,7132,7095,7056,7015,6973,6929,6883,6835,
6786,6735,6682,6628,6572,6514,6455,6394,6332,6268,6203,6136,6067,5997,5926,5853,
5778,5703,5625,5547,5467,5385,5303,5219,5134,5047,4959,4870,4780,4689,4596,4503,
4408,4312,4215,4117,4018,3918,3817,3715,3613,3509,3404,3299,3193,3086,2978,2870,
2760,2651,2540,2429,2317,2205,2092,1979,1865,1750,1636,1520,1405,1289,1173,1056,
939,823,705,588,470,353,235,117
}; 
/*------------------------------------------------------------------------------
函数名:TIM0_PWM_Init(u16 arr,u16 psc)
描  述:上管Q1,Q2驱动,下管Q3,Q4驱动互补PWM输出 pb12杀车功能
-----------------------------------------------------------------------------*/

void TIM0_PWM_Init(void)
{        
    timer_oc_parameter_struct timer_ocintpara;      //定时器比较输出初始化结构体
    timer_parameter_struct timer_initpara;         // 定时器捕获输入初始化结构体
    timer_break_parameter_struct timer_breakpara;

    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);

    //Configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);                //TIM0CH1高频
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);               //TIM0CH2工频

    //Configure  PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);            
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);                    
    
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_12);//刹车

    rcu_periph_clock_enable(RCU_TIMER0);
    
     timer_deinit(TIMER0);
    
     // TIMER0 configuration 
     timer_initpara.prescaler                  = 0;                                                      //时钟预分频器
     timer_initpara.alignedmode           = TIMER_COUNTER_EDGE;//TIMER_COUNTER_CENTER_UP;                //计数器触发方式
     timer_initpara.counterdirection  = TIMER_COUNTER_UP;                                                //计数器模式选择向上计数
     timer_initpara.period                      = 7500;      //16KHz                                            //定时器周期个数 自动重载值
     timer_initpara.clockdivision          = TIMER_CKDIV_DIV1;                                           //时钟分频因子
     timer_initpara.repetitioncounter = 0;                                                               //重复计数值
     timer_init(TIMER0,&timer_initpara); 
    
      // CH1 and CH2 configuration in PWM mode 
     timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;                                                   //配置比较输出模式状态(使能或禁止输出)
     timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;                                                  //互补比较输出状态
     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_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_1,0);                     //配置定时器通道输出脉冲值
    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,0);
    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_breakpara.runoffstate      = TIMER_ROS_STATE_DISABLE;                     //运行模式下输出--禁止
    timer_breakpara.ideloffstate     = TIMER_IOS_STATE_DISABLE ;                    //空闲模式下输出选择--禁止
    timer_breakpara.deadtime         = 0x8C;                                        //死区时间1.2us
    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_DISABLE;                         //刹车功能禁止-暂时
    timer_break_config(TIMER0,&timer_breakpara);

    // TIMER0 primary output function enable 
    timer_primary_output_config(TIMER0,ENABLE);

    // auto-reload preload enable 
    timer_auto_reload_shadow_enable(TIMER0);
        
    // TIMER0 counter enable 
    timer_enable(TIMER0);

}


/*------------------------------------------------------------------------------
函数名:TIM2_Int_Init
描  述: 
-----------------------------------------------------------------------------*/

void TIM2_Int_Init(void)                        //ifreq为不分频时的更新中断频率,psc为预分频值
{
    timer_parameter_struct  TIM_TimeBaseStructure;
    rcu_periph_clock_enable(RCU_TIMER2);
    //定时器TIM2初始化

    TIM_TimeBaseStructure.period = 4999;                //60Hz
    TIM_TimeBaseStructure.prescaler = 0;                                                  //设置用来作为TIMx时钟频率除数的预分频值
    TIM_TimeBaseStructure.clockdivision = TIMER_CKDIV_DIV1;                               //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.counterdirection = TIMER_COUNTER_UP;                            //TIM向上计数模式
    
    timer_init(TIMER2, &TIM_TimeBaseStructure);                                           //根据指定的参数初始化TIMx的时间基数单位
    timer_interrupt_enable(TIMER2, TIMER_INT_UP);
    timer_enable(TIMER2);    
    nvic_irq_enable(TIMER2_IRQn, 3, 2);
             
}

void TIMER2_IRQHandler(void)  
{
    u16 u16TimeCount = 0;
    if (timer_interrupt_flag_get(TIMER2, TIMER_INT_UP) != RESET)  //检查TIM2更新中断发生与否
      {       
          if(u16TimeCount<200)
          {
              timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,spwm[u16TimeCount]);    
              timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,0);
              ++u16TimeCount;
          }
          else if(u16TimeCount >= 200 && u16TimeCount<400)    //一周期采样400个点
          {
              timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,0);
              timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,spwm[u16TimeCount-200]);
                
              ++u16TimeCount;
          }
          else
          {
              u16TimeCount = 0;
          }
            
          timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);  //清除TIMx更新中断标志           
    }
        
}

int main(void)
{     
     GpioInit();                                       //初始化升压电路控制引脚

     TIM0_PWM_Init();
     TIM2_Int_Init();                               
     TIM3_Int_Init(9999,11999);            //120M系统时钟--1s
}


总结

以上就是对实现SPWM波形的软件控制代码(已验证),后面还需要控制调制比和步长让波形达到自己电路的输出要求,鉴于大家设计的电路都不一样在这里就不做介绍了。SPWM数组根据自己设置的波形频率需要改变,这个生成工具网上可以下载,有需要的话博主也可以提供。博主是新手,希望各位看官多多包含和提出意见。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>