diff --git a/Project/HC32F460/source/Module/dc_motor/dc_motor.c b/Project/HC32F460/source/Module/dc_motor/dc_motor.c index bb60a0c..da01ae2 100644 --- a/Project/HC32F460/source/Module/dc_motor/dc_motor.c +++ b/Project/HC32F460/source/Module/dc_motor/dc_motor.c @@ -65,6 +65,9 @@ void DCMOTORDBGOnOff(uint8_t OnOff) #define TIMER4_PWM_H_PIN (Pin09) #define TIMER4_PWM_L_PORT (PortB) /* TIM4_1_OUL_B:PE8 TIM4_1_OVL_B:PE10 TIM4_1_OWL_B:PE12 */ #define TIMER4_PWM_L_PIN (Pin14) + +en_timer4_oco_ch_t enOcoLowCh = (en_timer4_oco_ch_t)(TIMER4_OCO_HIGH_CH + 1); + #endif @@ -375,7 +378,7 @@ void AdcLoopHander(void) - +#if(0) void Timer41_Init(uint8_t dir) { uint8_t E_OC_Port = 0; @@ -516,9 +519,131 @@ void Timer41_Init(uint8_t dir) TIMER4_CNT_Start(TIMER4_UNIT); } +#endif +#if(1) +void Timer41_Init(void) +{ + stc_timer4_cnt_init_t stcCntInit; + stc_timer4_oco_init_t stcOcoInit; + stc_timer4_pwm_init_t stcPwmInit; + stc_oco_low_ch_compare_mode_t stcLowChCmpMode; + stc_oco_high_ch_compare_mode_t stcHighChCmpMode; + uint16_t u8OcoOccrVal = TIMER4_CNT_CYCLE_VAL/10u; + en_timer4_oco_ch_t enOcoLowCh = (en_timer4_oco_ch_t)(TIMER4_OCO_HIGH_CH + 1); + + /* Clear structures */ + MEM_ZERO_STRUCT(stcCntInit); + MEM_ZERO_STRUCT(stcOcoInit); + MEM_ZERO_STRUCT(stcLowChCmpMode); + MEM_ZERO_STRUCT(stcHighChCmpMode); + MEM_ZERO_STRUCT(stcPwmInit); + + /* Enable peripheral clock */ + PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM41, Enable); + + /* Timer4 CNT : Initialize CNT configuration structure */ + stcCntInit.enBufferCmd = Disable; + stcCntInit.enClk = Timer4CntPclk; + stcCntInit.enClkDiv = Timer4CntPclkDiv4; /* CNT clock divide */ + stcCntInit.u16Cycle = TIMER4_CNT_CYCLE_VAL; +// stcCntInit.enCntMode = Timer4CntSawtoothWave; //锯齿波模式 + stcCntInit.enCntMode = Timer4CntTriangularWave; //三角波模式Timer4CntTriangularWave + stcCntInit.enZeroIntCmd = Disable; + stcCntInit.enPeakIntCmd = Disable; + stcCntInit.enZeroIntMsk = Timer4CntIntMask0; + stcCntInit.enPeakIntMsk = Timer4CntIntMask0; + TIMER4_CNT_Init(TIMER4_UNIT, &stcCntInit); /* Initialize CNT */ + + /* Timer4 OCO : Initialize OCO configuration structure */ + stcOcoInit.enOccrBufMode = OccrBufDisable; + stcOcoInit.enOcmrBufMode = OcmrBufDisable; + stcOcoInit.enPortLevel = OcPortLevelHigh; /*输出高电平到OC端口*/ + stcOcoInit.enOcoIntCmd = Disable; + TIMER4_OCO_Init(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, &stcOcoInit); /* Initialize OCO high channel */ + TIMER4_OCO_Init(TIMER4_UNIT, enOcoLowCh, &stcOcoInit); /* Initialize OCO low channel */ + + if (!(TIMER4_OCO_HIGH_CH % 2)) + { + /* ocmr[15:0] = 0x225F */ + stcHighChCmpMode.enCntZeroNotMatchOpState = OcoOpOutputHold; ///< b15~b14 + stcHighChCmpMode.enCntPeakNotMatchOpState = OcoOpOutputLow; ///< b13~b12 + stcHighChCmpMode.enCntZeroMatchOpState = OcoOpOutputHold; ///< b11~b10 + stcHighChCmpMode.enCntUpCntMatchOpState = OcoOpOutputLow; ///< b9~b8 + stcHighChCmpMode.enCntPeakMatchOpState = OcoOpOutputHigh; ///< b7~b6 + stcHighChCmpMode.enCntDownCntMatchOpState = OcoOpOutputHigh; ///< b5~b4 + + stcHighChCmpMode.enCntZeroMatchOcfState = OcoOcfSet; ///< b3 + stcHighChCmpMode.enCntUpCntMatchOcfState = OcoOcfSet; ///< b2 + stcHighChCmpMode.enCntPeakMatchOcfState = OcoOcfSet; ///< b1 + stcHighChCmpMode.enCntDownCntMatchOcfState = OcoOcfSet; ///< b0 + + stcHighChCmpMode.enMatchConditionExtendCmd = Disable; + + TIMER4_OCO_SetHighChCompareMode(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, &stcHighChCmpMode); /* Set OCO high channel compare mode */ + } + + /*************Timer4 OCO ocmr1[31:0] = 0x0FF0 0FFF*****************************/ + if (enOcoLowCh % 2) + { + /* OCMR[31:0] Ox 2250 225F 0000 1111 1111 0000 0000 1111 1111 1111 */ + stcLowChCmpMode.enCntZeroLowMatchHighMatchLowChOpState = OcoOpOutputHold; /* bit[27:26] 00 */ + stcLowChCmpMode.enCntZeroLowMatchHighNotMatchLowChOpState = OcoOpOutputHold; /* bit[11:10] 00 */ + stcLowChCmpMode.enCntZeroLowNotMatchHighMatchLowChOpState = OcoOpOutputHold; /* bit[31:30] 00 */ + stcLowChCmpMode.enCntZeroLowNotMatchHighNotMatchLowChOpState = OcoOpOutputHold; /* bit[15:14] 00 */ + + stcLowChCmpMode.enCntUpCntLowMatchHighMatchLowChOpState = OcoOpOutputLow; /* bit[25:24] 10 */ + stcLowChCmpMode.enCntUpCntLowMatchHighNotMatchLowChOpState = OcoOpOutputLow; /* bit[9:8] 10 */ + stcLowChCmpMode.enCntUpCntLowNotMatchHighMatchLowChOpState = OcoOpOutputHold; /* bit[19:18] 00 */ + + stcLowChCmpMode.enCntPeakLowMatchHighMatchLowChOpState = OcoOpOutputHigh; /* bit[23:22] 01 */ + stcLowChCmpMode.enCntPeakLowMatchHighNotMatchLowChOpState = OcoOpOutputHigh; /* bit[7:6] 01 */ + stcLowChCmpMode.enCntPeakLowNotMatchHighMatchLowChOpState = OcoOpOutputLow; /* bit[29:28] 10 */ + stcLowChCmpMode.enCntPeakLowNotMatchHighNotMatchLowChOpState = OcoOpOutputLow; /* bit[13:12] 10 */ + + stcLowChCmpMode.enCntDownLowMatchHighMatchLowChOpState = OcoOpOutputHigh; /* bit[21:20] 01 */ + stcLowChCmpMode.enCntDownLowMatchHighNotMatchLowChOpState = OcoOpOutputHigh; /* bit[5:4] 01 */ + stcLowChCmpMode.enCntDownLowNotMatchHighMatchLowChOpState = OcoOpOutputHold; /* bit[17:16] 00 */ + + stcLowChCmpMode.enCntZeroMatchOcfState = OcoOcfSet; /* bit[3] 1 */ + stcLowChCmpMode.enCntUpCntMatchOcfState = OcoOcfSet; /* bit[2] 1 */ + stcLowChCmpMode.enCntPeakMatchOcfState = OcoOcfSet; /* bit[1] 1 */ + stcLowChCmpMode.enCntDownCntMatchOcfState = OcoOcfSet; /* bit[0] 1 */ + + TIMER4_OCO_SetLowChCompareMode(TIMER4_UNIT, enOcoLowCh, &stcLowChCmpMode); /* Set OCO low channel compare mode */ + } + +// /* Set OCO compare value */ + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, 0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, 0); + + /* Enable OCO */ + + TIMER4_OCO_OutputCompareCmd(TIMER4_UNIT, enOcoLowCh, Enable); + TIMER4_OCO_OutputCompareCmd(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, Enable); + + /* Initialize PWM I/O */ + PORT_SetFunc(TIMER4_PWM_H_PORT, TIMER4_PWM_H_PIN, Func_Tim4, Disable); + PORT_SetFunc(TIMER4_PWM_L_PORT, TIMER4_PWM_L_PIN, Func_Tim4, Disable); + + /* Timer4 PWM: Initialize PWM configuration structure */ + //重载定时器中断 + stcPwmInit.enRtIntMaskCmd = Enable; + //计数时钟分频 + stcPwmInit.enClkDiv = PwmPlckDiv1; /*滤波计数器和死区计数器的计数时钟分频*/ + //PWM输出极性控制 + stcPwmInit.enOutputState = PwmHPwmLReverse; /*输出PWMH信号不改变电平,输出PWML信号反转*/ + //PWM输出模式 + stcPwmInit.enMode = PwmThroughMode; /*直通模式*/ + TIMER4_PWM_Init(TIMER4_UNIT, TIMER4_PWM_CH, &stcPwmInit); /* Initialize timer4 pwm */ + + /* Clear && Start CNT */ + TIMER4_CNT_Start(TIMER4_UNIT); +} + +#endif void Timer61A_Init(void) { @@ -691,10 +816,12 @@ void dcmotor_init(void) // PORT_SetBits(PortA, Pin03); // /* SD拉低,关闭输出 */ // -// dcmotor_stop(); /* 停止电机 */ -// dcmotor_dir(0); /* 设置正转 */ -// dcmotor_speed(0); /* 速度设置为0 */ -// dcmotor_start(); /* 开启电机 */ + Timer41_Init(); + + dcmotor_stop(); /* 停止电机 */ + dcmotor_dir(0); /* 设置正转 */ + dcmotor_speed(0); /* 速度设置为0 */ + dcmotor_start(); /* 开启电机 */ } /** @@ -719,7 +846,10 @@ void dcmotor_stop(void) #endif #if(TIMER == TIMER4) - TIMER4_CNT_Stop(TIMER4_UNIT); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, 0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, 0u); + DISABLE_MOTOR; + #endif } @@ -751,17 +881,19 @@ void dcmotor_dir(uint8_t para) #endif #if(TIMER == TIMER4) + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, 0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, 0u); if (para == 0) /* 正转 */ { - - - Timer41_Init(1); - + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, 0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, 0u); } else if (para == 1) /* 反转 */ { - Timer41_Init(0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, 0); + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, 0u); } + dcmotor_start(); #endif } @@ -782,8 +914,8 @@ void dcmotor_speed(uint16_t para) #endif #if(TIMER == TIMER4) - TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, TIMER4_CNT_CYCLE_VAL - g_motorSpeed); //正转 - TIMER4_OCO_WriteOccr(TIMER4_UNIT, Timer4OcoOul, TIMER4_CNT_CYCLE_VAL - g_motorSpeed); //反转 + TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, g_motorSpeed); //正转 + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, g_motorSpeed); //反转 #endif dcmotor_stop(); return; @@ -797,10 +929,7 @@ void dcmotor_speed(uint16_t para) #endif #if(TIMER == TIMER4) -// TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, TIMER4_CNT_CYCLE_VAL - g_motorSpeed); //正转 -// TIMER4_OCO_WriteOccr(TIMER4_UNIT, Timer4OcoOul, TIMER4_CNT_CYCLE_VAL - g_motorSpeed); //反转 - TIMER4_OCO_WriteOccr(TIMER4_UNIT, Timer4OcoOul, g_motorSpeed); //反转 - + TIMER4_OCO_WriteOccr(TIMER4_UNIT, enOcoLowCh, g_motorSpeed); //反转 #endif DCMOTOR_DBG_LOG("REVERSE\tnewSpeed = %d\r\n", g_motorSpeed); @@ -814,7 +943,6 @@ void dcmotor_speed(uint16_t para) #if(TIMER == TIMER4) TIMER4_OCO_WriteOccr(TIMER4_UNIT, TIMER4_OCO_HIGH_CH, g_motorSpeed); //正转 -// TIMER4_OCO_WriteOccr(TIMER4_UNIT, Timer4OcoOul, TIMER4_CNT_CYCLE_VAL - g_motorSpeed); //反转 #endif DCMOTOR_DBG_LOG("FORWARD\tnewSpeed = %d\r\n", g_motorSpeed); }