平台:keil V5.31
宏定义:
/* ================================================================
引脚和定时器单元定义
================================================================ */
// 第一路:TMR6_1, PA8/PB13
#define TMR6_1_UNIT CM_TMR6_1
#define PWM1_PORT_A GPIO_PORT_A
#define PWM1_PIN_A GPIO_PIN_08
#define PWM1_PORT_B GPIO_PORT_B
#define PWM1_PIN_B GPIO_PIN_13
// 第二路:TMR6_2, PA9/PB14
#define TMR6_2_UNIT CM_TMR6_2
#define PWM2_PORT_A GPIO_PORT_A
#define PWM2_PIN_A GPIO_PIN_09
#define PWM2_PORT_B GPIO_PORT_B
#define PWM2_PIN_B GPIO_PIN_14
// 第三路:TMR6_3, PA10/PB15
#define TMR6_3_UNIT CM_TMR6_3
#define PWM3_PORT_A GPIO_PORT_A
#define PWM3_PIN_A GPIO_PIN_10
#define PWM3_PORT_B GPIO_PORT_B
#define PWM3_PIN_B GPIO_PIN_15
#define PWM_FUNC GPIO_FUNC_3
/* ================================================================
PWM 参数配置
================================================================ */
#define PWM_FREQ_HZ 20000U // 20kHz PWM 频率
#define SYSTEM_CLOCK_HZ 200000000U // 200MHz 系统时钟 (PCLK0)
#define PWM_PERIOD (SYSTEM_CLOCK_HZ / PWM_FREQ_HZ) // 10000
// 死区时间: 1us
#define DEAD_TIME_NS 1000U
#define DEAD_TIME_COUNT ((DEAD_TIME_NS * (SYSTEM_CLOCK_HZ / 1000000U)) / 1000U) // 200
配置
static void GPIO_ConfigSinglePin(uint8_t u8Port, uint16_t u16Pin)
{
stc_gpio_init_t stcGpioInit;
GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinDir = PIN_DIR_OUT;
stcGpioInit.u16PinOutputType= PIN_OUT_TYPE_CMOS;
stcGpioInit.u16PinDrv = PIN_HIGH_DRV;
stcGpioInit.u16PinAttr = PIN_ATTR_DIGITAL;
GPIO_SetFunc(u8Port, u16Pin, PWM_FUNC);
GPIO_Init(u8Port, u16Pin, &stcGpioInit);
}
void GPIO_Config(void)
{
// 配置 PA8, PA9, PA10
GPIO_ConfigSinglePin(PWM1_PORT_A, PWM1_PIN_A);
GPIO_ConfigSinglePin(PWM2_PORT_A, PWM2_PIN_A);
GPIO_ConfigSinglePin(PWM3_PORT_A, PWM3_PIN_A);
// 配置 PB13, PB14, PB15
GPIO_ConfigSinglePin(PWM1_PORT_B, PWM1_PIN_B);
GPIO_ConfigSinglePin(PWM2_PORT_B, PWM2_PIN_B);
GPIO_ConfigSinglePin(PWM3_PORT_B, PWM3_PIN_B);
}
void TMR6_SinglePWM_Init(CM_TMR6_TypeDef *tmrUnit,
uint32_t fcgPeriph,
uint32_t period,
uint32_t deadTime,
uint8_t duty)
{
stc_tmr6_init_t stcTmr6Init;
stc_tmr6_pwm_init_t stcPwmInit;
// 1. 使能 Timer6 时钟
FCG_Fcg2PeriphClockCmd(fcgPeriph, ENABLE);
// 2. 基础计数配置
TMR6_StructInit(&stcTmr6Init);
stcTmr6Init.u8CountSrc = TMR6_CNT_SRC_SW; // 软件计数模式
stcTmr6Init.sw_count.u32CountMode = TMR6_MD_SAWTOOTH; // 锯齿波模式 (向上计数)
stcTmr6Init.sw_count.u32CountDir = TMR6_CNT_UP; // 向上计数
stcTmr6Init.sw_count.u32ClockDiv = TMR6_CLK_DIV1; // 不分频
stcTmr6Init.u32PeriodValue = period; // 周期值
TMR6_Init(tmrUnit, &stcTmr6Init);
// 3. 死区时间配置
// 先使能死区功能
TMR6_DeadTimeFuncCmd(tmrUnit, ENABLE);
// 配置死区寄存器(向上计数阶段)
TMR6_SetDeadTimeValue(tmrUnit, TMR6_DEADTIME_REG_UP_A, deadTime);
TMR6_SetDeadTimeValue(tmrUnit, TMR6_DEADTIME_REG_UP_B, deadTime);
// 配置死区寄存器(向下计数阶段),如果使用锯齿波模式,此值可设相同
TMR6_SetDeadTimeValue(tmrUnit, TMR6_DEADTIME_REG_DOWN_A, deadTime);
TMR6_SetDeadTimeValue(tmrUnit, TMR6_DEADTIME_REG_DOWN_B, deadTime);
// 4. 配置 PWMA 通道(主通道)
TMR6_PWM_StructInit(&stcPwmInit);
stcPwmInit.u32CompareValue = (period * duty) / 100; // 占空比
stcPwmInit.u32StartPolarity = TMR6_PWM_LOW; // 计数开始输出低
stcPwmInit.u32StopPolarity = TMR6_PWM_LOW; // 计数停止输出低
stcPwmInit.u32CompareMatchPolarity = TMR6_PWM_HIGH; // 比较匹配翻转为高
stcPwmInit.u32PeriodMatchPolarity = TMR6_PWM_LOW; // 周期匹配翻转为低
stcPwmInit.u32StartStopHold = TMR6_PWM_START_STOP_CHANGE;
TMR6_PWM_Init(tmrUnit, TMR6_CH_A, &stcPwmInit);
// 5. 配置 PWMB 通道(互补通道,极性相反)
TMR6_PWM_StructInit(&stcPwmInit);
stcPwmInit.u32CompareValue = (period * duty) / 100;
stcPwmInit.u32StartPolarity = TMR6_PWM_HIGH; // 与PWMA相反
stcPwmInit.u32StopPolarity = TMR6_PWM_HIGH; // 与PWMA相反
stcPwmInit.u32CompareMatchPolarity = TMR6_PWM_LOW; // 与PWMA相反
stcPwmInit.u32PeriodMatchPolarity = TMR6_PWM_HIGH; // 与PWMA相反
stcPwmInit.u32StartStopHold = TMR6_PWM_START_STOP_CHANGE;
TMR6_PWM_Init(tmrUnit, TMR6_CH_B, &stcPwmInit);
// 6. 设置引脚功能为比较输出
TMR6_SetFunc(tmrUnit, TMR6_CH_A, TMR6_PIN_CMP_OUTPUT);
TMR6_SetFunc(tmrUnit, TMR6_CH_B, TMR6_PIN_CMP_OUTPUT);
// 7. 使能 PWM 输出
TMR6_PWM_OutputCmd(tmrUnit, TMR6_CH_A, ENABLE);
TMR6_PWM_OutputCmd(tmrUnit, TMR6_CH_B, ENABLE);
}
void TMR6_AllPWM_Init(void)
{
// 初始化三路,初始占空比50%
TMR6_SinglePWM_Init(CM_TMR6_1, FCG2_PERIPH_TMR6_1, PWM_PERIOD, DEAD_TIME_COUNT, 50);
TMR6_SinglePWM_Init(CM_TMR6_2, FCG2_PERIPH_TMR6_2, PWM_PERIOD, DEAD_TIME_COUNT, 50);
TMR6_SinglePWM_Init(CM_TMR6_3, FCG2_PERIPH_TMR6_3, PWM_PERIOD, DEAD_TIME_COUNT, 50);
}
设置
void TMR6_StartAll(void)
{
TMR6_Start(CM_TMR6_1);
TMR6_Start(CM_TMR6_2);
TMR6_Start(CM_TMR6_3);
}
void TMR6_StopAll(void)
{
TMR6_Stop(CM_TMR6_1);
TMR6_Stop(CM_TMR6_2);
TMR6_Stop(CM_TMR6_3);
}
void TMR6_SetDuty(CM_TMR6_TypeDef *tmrUnit, uint8_t duty)
{
uint32_t compareValue;
if (duty > 100) duty = 100;
compareValue = (PWM_PERIOD * duty) / 100;
// 更新 PWMA 和 PWMB 的比较值(两者相同)
TMR6_SetCompareValue(tmrUnit, TMR6_CMP_REG_A, compareValue);
TMR6_SetCompareValue(tmrUnit, TMR6_CMP_REG_B, compareValue);
}
void TMR6_SyncStartAll(void)
{
// 使用软件同步功能同时启动 TMR6_1, TMR6_2, TMR6_3
TMR6_SWSyncStart(TMR6_SW_SYNC_ALL);
}
void TMR6_SyncStopAll(void)
{
TMR6_SWSyncStop(TMR6_SW_SYNC_ALL);
}
主函数
int main(void)
{
// 系统时钟初始化 (假设已配置为200MHz)
// SystemClock_Config();
/* Unlock peripherals or registers */
LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM);
// 配置GPIO
GPIO_Config();
// 初始化三路互补PWM
TMR6_AllPWM_Init();
// 启动所有PWM(方式1:分别启动)
// TMR6_StartAll();
// 或使用软件同步同时启动(方式2:推荐)
TMR6_SyncStartAll();
while (1)
{
// 示例:动态调整占空比
//// TMR6_SetDuty(CM_TMR6_1, 30); // 第一路 30%
//// TMR6_SetDuty(CM_TMR6_2, 60); // 第二路 60%
//// TMR6_SetDuty(CM_TMR6_3, 90); // 第三路 90%
// delay_ms(1000);
}
}
实验结果:

