文章目录
- 前言
- 一、原理介绍
- 二、代码
- 1.GD32F303RCT6的PWM配置
- 2.GD32F303RCT6的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 functiongpio_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 functiongpio_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.2ustimer_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; //60HzTIM_TimeBaseStructure.prescaler = 0; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.clockdivision = TIMER_CKDIV_DIV1; //设置时钟分割:TDTS = Tck_timTIM_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数组根据自己设置的波形频率需要改变,这个生成工具网上可以下载,有需要的话博主也可以提供。博主是新手,希望各位看官多多包含和提出意见。