小华芯片HC32F460之TMR6输出互补PWM

📅 2026/7/30 2:40:12
小华芯片HC32F460之TMR6输出互补PWM
平台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); } }实验结果