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

📅 2026/8/3 12:23:00
小华芯片HC32F460之TMR4输出互补PWM
平台keil V5.31代码/******************************************************************************* * Include files ******************************************************************************/ #include main.h /******************************************************************************* * Local type definitions (typedef) ******************************************************************************/ /******************************************************************************* * Local pre-processor symbols/macros (#define) ******************************************************************************/ /* Peripheral register WE/WP selection */ #define LL_PERIPH_SEL (LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \ LL_PERIPH_EFM | LL_PERIPH_SRAM) /* Get TMR4 PWM channel by OC channel */ #define TMR4_PWM_CH(x) (((x) TMR4_OC_CH_UL) ? TMR4_PWM_CH_U : \ (((x) TMR4_OC_CH_VL) ? TMR4_PWM_CH_V : TMR4_PWM_CH_W)) ///* Get TMR4 PWM port by PWM channel */ //#define TMR4_PWM_PIN_OXH(x) ((TMR4_PWM_CH_U (x)) ? TMR4_PWM_PIN_OUH : \ // ((TMR4_PWM_CH_V (x)) ? TMR4_PWM_PIN_OVH : TMR4_PWM_PIN_OWH)) //#define TMR4_PWM_PIN_OXL(x) ((TMR4_PWM_CH_U (x)) ? TMR4_PWM_PIN_OUL : \ // ((TMR4_PWM_CH_V (x)) ? TMR4_PWM_PIN_OVL : TMR4_PWM_PIN_OWL)) #define PWM_FREQ_HZ 20000U // 20kHz PWM 频率 #define SYSTEM_CLOCK_HZ 200000000U // 200MHz 系统时钟 (PCLK0) #define PWM_PERIOD (SYSTEM_CLOCK_HZ / PWM_FREQ_HZ) // 10000 /** * brief Get TMR4 clock frequency. * param None * retval TMR4 clock frequency */ static uint32_t TMR4_ClockFreq(void) { return CLK_GetBusClockFreq(CLK_BUS_PCLK1); } /** * brief Main function of TMR4 PWM dead timer mode * param None * retval int32_t return value, if needed */ #define BSP_XTAL_PORT (GPIO_PORT_H) #define BSP_XTAL_PIN (GPIO_PIN_00 | GPIO_PIN_01) __WEAKDEF void BSP_CLK_Init(void) { stc_clock_xtal_init_t stcXtalInit; stc_clock_pll_init_t stcMpllInit; GPIO_AnalogCmd(BSP_XTAL_PORT, BSP_XTAL_PIN, ENABLE); (void)CLK_XtalStructInit(stcXtalInit); (void)CLK_PLLStructInit(stcMpllInit); /* Set bus clk div. */ CLK_SetClockDiv(CLK_BUS_CLK_ALL, (CLK_HCLK_DIV1 | CLK_EXCLK_DIV2 | CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | \ CLK_PCLK2_DIV4 | CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2)); /* Config Xtal and enable Xtal */ stcXtalInit.u8Mode CLK_XTAL_MD_OSC; stcXtalInit.u8Drv CLK_XTAL_DRV_ULOW; stcXtalInit.u8State CLK_XTAL_ON; stcXtalInit.u8StableTime CLK_XTAL_STB_2MS; (void)CLK_XtalInit(stcXtalInit); /* MPLL config (XTAL / pllmDiv * plln / PllpDiv 200M). */ stcMpllInit.PLLCFGR 0UL; stcMpllInit.PLLCFGR_f.PLLM 1UL - 1UL; stcMpllInit.PLLCFGR_f.PLLN 50UL - 1UL; stcMpllInit.PLLCFGR_f.PLLP 2UL - 1UL; stcMpllInit.PLLCFGR_f.PLLQ 2UL - 1UL; stcMpllInit.PLLCFGR_f.PLLR 2UL - 1UL; stcMpllInit.u8PLLState CLK_PLL_ON; stcMpllInit.PLLCFGR_f.PLLSRC CLK_PLL_SRC_XTAL; (void)CLK_PLLInit(stcMpllInit); /* Wait MPLL ready. */ while (SET ! CLK_GetStableStatus(CLK_STB_FLAG_PLL)) { ; } /* sram init include read/write wait cycle setting */ SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE0, SRAM_WAIT_CYCLE0); SRAM_SetWaitCycle((SRAM_SRAM12 | SRAM_SRAM3 | SRAM_SRAMR), SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1); /* flash read wait cycle setting */ (void)EFM_SetWaitCycle(EFM_WAIT_CYCLE5); /* 3 cycles for 126MHz ~ 200MHz */ GPIO_SetReadWaitCycle(GPIO_RD_WAIT3); /* Switch driver ability */ (void)PWC_HighSpeedToHighPerformance(); /* Switch system clock source to MPLL. */ CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL); /* Reset cache ram */ EFM_CacheRamReset(ENABLE); EFM_CacheRamReset(DISABLE); /* Enable cache */ EFM_CacheCmd(ENABLE); } unsigned int temp0; int32_t main(void) { uint32_t u32PwmCh; stc_tmr4_init_t stcTmr4Init; stc_tmr4_oc_init_t stcTmr4OcInit; stc_tmr4_pwm_init_t stcTmr4PwmInit; un_tmr4_oc_ocmrh_t unTmr4OcOcmrh; un_tmr4_oc_ocmrl_t unTmr4OcOcmrl; /* MCU Peripheral registers write unprotected */ LL_PERIPH_WE(LL_PERIPH_SEL); /* Initialize BSP system clock. */ BSP_CLK_Init(); /* Initialize PWM I/O */ GPIO_SetFunc(GPIO_PORT_A, GPIO_PIN_08, GPIO_FUNC_2); GPIO_SetFunc(GPIO_PORT_B, GPIO_PIN_13, GPIO_FUNC_2); /* Enable TMR4 peripheral clock */ FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMR4_1, ENABLE); /* MCU Peripheral registers write protected */ LL_PERIPH_WP(LL_PERIPH_SEL); /************************* Configure TMR4 counter *************************/ (void)TMR4_StructInit(stcTmr4Init); stcTmr4Init.u16ClockSrc TMR4_CLK_SRC_INTERNCLK; stcTmr4Init.u16CountMode TMR4_MD_TRIANGLE; stcTmr4Init.u16ClockDiv TMR4_CLK_DIV1;//TMR4_CLK_DIV128; stcTmr4Init.u16PeriodValue PWM_PERIOD;//TMR4_CNT_PERIOD_VALUE(stcTmr4Init.u16ClockDiv); (void)TMR4_Init(CM_TMR4_1, stcTmr4Init); /************************* Configure TMR4 output-compare ******************/ /* TMR4 OC low channel: initialize */ (void)TMR4_OC_StructInit(stcTmr4OcInit); stcTmr4OcInit.u16CompareValue stcTmr4Init.u16PeriodValue / 2U; (void)TMR4_OC_Init(CM_TMR4_1, TMR4_OC_CH_UL, stcTmr4OcInit); /* TMR4 OCO low channel: compare mode OCMR[31:0] 0x0FF0 0FFF b 0000 1111 1111 0000 0000 1111 1111 1111 */ unTmr4OcOcmrl.OCMRx_f.OCFDCL TMR4_OC_OCF_SET; /* bit[0] 1 */ unTmr4OcOcmrl.OCMRx_f.OCFPKL TMR4_OC_OCF_SET; /* bit[1] 1 */ unTmr4OcOcmrl.OCMRx_f.OCFUCL TMR4_OC_OCF_SET; /* bit[2] 1 */ unTmr4OcOcmrl.OCMRx_f.OCFZRL TMR4_OC_OCF_SET; /* bit[3] 1 */ unTmr4OcOcmrl.OCMRx_f.OPDCL TMR4_OC_INVT; /* bit[5:4] 11 */ unTmr4OcOcmrl.OCMRx_f.OPPKL TMR4_OC_INVT; /* bit[7:6] 11 */ unTmr4OcOcmrl.OCMRx_f.OPUCL TMR4_OC_INVT; /* bit[9:8] 11 */ unTmr4OcOcmrl.OCMRx_f.OPZRL TMR4_OC_INVT; /* bit[11:10] 11 */ unTmr4OcOcmrl.OCMRx_f.OPNPKL TMR4_OC_HOLD; /* bit[13:12] 00 */ unTmr4OcOcmrl.OCMRx_f.OPNZRL TMR4_OC_HOLD; /* bit[15:14] 00 */ unTmr4OcOcmrl.OCMRx_f.EOPNDCL TMR4_OC_HOLD; /* bit[17:16] 00 */ unTmr4OcOcmrl.OCMRx_f.EOPNUCL TMR4_OC_HOLD; /* bit[19:18] 00 */ unTmr4OcOcmrl.OCMRx_f.EOPDCL TMR4_OC_INVT; /* bit[21:20] 11 */ unTmr4OcOcmrl.OCMRx_f.EOPPKL TMR4_OC_INVT; /* bit[23:22] 11 */ unTmr4OcOcmrl.OCMRx_f.EOPUCL TMR4_OC_INVT; /* bit[25:24] 11 */ unTmr4OcOcmrl.OCMRx_f.EOPZRL TMR4_OC_INVT; /* bit[27:26] 11 */ unTmr4OcOcmrl.OCMRx_f.EOPNPKL TMR4_OC_HOLD; /* bit[29:28] 00 */ unTmr4OcOcmrl.OCMRx_f.EOPNZRL TMR4_OC_HOLD; /* bit[31:30] 00 */ TMR4_OC_SetLowChCompareMode(CM_TMR4_1, TMR4_OC_CH_UL, unTmr4OcOcmrl); /* TMR4 OC low channel: enable */ TMR4_OC_Cmd(CM_TMR4_1, TMR4_OC_CH_UL, ENABLE); /************************* Configure TMR4 PWM *****************************/ u32PwmCh TMR4_PWM_CH(TMR4_OC_CH_UL); /* TMR4 PWM: initialize */ (void)TMR4_PWM_StructInit(stcTmr4PwmInit); stcTmr4PwmInit.u16Mode TMR4_PWM_MD_DEAD_TMR; stcTmr4PwmInit.u16ClockDiv TMR4_PWM_CLK_DIV128; (void)TMR4_PWM_Init(CM_TMR4_1, u32PwmCh, stcTmr4PwmInit); /* TMR4 PWM: set dead time count */ TMR4_PWM_SetDeadTimeValue(CM_TMR4_1, u32PwmCh, TMR4_PWM_PDAR_IDX, 10U/*TMR4_OC_GetCompareValue(TMR4_UNIT, TMR4_OC_CH)*/); TMR4_PWM_SetDeadTimeValue(CM_TMR4_1, u32PwmCh, TMR4_PWM_PDBR_IDX, 10U); /* Start TMR4 count. */ TMR4_Start(CM_TMR4_1); for (;;) { temp; } }实验结果示波器测量PA8和PB13如果要配置V相PA9和PB14只需要把TMR4_OC_CH_UL替换成TMR4_OC_CH_VL即可同样配置W相PA10和PB15只需要把TMR4_OC_CH_UL替换成TMR4_OC_CH_WL即可。