diff --git a/Project/HC32F460/MDK/HC32F460.uvoptx b/Project/HC32F460/MDK/HC32F460.uvoptx
index 8a1f3d6..2db777c 100644
--- a/Project/HC32F460/MDK/HC32F460.uvoptx
+++ b/Project/HC32F460/MDK/HC32F460.uvoptx
@@ -101,9 +101,7 @@
0
0
1
- 0
- 0
- 6
+ 2
@@ -114,9 +112,14 @@
- Segger\JL2CM3.dll
+ BIN\CMSIS_AGDI.dll
+
+ 0
+ CMSIS_AGDI
+ -X"" -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD1FFF8000 -FC1000 -FN2 -FF0HC32F460_512K.FLM -FS00 -FL080000 -FP0($$Device:HC32F460JEUA$FlashARM\HC32F460_512K.FLM) -FF1HC32F460_otp.FLM -FS13000C00 -FL13FC -FP1($$Device:HC32F460JEUA$FlashARM\HC32F460_otp.FLM)
+
0
ARMRTXEVENTFLAGS
@@ -205,6 +208,26 @@
1
App.ADTrack.RightLow_Org_AdZero,0x0A
+
+ 11
+ 1
+ LeftSlopeSum,0x0A
+
+
+ 12
+ 1
+ RightSlopeSum,0x0A
+
+
+ 13
+ 1
+ LeftDiffSum,0x0A
+
+
+ 14
+ 1
+ RightDiffSum,0x0A
+
0
@@ -250,7 +273,6 @@
1
- 1
0
2
1000000
@@ -338,8 +360,6 @@
0
0
1
- 0
- 0
-1
@@ -401,7 +421,7 @@
common
- 0
+ 1
0
0
0
@@ -421,7 +441,7 @@
1
2
1
- 0
+ 1
0
0
..\..\..\mcu\common\system_hc32f460.c
@@ -433,7 +453,7 @@
driver
- 0
+ 1
0
0
0
@@ -1067,6 +1087,26 @@
+
+ dc_motor
+ 1
+ 0
+ 0
+ 0
+
+ 5
+ 54
+ 1
+ 0
+ 0
+ 0
+ ..\source\Module\dc_motor\dc_motor.c
+ dc_motor.c
+ 0
+ 0
+
+
+
Readme
0
diff --git a/Project/HC32F460/MDK/HC32F460.uvprojx b/Project/HC32F460/MDK/HC32F460.uvprojx
index 7b4f278..4fcfdad 100644
--- a/Project/HC32F460/MDK/HC32F460.uvprojx
+++ b/Project/HC32F460/MDK/HC32F460.uvprojx
@@ -10,7 +10,7 @@
Debug
0x4
ARM-ADS
- 5060960::V5.06 update 7 (build 960)::ARMCC
+ 5060528::V5.06 update 5 (build 528)::ARMCC
0
@@ -184,9 +184,6 @@
0
0
1
- 0
- 0
- 0
1
1
8
@@ -327,7 +324,6 @@
0
0
1
- 0
0
3
5
@@ -340,7 +336,7 @@
__DEBUG,HC32F460,USE_DEVICE_DRIVER_LIB,JEUA
- ..\..\..\mcu\common;..\source\User\Inc;..\source\User\Src;..\..\..\driver\src;..\..\..\driver\inc;..\source\Module\CS1237
+ ..\..\..\mcu\common;..\source\User\Inc;..\source\User\Src;..\..\..\driver\src;..\..\..\driver\inc;..\source\Module\CS1237;..\source\Module\dc_motor
@@ -353,7 +349,7 @@
0
0
0
- 4
+ 0
@@ -666,6 +662,16 @@
+
+ dc_motor
+
+
+ dc_motor.c
+ 1
+ ..\source\Module\dc_motor\dc_motor.c
+
+
+
Readme
@@ -852,9 +858,6 @@
0
0
1
- 0
- 0
- 0
1
1
8
@@ -995,7 +998,6 @@
0
0
1
- 0
0
0
0
@@ -1021,7 +1023,7 @@
0
0
0
- 1
+ 0
@@ -1334,6 +1336,16 @@
+
+ dc_motor
+
+
+ dc_motor.c
+ 1
+ ..\source\Module\dc_motor\dc_motor.c
+
+
+
Readme
@@ -1358,14 +1370,4 @@
-
-
-
- HC32F460
- 0
- 1
-
-
-
-
diff --git a/Project/HC32F460/MDK/RTE/_Debug/RTE_Components.h b/Project/HC32F460/MDK/RTE/_Debug/RTE_Components.h
index 14a0fac..c0360b3 100644
--- a/Project/HC32F460/MDK/RTE/_Debug/RTE_Components.h
+++ b/Project/HC32F460/MDK/RTE/_Debug/RTE_Components.h
@@ -1,6 +1,6 @@
/*
- * Auto generated Run-Time-Environment Configuration File
+ * Auto generated Run-Time-Environment Component Configuration File
* *** Do not modify ! ***
*
* Project: 'HC32F460'
@@ -17,5 +17,4 @@
#define CMSIS_device_header "HC32F460JEUA.h"
-
#endif /* RTE_COMPONENTS_H */
diff --git a/Project/HC32F460/source/Module/dc_motor/dc_motor.c b/Project/HC32F460/source/Module/dc_motor/dc_motor.c
new file mode 100644
index 0000000..f1d056d
--- /dev/null
+++ b/Project/HC32F460/source/Module/dc_motor/dc_motor.c
@@ -0,0 +1,553 @@
+#include "dc_motor.h"
+#include "hc32_ddl.h"
+#include "Debug.h"
+
+
+
+// 全局变量
+volatile MotorState g_motorState = MOTOR_STOPPED;
+volatile MotorCommand g_motorCmd = MOTOR_CMD_STOP;
+volatile MotorDirection g_motorDirection = DIR_STOPPED; // 新增运行方向标志位
+volatile uint16_t g_motorSpeed = 0;
+volatile uint16_t g_accelTimer = 0;
+
+static uint16_t accelCounter = 0;
+
+
+static uint8_t DcMotorDispEn = true;
+
+#define DCMOTOR_DBG_LOG(...) { if(DcMotorDispEn) DBG_LOG(__VA_ARGS__);}
+#define DCMOTOR_DBG_ARRAY(ARRAY, SIZE) { if(DcMotorDispEn) {DBG_ARRAY(ARRAY,SIZE)}}
+
+
+
+void DCMOTORDBGOnOff(uint8_t OnOff)
+{
+ DcMotorDispEn = OnOff;
+ if(OnOff)
+ DBG_LOG("\r\nKey Display Enable!\r\n");
+ else
+ DBG_LOG("\r\nKey Display Disable!\r\n");
+}
+
+
+void Timer61A_Init(void)
+{
+ uint16_t u16Period;
+// uint16_t u16Compare;
+ stc_timer6_basecnt_cfg_t stcTIM6BaseCntCfg;
+ stc_timer6_port_output_cfg_t stcTIM6PWMxCfg;
+ stc_timer6_gcmp_buf_cfg_t stcGCMPBufCfg;
+ stc_port_init_t stcPortInit;
+ stc_irq_regi_conf_t stcIrqRegiConf;
+ stc_timer6_deadtime_cfg_t stcDeadTimeCfg;
+
+ MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
+ MEM_ZERO_STRUCT(stcTIM6PWMxCfg);
+ MEM_ZERO_STRUCT(stcGCMPBufCfg);
+ MEM_ZERO_STRUCT(stcPortInit);
+ MEM_ZERO_STRUCT(stcIrqRegiConf);
+ MEM_ZERO_STRUCT(stcDeadTimeCfg);
+
+ /* Initialize Clock */
+// BSP_CLK_Init();
+
+ PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM61, Enable);
+
+ PORT_SetFunc(PortA, Pin08, Func_Tim6, Disable); //Timer61 PWMA
+ PORT_SetFunc(PortB, Pin13, Func_Tim6, Disable); //Timer61 PWMB
+
+ stcTIM6BaseCntCfg.enCntMode = Timer6CntTriangularModeA; //Triangular wave mode
+ stcTIM6BaseCntCfg.enCntDir = Timer6CntDirUp; //Counter counting up
+ stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv1; //Count clock: pclk
+ Timer6_Init(M4_TMR61, &stcTIM6BaseCntCfg); //timer6 PWM frequency, count mode and clk config
+
+ u16Period = 10000u;
+ Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period); //period set
+
+// u16Compare = 3000u;
+// Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, u16Compare); //Set General Compare RegisterA Value
+// Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, u16Compare); //Set General Compare RegisterC Value as buffer register of GCMAR
+
+
+ /*PWMA/PWMB output buf config*/
+ stcGCMPBufCfg.bEnGcmpTransBuf = true;
+ stcGCMPBufCfg.enGcmpBufTransType = Timer6GcmpPrdSingleBuf; //Single buffer transfer
+ Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg); //GCMAR buffer transfer set
+ Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg); //GCMBR buffer transfer set
+
+ stcTIM6PWMxCfg.bOutEn = true; //Output enable
+ stcTIM6PWMxCfg.enPerc = Timer6PWMxCompareKeep; //PWMA port output keep former level when CNTER value match PERAR
+ stcTIM6PWMxCfg.enCmpc = Timer6PWMxCompareInv; //PWMA port output inverse level when CNTER value match with GCMAR
+ stcTIM6PWMxCfg.enStaStp = Timer6PWMxStateSelSS; //PWMA output status is decide by STACA STPCA when CNTER start and stop
+ stcTIM6PWMxCfg.enStaOut = Timer6PWMxPortOutLow; //PWMA port output set low level when CNTER start
+ stcTIM6PWMxCfg.enStpOut = Timer6PWMxPortOutLow; //PWMA port output set low level when CNTER stop
+ stcTIM6PWMxCfg.enDisVal = Timer6PWMxDisValLow;
+ Timer6_PortOutputConfig(M4_TMR61, Timer6PWMA, &stcTIM6PWMxCfg);
+ Timer6_SetFunc(M4_TMR61, Timer6PWMA, Timer6ModeCompareOutput); //Compare output function
+
+ stcTIM6PWMxCfg.bOutEn = true; //Output enable
+ stcTIM6PWMxCfg.enPerc = Timer6PWMxCompareKeep; //PWMB port output keep former level when CNTER value match PERAR
+ stcTIM6PWMxCfg.enCmpc = Timer6PWMxCompareHigh; //PWMB port output inverse level when CNTER value match with GCMBR
+ stcTIM6PWMxCfg.enStaStp = Timer6PWMxStateSelSS; //PWMB output status is decide by STACB STPCB when CNTER start and stop
+ stcTIM6PWMxCfg.enStaOut = Timer6PWMxPortOutLow; //PWMB port output set high level when CNTER start
+ stcTIM6PWMxCfg.enStpOut = Timer6PWMxPortOutLow; //PWMB port output set low level when CNTER stop
+ stcTIM6PWMxCfg.enDisVal = Timer6PWMxDisValLow;
+ Timer6_PortOutputConfig(M4_TMR61, Timer6PWMB, &stcTIM6PWMxCfg);
+ Timer6_SetFunc(M4_TMR61, Timer6PWMB, Timer6ModeCompareOutput); //Compare output function
+
+ Timer6_SetDeadTimeValue(M4_TMR61, Timer6DeadTimUpAR, 10u); // Set dead time value (up count)
+
+ stcDeadTimeCfg.bEnDeadtime = true; //Enable Hardware DeadTime
+ stcDeadTimeCfg.bEnDtBufUp = false; //Disable buffer transfer
+ stcDeadTimeCfg.bEnDtBufDwn = false; //Disable buffer transfer
+ stcDeadTimeCfg.bEnDtEqualUpDwn = true; //Make the down count dead time value equal to the up count dead time setting
+ Timer6_ConfigDeadTime(M4_TMR61, &stcDeadTimeCfg); // Hardware dead time function config
+}
+
+
+void Timer61B_Init(void)
+{
+ uint16_t u16Period;
+// uint16_t u16Compare;
+ stc_timer6_basecnt_cfg_t stcTIM6BaseCntCfg;
+ stc_timer6_port_output_cfg_t stcTIM6PWMxCfg;
+ stc_timer6_gcmp_buf_cfg_t stcGCMPBufCfg;
+ stc_port_init_t stcPortInit;
+ stc_irq_regi_conf_t stcIrqRegiConf;
+ stc_timer6_deadtime_cfg_t stcDeadTimeCfg;
+
+ MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
+ MEM_ZERO_STRUCT(stcTIM6PWMxCfg);
+ MEM_ZERO_STRUCT(stcGCMPBufCfg);
+ MEM_ZERO_STRUCT(stcPortInit);
+ MEM_ZERO_STRUCT(stcIrqRegiConf);
+ MEM_ZERO_STRUCT(stcDeadTimeCfg);
+
+
+ PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM61, Enable);
+
+ PORT_SetFunc(PortA, Pin08, Func_Tim6, Disable); //Timer61 PWMA
+ PORT_SetFunc(PortB, Pin13, Func_Tim6, Disable); //Timer61 PWMB
+
+ stcTIM6BaseCntCfg.enCntMode = Timer6CntTriangularModeA; //Triangular wave mode
+ stcTIM6BaseCntCfg.enCntDir = Timer6CntDirUp; //Counter counting up
+ stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv1; //Count clock: pclk
+ Timer6_Init(M4_TMR61, &stcTIM6BaseCntCfg); //timer6 PWM frequency, count mode and clk config
+
+ u16Period = 10000u;
+ Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period); //period set
+
+// u16Compare = 3000u;
+// Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, u16Compare); //Set General Compare RegisterA Value
+// Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, u16Compare); //Set General Compare RegisterC Value as buffer register of GCMAR
+
+
+ /*PWMA/PWMB output buf config*/
+ stcGCMPBufCfg.bEnGcmpTransBuf = true;
+ stcGCMPBufCfg.enGcmpBufTransType = Timer6GcmpPrdSingleBuf; //Single buffer transfer
+ Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg); //GCMAR buffer transfer set
+ Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg); //GCMBR buffer transfer set
+
+ stcTIM6PWMxCfg.bOutEn = true; //Output enable
+ stcTIM6PWMxCfg.enPerc = Timer6PWMxCompareKeep; //PWMA port output keep former level when CNTER value match PERAR
+ stcTIM6PWMxCfg.enCmpc = Timer6PWMxCompareHigh; //PWMA port output inverse level when CNTER value match with GCMAR
+ stcTIM6PWMxCfg.enStaStp = Timer6PWMxStateSelSS; //PWMA output status is decide by STACA STPCA when CNTER start and stop
+ stcTIM6PWMxCfg.enStaOut = Timer6PWMxPortOutLow; //PWMA port output set low level when CNTER start
+ stcTIM6PWMxCfg.enStpOut = Timer6PWMxPortOutLow; //PWMA port output set low level when CNTER stop
+ stcTIM6PWMxCfg.enDisVal = Timer6PWMxDisValLow;
+ Timer6_PortOutputConfig(M4_TMR61, Timer6PWMA, &stcTIM6PWMxCfg);
+ Timer6_SetFunc(M4_TMR61, Timer6PWMA, Timer6ModeCompareOutput); //Compare output function
+
+ stcTIM6PWMxCfg.bOutEn = true; //Output enable
+ stcTIM6PWMxCfg.enPerc = Timer6PWMxCompareKeep; //PWMB port output keep former level when CNTER value match PERAR
+ stcTIM6PWMxCfg.enCmpc = Timer6PWMxCompareInv; //PWMB port output inverse level when CNTER value match with GCMBR
+ stcTIM6PWMxCfg.enStaStp = Timer6PWMxStateSelSS; //PWMB output status is decide by STACB STPCB when CNTER start and stop
+ stcTIM6PWMxCfg.enStaOut = Timer6PWMxPortOutLow; //PWMB port output set high level when CNTER start
+ stcTIM6PWMxCfg.enStpOut = Timer6PWMxPortOutLow; //PWMB port output set low level when CNTER stop
+ stcTIM6PWMxCfg.enDisVal = Timer6PWMxDisValLow;
+ Timer6_PortOutputConfig(M4_TMR61, Timer6PWMB, &stcTIM6PWMxCfg);
+ Timer6_SetFunc(M4_TMR61, Timer6PWMB, Timer6ModeCompareOutput); //Compare output function
+
+ Timer6_SetDeadTimeValue(M4_TMR61, Timer6DeadTimUpAR, 10u); // Set dead time value (up count)
+
+ stcDeadTimeCfg.bEnDeadtime = true; //Enable Hardware DeadTime
+ stcDeadTimeCfg.bEnDtBufUp = false; //Disable buffer transfer
+ stcDeadTimeCfg.bEnDtBufDwn = false; //Disable buffer transfer
+ stcDeadTimeCfg.bEnDtEqualUpDwn = true; //Make the down count dead time value equal to the up count dead time setting
+ Timer6_ConfigDeadTime(M4_TMR61, &stcDeadTimeCfg); // Hardware dead time function config
+}
+
+
+
+/**
+ * @brief 电机初始化
+ * @param 无
+ * @retval 无
+ */
+void dcmotor_init(void)
+{
+ stc_port_init_t stcPortInit;
+
+
+ stcPortInit.enPinMode = Pin_Mode_Out;
+ stcPortInit.enPinOType = Pin_OType_Cmos;
+ stcPortInit.enPinDrv = Pin_Drv_H;
+ stcPortInit.enPullUp = Disable;
+
+ PORT_Init(SHUTDOWN1_GPIO_Port, SHUTDOWN1_Pin, &stcPortInit);
+ PORT_SetBits(SHUTDOWN1_GPIO_Port, SHUTDOWN1_Pin);
+
+ PORT_Init(PortA, Pin03, &stcPortInit);
+ PORT_SetBits(PortA, Pin03);
+ /* SD拉低,关闭输出 */
+
+ dcmotor_stop(); /* 停止电机 */
+ dcmotor_dir(0); /* 设置正转 */
+ dcmotor_speed(0); /* 速度设置为0 */
+ dcmotor_start(); /* 开启电机 */
+}
+
+/**
+ * @brief 电机开启
+ * @param 无
+ * @retval 无
+ */
+void dcmotor_start(void)
+{
+ ENABLE_MOTOR; /* 拉高SD引脚,开启电机 */
+}
+
+/**
+ * @brief 电机停止
+ * @param 无
+ * @retval 无
+ */
+void dcmotor_stop(void)
+{
+ Timer6_StopCount(M4_TMR61);
+}
+
+/**
+ * @brief 电机旋转方向设置
+ * @param para:方向 0正转,1反转
+ * @note 以电机正面,顺时针方向旋转为正转
+ * @retval 无
+ */
+void dcmotor_dir(uint8_t para)
+{
+ Timer6_StopCount(M4_TMR61);
+ Timer6_DeInit(M4_TMR61);
+
+ if (para == 0) /* 正转 */
+ {
+
+
+ Timer61A_Init();
+
+ }
+ else if (para == 1) /* 反转 */
+ {
+ Timer61B_Init();
+ }
+ dcmotor_start();
+ Timer6_StartCount(M4_TMR61);
+
+}
+
+/**
+ * @brief 电机速度设置
+ * @param para:比较寄存器值
+ * @retval 无
+ */
+void dcmotor_speed(uint16_t para)
+{
+ g_motorSpeed = (para > MAX_SPEED) ? MAX_SPEED : para;
+
+ if (g_motorSpeed == 0) {
+ g_motorDirection = DIR_STOPPED;
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, g_motorSpeed);
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, g_motorSpeed);
+ dcmotor_stop();
+ return;
+ }
+
+ if(Motor_GetDirection() == DIR_REVERSE) //反转
+ {
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, g_motorSpeed); //Set General Compare RegisterA Value
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, g_motorSpeed); //Set General Compare RegisterC Value as buffer register of GCMAR
+ DBG_LOG("REVERSE\tnewSpeed = %d\r\n", g_motorSpeed);
+ }
+ else if(Motor_GetDirection() == DIR_FORWARD) //正转
+ {
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, 10000-g_motorSpeed); //Set General Compare RegisterA Value
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, 10000-g_motorSpeed); //Set General Compare RegisterC Value as buffer register of GCMAR
+ DBG_LOG("FORWARD\tnewSpeed = %d\r\n", g_motorSpeed);
+ }
+}
+
+/**
+ * @brief 电机控制
+ * @param para: pwm比较值 ,正数电机为正转,负数为反转
+ * @note 根据传入的参数控制电机的转向和速度
+ * @retval 无
+ */
+void motor_pwm_set(float para)
+{
+ int val = (int)para;
+
+ if(val == 0)
+ {
+ dcmotor_stop();
+ return;
+ }
+
+ if (val > 0)
+ {
+ g_motorDirection = DIR_FORWARD;
+ dcmotor_dir(0); /* 正转 */
+ dcmotor_speed(10000-val);
+ }
+ else
+ {
+ g_motorDirection = DIR_REVERSE;
+ dcmotor_dir(1); /* 反转 */
+ dcmotor_speed(-val);
+ }
+ DCMOTOR_DBG_LOG("dcmotor_speed:%d\r\n", val);
+}
+
+
+
+
+// 设置电机方向
+void Motor_SetDirection(uint8_t dir) {
+ // 更新方向标志位
+ if (dir == 0) {
+ g_motorDirection = DIR_FORWARD;
+// Up();
+ dcmotor_dir(0);
+ } else {
+ g_motorDirection = DIR_REVERSE;
+// Down();
+ dcmotor_dir(1);
+ }
+
+}
+
+
+// 电机控制接口
+void Motor_Control(MotorCommand cmd) {
+ g_motorCmd = cmd;
+}
+
+// 获取电机当前方向
+MotorDirection Motor_GetDirection(void) {
+ return g_motorDirection;
+}
+
+
+// 设置电机速度
+void Motor_SetSpeed(uint16_t speed) {
+ g_motorSpeed = (speed > MAX_SPEED) ? MAX_SPEED : speed;
+
+ // 当速度为零时,更新方向状态为停止
+ if (g_motorSpeed == 0) {
+ g_motorDirection = DIR_STOPPED;
+ }
+
+ if(Motor_GetDirection() == DIR_REVERSE) //反转
+ {
+// Adt_SetCompareValue(M0P_ADTIM4, AdtCompareC, PWM_PERIOD - g_motorSpeed);
+// DBG_LOG("REVERSE\tnewSpeed = %d\r\n", g_motorSpeed);
+ }
+ else if(Motor_GetDirection() == DIR_FORWARD) //正转
+ {
+// Adt_SetCompareValue(M0P_ADTIM5, AdtCompareC, g_motorSpeed);
+// DBG_LOG("FORWARD\tnewSpeed = %d\r\n", g_motorSpeed);
+ }
+ else
+ {
+// StopMotor();
+ }
+
+
+}
+
+
+
+
+
+bool Dcmotor1msStatus = false;
+void Dcmotor1msRoutine(void)
+{
+ Dcmotor1msStatus = true;
+
+}
+
+
+
+
+uint8_t KeyASta;
+uint8_t KeyBSta;
+uint8_t RunSta;
+void DcmotorLoopHandler(void)
+{
+
+#if(1)
+
+
+ if((RunSta == false) && (KeyASta == true) && (KeyBSta == false))
+ {
+ Motor_Control(MOTOR_CMD_REVERSE);
+ }
+ else if((RunSta == false) && (KeyASta == false) && (KeyBSta == true))
+ {
+ Motor_Control(MOTOR_CMD_FORWARD);
+ }
+ else if((RunSta == true) && (KeyASta == false) && (KeyBSta == false))
+ {
+ Motor_Control(MOTOR_CMD_STOP);
+ RunSta = false;
+ }
+
+ switch (g_motorCmd)
+ {
+ case MOTOR_CMD_REVERSE:
+ if(RunSta == false)
+ {
+ RunSta = true;
+ Timer61B_Init();
+ g_motorSpeed = 8000;
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, g_motorSpeed);
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, g_motorSpeed);
+ Timer6_StartCount(M4_TMR61);
+ }
+
+ break;
+ case MOTOR_CMD_FORWARD:
+ if(RunSta == false)
+ {
+ RunSta = true;
+ Timer61A_Init();
+ g_motorSpeed = 8000;
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, g_motorSpeed);
+ Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, g_motorSpeed);
+ Timer6_StartCount(M4_TMR61);
+ }
+
+ break;
+ default:
+ Timer6_StopCount(M4_TMR61);
+ RunSta = false;
+ break;
+ }
+
+#endif
+
+
+#if(0)
+
+
+ if((RunSta == false) && (KeyASta == true) && (KeyBSta == false))
+ {
+ Motor_Control(MOTOR_CMD_REVERSE);
+ RunSta = true;
+ }
+ else if((RunSta == false) && (KeyASta == false) && (KeyBSta == true))
+ {
+ Motor_Control(MOTOR_CMD_FORWARD);
+ RunSta = true;
+ }
+ else if((RunSta == true) && (KeyASta == false) && (KeyBSta == false))
+ {
+ Motor_Control(MOTOR_CMD_STOP);
+ RunSta = false;
+ }
+
+ if(Dcmotor1msStatus == true)
+ {
+ Dcmotor1msStatus = false;
+
+ // 电机状态机处理
+ switch (g_motorState) {
+ case MOTOR_STOPPED:
+// Motor_SetSpeed(0);
+// motor_pwm_set(0);
+ dcmotor_speed(0);
+
+ // 检测新命令
+ if (g_motorCmd == MOTOR_CMD_FORWARD) {
+ Motor_SetDirection(0); // 设置正转方向
+ g_motorState = MOTOR_ACCELERATING;
+ accelCounter = 0;
+// Motor_SetSpeed(ACCEL_STEP); // 初始速度
+// motor_pwm_set(ACCEL_STEP);
+ dcmotor_speed(ACCEL_STEP);
+ }
+ else if (g_motorCmd == MOTOR_CMD_REVERSE) {
+ Motor_SetDirection(1); // 设置反转方向
+ g_motorState = MOTOR_ACCELERATING;
+ accelCounter = 0;
+// Motor_SetSpeed(ACCEL_STEP); // 初始速度
+// motor_pwm_set(ACCEL_STEP);
+ dcmotor_speed(ACCEL_STEP);
+ }
+ break;
+
+ case MOTOR_ACCELERATING:
+ // 加速过程
+ if (++accelCounter >= ACCEL_INTERVAL) {
+ accelCounter = 0;
+ uint16_t newSpeed = g_motorSpeed + ACCEL_STEP;
+
+ if (newSpeed >= MAX_SPEED) {
+ newSpeed = MAX_SPEED;
+ g_motorState = MOTOR_RUNNING; // 达到最大速度,进入匀速
+ }
+// Motor_SetSpeed(newSpeed);
+// motor_pwm_set(newSpeed);
+ dcmotor_speed(newSpeed);
+ }
+
+ // 检查停止命令
+ if (g_motorCmd == MOTOR_CMD_STOP) {
+ g_motorState = MOTOR_DECELERATING;
+ }
+ break;
+
+ case MOTOR_RUNNING:
+ // 检查停止命令
+ if (g_motorCmd == MOTOR_CMD_STOP) {
+ g_motorState = MOTOR_DECELERATING;
+ }
+ // 检查方向改变命令
+ else if ((g_motorCmd == MOTOR_CMD_FORWARD && g_motorDirection != DIR_FORWARD) ||
+ (g_motorCmd == MOTOR_CMD_REVERSE && g_motorDirection != DIR_REVERSE)) {
+ g_motorState = MOTOR_DECELERATING; // 需要先减速停止
+ }
+ break;
+
+ case MOTOR_DECELERATING:
+ // 减速过程
+ if (++accelCounter >= ACCEL_INTERVAL) {
+ accelCounter = 0;
+// if (g_motorSpeed > DECEL_STEP) {
+ if (g_motorSpeed > DECEL_STEP) {
+// Motor_SetSpeed(g_motorSpeed - DECEL_STEP);
+// motor_pwm_set(g_motorSpeed - DECEL_STEP);
+ dcmotor_speed(g_motorSpeed - DECEL_STEP);
+ } else {
+// Motor_SetSpeed(0);
+// motor_pwm_set(0);
+ dcmotor_speed(0);
+ g_motorState = MOTOR_STOPPED; // 减速完成,进入停止状态
+ }
+ }
+ break;
+ }
+ }
+
+
+#endif
+}
diff --git a/Project/HC32F460/source/Module/dc_motor/dc_motor.h b/Project/HC32F460/source/Module/dc_motor/dc_motor.h
new file mode 100644
index 0000000..f868e8d
--- /dev/null
+++ b/Project/HC32F460/source/Module/dc_motor/dc_motor.h
@@ -0,0 +1,92 @@
+
+#ifndef __DCMOTOR_H
+#define __DCMOTOR_H
+
+#include "hc32_ddl.h"
+
+
+// 电机控制参数
+#define PWM_PERIOD TIM_PERIOD // PWM周期值 (ARR)
+#define MAX_SPEED 9900 // 最大速度(PWM占空比)
+#define ACCEL_STEP 100 // 加速步进值
+#define DECEL_STEP 100 // 减速步进值
+#define ACCEL_INTERVAL 5 // 加减速间隔(ms)
+
+
+
+// 电机控制命令
+typedef enum {
+ MOTOR_CMD_STOP,
+ MOTOR_CMD_FORWARD,
+ MOTOR_CMD_REVERSE
+} MotorCommand;
+
+// 电机运行状态机
+typedef enum {
+ MOTOR_STOPPED,
+ MOTOR_ACCELERATING,
+ MOTOR_RUNNING,
+ MOTOR_DECELERATING
+} MotorState;
+
+
+// 电机转动方向
+typedef enum {
+ DIR_STOPPED,
+ DIR_FORWARD,
+ DIR_REVERSE
+} MotorDirection;
+
+
+
+/* 停止引脚操作宏定义
+ * 此引脚控制H桥是否生效以达到开启和关闭电机的效果
+ */
+#define SHUTDOWN1_Pin Pin12
+#define SHUTDOWN1_GPIO_Port PortB
+
+//#define SHUTDOWN2_Pin GPIO_PIN_2
+//#define SHUTDOWN2_GPIO_Port GPIOF
+#define SHUTDOWN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0) /* PF口时钟使能 */
+
+/* 电机停止引脚定义 这里默认是接口1 */
+#define ENABLE_MOTOR PORT_SetBits(SHUTDOWN1_GPIO_Port,SHUTDOWN1_Pin)
+#define DISABLE_MOTOR PORT_ResetBits(SHUTDOWN1_GPIO_Port,SHUTDOWN1_Pin)
+
+/******************************************************************************************/
+
+void dcmotor_init(void); /* 直流有刷电机初始化 */
+void dcmotor_start(void); /* 开启电机 */
+void dcmotor_stop(void); /* 关闭电机 */
+void dcmotor_dir(uint8_t para); /* 设置电机方向 */
+void dcmotor_speed(uint16_t para); /* 设置电机速度 */
+void motor_pwm_set(float para); /* 电机控制 */
+
+
+
+
+MotorDirection Motor_GetDirection(void);/* 获取电机转动方向 */
+void Motor_Control(MotorCommand cmd); /* 电机控制 */
+void Dcmotor1msRoutine(void);
+void DcmotorLoopHandler(void);
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Project/HC32F460/source/User/Inc/ddl_config.h b/Project/HC32F460/source/User/Inc/ddl_config.h
index d727bbd..16efb04 100644
--- a/Project/HC32F460/source/User/Inc/ddl_config.h
+++ b/Project/HC32F460/source/User/Inc/ddl_config.h
@@ -88,8 +88,8 @@ extern "C"
#define DDL_QSPI_ENABLE (DDL_OFF)
#define DDL_RMU_ENABLE (DDL_OFF)
#define DDL_RTC_ENABLE (DDL_ON)
-#define DDL_SDIOC_ENABLE (DDL_ON)
-#define DDL_SPI_ENABLE (DDL_ON)
+#define DDL_SDIOC_ENABLE (DDL_OFF)
+#define DDL_SPI_ENABLE (DDL_OFF)
#define DDL_SRAM_ENABLE (DDL_ON)
#define DDL_SWDT_ENABLE (DDL_ON)
#define DDL_TIMER0_ENABLE (DDL_OFF)
@@ -98,7 +98,7 @@ extern "C"
#define DDL_TIMER4_OCO_ENABLE (DDL_OFF)
#define DDL_TIMER4_PWM_ENABLE (DDL_OFF)
#define DDL_TIMER4_SEVT_ENABLE (DDL_OFF)
-#define DDL_TIMER6_ENABLE (DDL_OFF)
+#define DDL_TIMER6_ENABLE (DDL_ON)
#define DDL_TIMERA_ENABLE (DDL_OFF)
#define DDL_TRNG_ENABLE (DDL_OFF)
#define DDL_USART_ENABLE (DDL_ON)
diff --git a/Project/HC32F460/source/User/Src/main.c b/Project/HC32F460/source/User/Src/main.c
index ff458b7..029679b 100644
--- a/Project/HC32F460/source/User/Src/main.c
+++ b/Project/HC32F460/source/User/Src/main.c
@@ -5,6 +5,7 @@
#include "Encryption.h"
#include "Debug.h"
#include "Algorithm.h"
+#include "dc_motor.h"
#include "CS1237_LEFTUP.h"
#include "CS1237_LEFTLOW.h"
#include "CS1237_RIGHTUP.h"
@@ -132,8 +133,8 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
{
uint32_t LeftSlopeSum = abs(App.LeftUpCS1237_SlopeArray[0]) + abs(App.LeftLowCS1237_SlopeArray[0]);
uint32_t RightSlopeSum = abs(App.RightUpCS1237_SlopeArray[0]) + abs(App.RightLowCS1237_SlopeArray[0]);
- uint32_t LeftDiffSum = abs(lu_ad[0]) + abs(ll_ad[0]);
- uint32_t RightDiffSum = abs(ru_ad[0]) + abs(rl_ad[0]);
+ uint32_t LeftDiffSum = abs(lu_diff[0]) + abs(ll_diff[0]);
+ uint32_t RightDiffSum = abs(ru_diff[0]) + abs(rl_diff[0]);
App.LeftRunFalg = false;
App.RightRunFalg = false;
@@ -154,6 +155,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& (Oll_diff3 <= -App.ADTrack.LeftLowVPT)))
{
//BDC_UP();
+ Motor_Control(MOTOR_CMD_FORWARD);
App.UpFlag = true;
App.StopFlag = false;
App.DownFlag = false;
@@ -172,6 +174,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& (Oll_diff1 >= App.ADTrack.LeftLowVPT)))
{
//BDC_DOWN();
+ Motor_Control(MOTOR_CMD_REVERSE);
App.DownFlag = true;
App.StopFlag = false;
App.UpFlag = false;
@@ -194,6 +197,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& (Orl_diff3 <= -App.ADTrack.RightLowVPT)))
{
//BDC_UP();
+ Motor_Control(MOTOR_CMD_FORWARD);
App.UpFlag = true;
App.StopFlag = false;
App.DownFlag = false;
@@ -212,6 +216,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& (Orl_diff3 >= App.ADTrack.RightLowVPT)))
{
//BDC_DOWN();
+ Motor_Control(MOTOR_CMD_REVERSE);
App.DownFlag = true;
App.StopFlag = false;
App.UpFlag = false;
@@ -227,6 +232,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& ll_slope > App.ADTrack.Slope_VPT)
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -236,6 +242,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& Oll_diff1 < (App.ADTrack.LeftLowVPT / 2))
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -248,6 +255,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& rl_slope > App.ADTrack.Slope_VPT)
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -257,6 +265,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& Orl_diff1 < (App.ADTrack.RightLowVPT / 2))
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -272,6 +281,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& ll_slope < -App.ADTrack.Slope_VPT)
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -281,6 +291,7 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& Oll_diff1 > -(App.ADTrack.LeftLowVPT / 2))
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -293,15 +304,17 @@ void SupportControlHandle(int32_t *lu_ad, int32_t *ll_ad, int32_t *ru_ad, int32_
&& rl_slope < -App.ADTrack.Slope_VPT)
{
//BDC_STOP();
- App.StopFlag = true;
- App.DownFlag = false;
- App.UpFlag = false;
- App.StopCollDelay1mSCnt = 1000;
+ Motor_Control(MOTOR_CMD_STOP);
+ App.StopFlag = true;
+ App.DownFlag = false;
+ App.UpFlag = false;
+ App.StopCollDelay1mSCnt = 1000;
}
else if(Oru_diff1 < (App.ADTrack.RightUpVPT / 2)
&& Orl_diff1 > -(App.ADTrack.RightLowVPT / 2))
{
//BDC_STOP();
+ Motor_Control(MOTOR_CMD_STOP);
App.StopFlag = true;
App.DownFlag = false;
App.UpFlag = false;
@@ -574,6 +587,7 @@ int main(void)
RIGHTUP_CS1237DataLoopCollect();
RIGHTLOW_CS1237DataLoopCollect();
ReadLoopHandler();
+ DcmotorLoopHandler();
AppLoopHandler();
}
}
@@ -593,6 +607,7 @@ void SysTick_IrqHandler(void)
LEFTLOW_CS12371mSRoutine();
RIGHTUP_CS12371mSRoutine();
RIGHTLOW_CS12371mSRoutine();
+ Dcmotor1msRoutine();
}
/*****************************************************************************************
diff --git a/driver/inc/hc32f460_timer6.h b/driver/inc/hc32f460_timer6.h
index f731e09..d25bcce 100644
--- a/driver/inc/hc32f460_timer6.h
+++ b/driver/inc/hc32f460_timer6.h
@@ -640,6 +640,9 @@ en_result_t Timer6_SetSpecialBuf(M4_TMR6_TypeDef *TMR6x,en_timer6_special_compar
/* Timer6 unit Set valid period Value*/
en_result_t Timer6_SetValidPeriod(M4_TMR6_TypeDef *TMR6x, const stc_timer6_validper_cfg_t* pstcTimer6ValidPerCfg);
+/* Config channel mode, capture or output */
+void Timer6_SetFunc(M4_TMR6_TypeDef *TMR6x, en_timer6_chx_port_t enTimer6PWMPort, en_timer6_func_mode_t enMode);
+
/* Config Input prot and filter function */
en_result_t Timer6_PortInputConfig(M4_TMR6_TypeDef *TMR6x, const stc_timer6_port_input_cfg_t* pstcTimer6PortInputCfg);
/* Config output prot function */
diff --git a/driver/src/hc32f460_timer6.c b/driver/src/hc32f460_timer6.c
index 461c25b..9c49684 100644
--- a/driver/src/hc32f460_timer6.c
+++ b/driver/src/hc32f460_timer6.c
@@ -92,6 +92,11 @@
( (Timer6PWMA == (x)) || \
(Timer6PWMB == (x)))
+/*!< Parameter valid check for timer6 port mode */
+#define IS_VALID_TIMER6_PORT_MODE(x) \
+( (Timer6ModeCompareOutput == (x)) || \
+ (Timer6ModeCaptureInput == (x)))
+
/*!< Parameter valid check for timer6 input port */
#define IS_VALID_TIMER6_INPUT_PORT(x) \
( (Timer6PWMA == (x)) || \
@@ -948,6 +953,34 @@ en_result_t Timer6_PortInputConfig(M4_TMR6_TypeDef *TMR6x, const stc_timer6_port
return enRet;
}
+/*******************************************************************************
+ * \brief Set channel function
+ * \param [in] TMR6x Timer6 unit
+ * \param [in] enTimer6PWMPort Port to be configured @ref en_timer6_chx_port_t
+ * \param [in] enMode Channel mode @ref en_timer6_func_mode_t
+ * \retval None
+ ******************************************************************************/
+void Timer6_SetFunc(M4_TMR6_TypeDef *TMR6x, en_timer6_chx_port_t enTimer6PWMPort, en_timer6_func_mode_t enMode)
+{
+ DDL_ASSERT(IS_VALID_NORMAL_TIMER6_UNIT(TMR6x));
+ DDL_ASSERT(IS_VALID_TIMER6_OUTPUT_PORT(enTimer6PWMPort));
+ DDL_ASSERT(IS_VALID_TIMER6_PORT_MODE(enMode));
+
+ switch (enTimer6PWMPort)
+ {
+ case Timer6xCHA:
+ TMR6x->PCONR_f.CAPMDA = enMode;
+ break;
+
+ case Timer6xCHB:
+ TMR6x->PCONR_f.CAPMDB = enMode;
+ break;
+
+ default:
+ break;
+ }
+}
+
/*******************************************************************************
* \brief Timer6 Output Port config
*