简介
- PWM(Pulse Width Modulation,脉宽调制)常用于电机驱动、灯光调节等场景。
- 本文基于GD32F303CCT6平台,使用TIMER0实现三路PWM输出。
引脚配置
通道 | 信号 | MCU引脚 | 复用模式 | 方向 | 备注 |
---|---|---|---|---|---|
PhaseC | CH0 | PA8 | GPIO_MODE_AF_PP | 输出 | PWM通道C |
PhaseB | CH1 | PA9 | GPIO_MODE_AF_PP | 输出 | PWM通道B |
PhaseA | CH2 | PA10 | GPIO_MODE_AF_PP | 输出 | PWM通道A |
- 使用定时器:TIMER0
- 输出模式:推挽复用输出,50MHz
- 频率:15KHz左右
PWM配置
主要宏定义如下:
宏定义名 | 说明 | 默认值 |
---|---|---|
PWM_DRIVER_ENABLE | PWM驱动使能开关 | 1 |
PWM_DUTY_LOW | 最低占空比(0%) | 0 |
PWM_DUTY_HIGH | 最高占空比(100%) | 899 |
初始化代码示例:
#include "pwm_config.h"
#define PWM_PHASE_A_PORT GPIOA
#define PWM_PHASE_A_PIN GPIO_PIN_10
#define PWM_PHASE_A_FUNC GPIO_MODE_AF_PP
#define PWM_PHASE_A_TIMER TIMER0
#define PWM_PHASE_A_TIMER_CH TIMER_CH_2
#define PWM_PHASE_A_TIMER_MODE TIMER_OC_MODE_PWM1
#define PWM_PHASE_B_PORT GPIOA
#define PWM_PHASE_B_PIN GPIO_PIN_9
#define PWM_PHASE_B_FUNC GPIO_MODE_AF_PP
#define PWM_PHASE_B_TIMER TIMER0
#define PWM_PHASE_B_TIMER_CH TIMER_CH_1
#define PWM_PHASE_B_TIMER_MODE TIMER_OC_MODE_PWM1
#define PWM_PHASE_C_PORT GPIOA
#define PWM_PHASE_C_PIN GPIO_PIN_8
#define PWM_PHASE_C_FUNC GPIO_MODE_AF_PP
#define PWM_PHASE_C_TIMER TIMER0
#define PWM_PHASE_C_TIMER_CH TIMER_CH_0
#define PWM_PHASE_C_TIMER_MODE TIMER_OC_MODE_PWM1
void 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_TIMER0);
/* GPIO:推挽复用输出 50 MHz */
gpio_init(PWM_PHASE_A_PORT, PWM_PHASE_A_FUNC, GPIO_OSPEED_50MHZ, PWM_PHASE_A_PIN);
gpio_init(PWM_PHASE_B_PORT, PWM_PHASE_B_FUNC, GPIO_OSPEED_50MHZ, PWM_PHASE_B_PIN);
gpio_init(PWM_PHASE_C_PORT, PWM_PHASE_C_FUNC, GPIO_OSPEED_50MHZ, PWM_PHASE_C_PIN);
timer_deinit(TIMER0);
timer_struct_para_init(&timer_initpara);
/* TIMER0 configuration */
timer_initpara.prescaler = 8 - 1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 1000 - 1; /* 15KHz */
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0,&timer_initpara);
/* CH0,CH1 and CH2 configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
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_auto_reload_shadow_enable(TIMER0);
/* 初始占空比 50% */
uint16_t duty = 500; /* 50%占空比 */
/* ---------- Configure PWM Channel 0 (Phase A) ---------- */
/* CH0 → PA8 (PWMA) - Configure timer channel output */
timer_channel_output_config(PWM_PHASE_A_TIMER, PWM_PHASE_A_TIMER_CH, &timer_ocintpara);
timer_channel_output_pulse_value_config(PWM_PHASE_A_TIMER, PWM_PHASE_A_TIMER_CH, duty);
timer_channel_output_mode_config(PWM_PHASE_A_TIMER, PWM_PHASE_A_TIMER_CH, TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(PWM_PHASE_A_TIMER, PWM_PHASE_A_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
/* ---------- Configure PWM Channel 1 (Phase B) ---------- */
/* CH1 → PA9 (PWMB) - Configure timer channel output */
timer_channel_output_config(PWM_PHASE_B_TIMER, PWM_PHASE_B_TIMER_CH, &timer_ocintpara);
timer_channel_output_pulse_value_config(PWM_PHASE_B_TIMER, PWM_PHASE_B_TIMER_CH, duty);
timer_channel_output_mode_config(PWM_PHASE_B_TIMER, PWM_PHASE_B_TIMER_CH, TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(PWM_PHASE_B_TIMER, PWM_PHASE_B_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
/* ---------- Configure PWM Channel 2 (Phase C) ---------- */
/* CH2 → PA10 (PWMC) - Configure timer channel output */
timer_channel_output_config(PWM_PHASE_C_TIMER, PWM_PHASE_C_TIMER_CH, &timer_ocintpara);
timer_channel_output_pulse_value_config(PWM_PHASE_C_TIMER, PWM_PHASE_C_TIMER_CH, duty);
timer_channel_output_mode_config(PWM_PHASE_C_TIMER, PWM_PHASE_C_TIMER_CH, TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(PWM_PHASE_C_TIMER, PWM_PHASE_C_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
timer_breakpara.runoffstate = TIMER_ROS_STATE_ENABLE; /* 运行时使能输出 */
timer_breakpara.ideloffstate = TIMER_IOS_STATE_ENABLE; /* 空闲时使能输出 */
timer_breakpara.deadtime = 200;
timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_HIGH;
timer_breakpara.outputautostate = TIMER_OUTAUTO_DISABLE;
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);
/* TIMER0 counter enable */
timer_enable(TIMER0);
}