Sfoglia il codice sorgente

1. 使用TIM6定时10ms运行FOC的normal task
2. 完善FOC的状态机

Signed-off-by: huhui <huhui@sharkgulf.com>

huhui 5 anni fa
parent
commit
21813fed9a

+ 17 - 0
Application/App/app.c

@@ -0,0 +1,17 @@
+#include "app/app.h"
+#include "foc/foc.h"
+
+void app_init(void){
+
+}
+
+void start_stop_handler(void) {
+	FOCState s = FOC_STM_State();
+	if (s == IDLE) {
+		Foc_Set_StartRamp(8.0f, 1000);
+		foc_start_motor();
+	}else {
+		foc_stop_motor();
+	}
+}
+

+ 5 - 0
Application/App/app.h

@@ -0,0 +1,5 @@
+#ifndef _APP_H__
+#define _APP_H__
+void app_init(void);
+#endif /* _APP_H__ */
+

+ 1 - 0
Application/App/communication.c

@@ -0,0 +1 @@
+

+ 5 - 0
Application/App/communication.h

@@ -0,0 +1,5 @@
+#ifndef _COMMUNICATION_H__
+#define _COMMUNICATION_H__
+
+#endif /* _COMMUNICATION_H__ */
+

+ 2 - 1
Application/App/main.c

@@ -1,9 +1,10 @@
 #include "bsp/bsp.h"
 #include "libs/task.h"
 #include "foc/foc.h"
-
+#include "app/app.h"
 int main(void){
 	system_init();
 	foc_init();
+	app_init();
 	task_run();
 }

+ 22 - 0
Application/App/protocol.h

@@ -0,0 +1,22 @@
+#ifndef _PROTOCOL_H__
+#define _PROTOCOL_H__
+#include "libs/types.h"
+
+
+#define Command_Start 0x01
+#define Command_Stop  0x02
+#define Command_Hall_Detect 0x03
+
+#pragma  pack (push,1)
+typedef struct {
+	u8 indentify; //if can, this is can addr
+}Frame_Head_t;
+typedef struct {
+	Frame_Head_t head;
+	u8 command;
+	u8 payload[0];
+}Frame_t;
+#pragma pack(pop)
+
+#endif /*_PROTOCOL_H__ */
+

+ 1 - 0
Application/Bsp/bsp.c

@@ -10,6 +10,7 @@ void system_init(void){
 	HAL_ADC1_Init();
 	HAL_EXIT_Enable();
 	serial_init();
+	TIM4_Init();
 }
 
 void system_reboot(void){

+ 1 - 0
Application/Bsp/bsp.h

@@ -4,6 +4,7 @@
 #include "hal/hal.h"
 #include "hal/pwm.h"
 #include "hal/adc.h"
+#include "hal/tim4.h"
 #include "bsp/serial.h"
 
 void system_init(void);

+ 21 - 3
Application/Bsp/foc_irqs.c

@@ -9,6 +9,8 @@ __weak void system_tick_handler(void){}
 __weak void current_sample_handler(void){}
 __weak void hall_sensor_handler(void){}
 __weak void uart2_irq_handler(void) {}
+__weak void foc_slow_task_handler(void){}
+__weak void start_stop_handler(void) {}
 
 void TIM1_BRK_TIM15_IRQHandler(void){
 	if (LL_TIM_IsActiveFlag_BRK2(TIM1))
@@ -20,8 +22,11 @@ void TIM1_BRK_TIM15_IRQHandler(void){
 }
 
 void TIM1_UP_TIM16_IRQHandler(void){
-	LL_TIM_ClearFlag_UPDATE(TIM1);
-	foc_pwm_up_handler();
+	if (LL_TIM_IsActiveFlag_UPDATE(TIM1))
+	{
+		LL_TIM_ClearFlag_UPDATE(TIM1);
+		foc_pwm_up_handler();
+	}
 }
 
 
@@ -30,6 +35,14 @@ void ADC1_IRQHandler(void) {
 	current_sample_handler();
 }
 
+void TIM6_DAC_IRQHandler(void) {
+	if (LL_TIM_IsActiveFlag_UPDATE(TIM6))
+	{
+		LL_TIM_ClearFlag_UPDATE(TIM6);
+		foc_slow_task_handler();
+	}
+}
+
 void SysTick_Handler(void)
 {
 	system_tick_handler();
@@ -49,11 +62,16 @@ void EXTI15_10_IRQHandler(void) {
     	LL_EXTI_ClearFlag_0_31 (LL_EXTI_LINE_10);
     	hall_sensor_handler();
   	}
+  	if ( LL_EXTI_ReadFlag_0_31(LL_EXTI_LINE_13) )
+  	{
+    	LL_EXTI_ClearFlag_0_31 (LL_EXTI_LINE_13);
+    	start_stop_handler();
+  	}
    	if ( LL_EXTI_ReadFlag_0_31(LL_EXTI_LINE_15) )
   	{
     	LL_EXTI_ClearFlag_0_31 (LL_EXTI_LINE_15);
     	hall_sensor_handler();
-  	} 
+  	}
 }
 
 void USART2_IRQHandler(void) {

+ 90 - 120
Application/FOC/foc.c

@@ -10,11 +10,10 @@
 #include "foc/vbus_sensor.h"
 #include "foc/ntc_sensor.h"
 
-static u32 foc_stm_task_handler(void);
-static u32 foc_measure_task_handler(void);
+static u32 foc_measure_task(void);
 static void foc_defulat_value(void);
 
-static motor_foc_t m_foc;
+static motor_foc_t mFOC;
 
 void foc_init(void) {
 	foc_defulat_value();
@@ -22,154 +21,125 @@ void foc_init(void) {
 	HAL_ADC1_Enable();
 	/* init pwm hardware timer */
 	PWM_TimerEnable();
-
-	task_start(foc_measure_task_handler, 0);
-	task_start(foc_stm_task_handler, 0);
-	printf("test\n");
-	foc_ramp_speed(400.0f, 10.0f);
+	/* enable tim4 to run the foc normal task */
+	TIM4_Enable();
 	
-	//foc_hall_detect(3.0f, m_foc.hall_table);
+	task_start(foc_measure_task, 0);
 }
 
 static void foc_defulat_value(void){
-	memset(&m_foc, 0, sizeof(m_foc));
-	m_foc.state = IDLE;
-	m_foc.gate_output = false;
-	m_foc.vbus = 12.0f;
-	phase_current_init(&m_foc.current_samp);
-}
-
-void foc_ramp_speed(float rpm, u32 duration_ms) {
-	float current = 8.0f;
-	m_foc.dq_ref.q = 0;
-	m_foc.dq_ref.d = 0;
-	//m_foc.override_p.is_override_theta = true;
-	foc_pwm_start(true);
-	for (int i = 0;i < 100;i++) {
-		m_foc.dq_ref.d = (float)i * current / 1000.0f;
-		task_udelay(10);
-	}
-	m_foc.dq_ref.d = 0.0f;
-	m_foc.dq_ref.q = 4.0f;
-	
-	while(1) {
-		for (int i = 0; i < 360; i++) {
-			m_foc.override_p.theta = i;
-			task_udelay(100);
-			int theta = hall_sensor_get_theta();
-			if (i % 10 == 0) {
-				printf("$%d;", theta);
-			}
-		}
-	}
+	memset(&mFOC, 0, sizeof(mFOC));
+	mFOC.state = IDLE;
+	mFOC.mosGate = false;
+	mFOC.vbus = 12.0f;
+	phase_current_init(&mFOC.current_samp);
 }
 
-int foc_hall_detect(float current, u16 *hall_table){
-	foc_pwm_start(true);
-	m_foc.override_p.is_override_theta = true;
-	m_foc.override_p.theta = 0.0f;
-	m_foc.override_p.is_override_v_dq = true;
-	m_foc.override_p.v_dq.d = .0f;
-	m_foc.override_p.v_dq.q = .0f;
-	
-	for (int i = 0;i < 1000;i++) {
-		m_foc.override_p.v_dq.d = (float)i * current / 1000.0f;
-		task_udelay(1000);
+
+void foc_clear(void) {
+	PWM_Stop();
+	mFOC.mosGate = false;
+	foc_defulat_value();
+}
+
+FOCState FOC_STM_State(void){
+	return mFOC.state;
+}
+
+FError FOC_STM_NextState(FOCState state) {
+	bool changed = false;
+	if (state == mFOC.state) {
+		return NoError;
 	}
-	float sin_hall[8];
-	float cos_hall[8];
-	int hall_iterations[8];
-	memset(sin_hall, 0, sizeof(sin_hall));
-	memset(cos_hall, 0, sizeof(cos_hall));
-	memset(hall_iterations, 0, sizeof(hall_iterations));
-
-	// Forwards
-	for (int i = 0;i < 3;i++) {
-		for (int j = 0;j < 360;j++) {
-			m_foc.override_p.theta = j;
-			task_udelay(10 * 1000);
-
-			int hall = get_hall_stat(7);
-			float s, c;
-			normal_sincosf(degree_2_pi(j), &s, &c);
-			sin_hall[hall] += s;
-			cos_hall[hall] += c;
-			hall_iterations[hall]++;
+	if (state == START) {
+		if (mFOC.state == IDLE) {
+			changed = true;
 		}
-	}
-
-	// Reverse
-	for (int i = 0;i < 3;i++) {
-		for (int j = 360;j >= 0;j--) {
-			m_foc.override_p.theta = j;
-			task_udelay(10 * 1000);
-
-			int hall = get_hall_stat(7);
-			float s, c;
-			normal_sincosf(degree_2_pi(j), &s, &c);
-			sin_hall[hall] += s;
-			cos_hall[hall] += c;
-			hall_iterations[hall]++;
+	}else if (state == IDLE) {
+		if (mFOC.state == ANY_STOP) {
+			changed = true;
 		}
-	}
-	foc_pwm_start(false);
-	m_foc.override_p.is_override_theta = false;
-	m_foc.override_p.is_override_v_dq = false;
-	int fails = 0;
-	for(int i = 0;i < 8;i++) {
-		if (hall_iterations[i] > 30) {
-			float ang = pi_2_degree(atan2f(sin_hall[i], cos_hall[i]));
-			fast_norm_angle(&ang);
-			hall_table[i] = (u16)ang;
-		} else {
-			hall_table[i] = 0xFFFF;
-			fails++;
+	}else if (state == ANY_STOP) {
+		if (mFOC.state != IDLE) {
+			changed = true;
+		}
+	}else if (state == CURRENT_CALIBRATE) {
+		if (mFOC.state == START) {
+			changed = true;
+		}
+	}else if (state == READY_TO_RUN) {
+		if (mFOC.state == CURRENT_CALIBRATE) {
+			changed = true;
+		}
+	}else if (state == RAMPINT_START) {
+		if (mFOC.state == READY_TO_RUN) {
+			changed = true;
 		}
+	}else if (state == RUNNING) {
+		if (mFOC.state == RAMPINT_START) {
+			changed = true;
+		}
+	}
+	if (changed) {
+		mFOC.state = state;
+		return NoError;
 	}
-	return fails == 2;	
+	return STMNotAllow;
 }
 
-void foc_clear(void) {
-	foc_defulat_value();
-	PWM_Stop();
-	m_foc.gate_output = false;
+/* ÉèÖÃÆô¶¯rampµçÁ÷ºÍʱ¼ä */
+void Foc_Set_StartRamp(float final, u32 duration_ms){
+	ramp_ctrl_init(&mFOC.start_ramp, 0.0f, final, duration_ms);
+}
+
+FError foc_start_motor(void){
+	return FOC_STM_NextState(START);
+}
+
+FError foc_stop_motor(void) {
+	return FOC_STM_NextState(ANY_STOP);
+}
+
+void foc_overide_theta(bool enable){
+	mFOC.override.is_theta = enable;
+}
+void foc_overide_vdq(bool enable){
+	mFOC.override.is_vdq = enable;
+}
+void foc_overide_set_theta(float theta){
+	mFOC.override.theta = theta;
 }
+void foc_overide_set_vdq(float d, float q){
+	mFOC.override.vdq.d = d;
+	mFOC.override.vdq.q = q;
+}
+
 
-static u32 foc_measure_task_handler(void){
+static u32 foc_measure_task(void){
 	vbus_sample_voltage();
 	ntc_sensor_sample();
 	return 1;
 }
 
-static u32 foc_stm_task_handler(void) {
-	switch (m_foc.state) {
-		case START:
-			break;
-		case CHARGER_BOOT_CAP:
-			break;
-		case READY_TO_RUN:
-			break;
-		default:
-			break;
-	}
-	return 10;
-}
-
 void foc_brake_handler(void) {
 
 }
 
 void foc_pwm_up_handler(void){
-	phase_current_adc_triger(&m_foc.current_samp);
+	phase_current_adc_triger(&mFOC.current_samp);
 }
 
 
 void current_sample_handler(void) {
-	foc_task(&m_foc);
+	FOC_Fast_Task(&mFOC);
+}
+
+void foc_slow_task_handler(void) {
+	FOC_Normal_Task(&mFOC);
 }
 
 void foc_pwm_start(bool start) {
-	if (start == m_foc.gate_output) {
+	if (start == mFOC.mosGate) {
 		return;
 	}
 	if (start) {
@@ -177,6 +147,6 @@ void foc_pwm_start(bool start) {
 	}else {
 		PWM_Stop();
 	}
-	m_foc.gate_output = start;	
+	mFOC.mosGate = start;	
 }
 

+ 10 - 1
Application/FOC/foc.h

@@ -4,10 +4,19 @@
 
 
 void foc_init(void);
+void foc_clear(void);
 void set_dq_voltage(float d_v, float q_v);
 void foc_pwm_start(bool start);
+FError foc_start_motor(void);
+FError foc_stop_motor(void);
 int foc_hall_detect(float current, u16 *hall_table);
-void foc_ramp_speed(float rpm, u32 duration_ms);
+void foc_overide_theta(bool enable);
+void foc_overide_vdq(bool enable);
+void foc_overide_set_theta(float theta);
+void foc_overide_set_vdq(float d, float q);
+FError FOC_STM_NextState(FOCState s);
+void Foc_Set_StartRamp(float final, u32 duration_ms);
+FOCState FOC_STM_State(void);
 
 #endif /* _FOC_H__ */
 

+ 54 - 9
Application/FOC/foc_task.c

@@ -1,6 +1,8 @@
 #include "hal/hal.h"
 #include "hal/pwm.h"
+#include "libs/task.h"
 #include "foc_task.h"
+#include "foc.h"
 #include "phase_current.h"
 #include "park_clark.h"
 #include "hall_sensor.h"
@@ -8,15 +10,16 @@
 
 static void __inline foc_update_theta(motor_foc_t *foc) {
 	float angle = 0.0f;
-	if (foc->override_p.is_override_theta) {
-		angle = foc->override_p.theta;
+	if (foc->override.is_theta) {
+		angle = foc->override.theta;
 	}else {
 		angle = hall_sensor_get_theta();
 	}
 	foc->motor_s.theta = degree_2_pi(angle);
 }
 
-static void __inline foc_update_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref_out) {
+/* 输出dq电压给反park,最后给svpwm */
+static void __inline Foc_Dq_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref_out) {
 	if (foc->mode == FOC_MODE_PI_DQ || foc->mode == FOC_MODE_PI_FULL) {
 		ref_out->d = pi_control(&foc->PI_id, foc->dq_ref.d - sampled->d);
 		ref_out->q = pi_control(&foc->PI_iq, foc->dq_ref.q - sampled->q);
@@ -24,14 +27,14 @@ static void __inline foc_update_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t
 		ref_out->d = foc->dq_ref.d;
 		ref_out->q = foc->dq_ref.q;
 	}
-	if (foc->override_p.is_override_v_dq) {
-		ref_out->d = foc->override_p.v_dq.d;
-		ref_out->q = foc->override_p.v_dq.q;
+	if (foc->override.is_vdq) {
+		ref_out->d = foc->override.vdq.d;
+		ref_out->q = foc->override.vdq.q;
 	}
 }
 
-
-void foc_task(motor_foc_t *foc){
+/* FOC 主控制逻辑 */
+void FOC_Fast_Task(motor_foc_t *foc){
 	current_samp_t *c_sample = &foc->current_samp;
 	alpha_beta_t sample_ab, pwm_ab;
 	dq_t         sample_dq, v_dq;
@@ -47,7 +50,7 @@ void foc_task(motor_foc_t *foc){
 	/* alpha-beta坐标转旋转坐标系D-Q */
 	Park(&sample_ab, foc->motor_s.theta, &sample_dq);
 	/* 处理D,Q电流环,速度环低频运行,不在此处处理*/
-	foc_update_PI_Contrl(foc, &sample_dq, &v_dq);
+	Foc_Dq_PI_Contrl(foc, &sample_dq, &v_dq);
 	/* d-q坐标转 alpha-beta坐标,输入给pwm */
 	Rev_Park(&v_dq, foc->motor_s.theta, &pwm_ab);
 	/* 生成 pwm,模拟正弦波,此处vbus需要动态采集 */
@@ -57,3 +60,45 @@ void foc_task(motor_foc_t *foc){
 	/* 更新duty和采样点到硬件TIM1中 */
 	PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
 }
+
+//输出dq电流,给电流环
+static void __inline Foc_Speed_PI_Control(motor_foc_t *foc) {
+	if (foc->mode == FOC_MODE_PI_SPEED || foc->mode == FOC_MODE_PI_FULL){
+		float speed_ref = ramp_get_target(&foc->speed_ramp);
+		float vq_out = pi_control(&foc->PI_speed, speed_ref - foc->motor_s.rpm);
+		foc->dq_ref.q = vq_out;
+	}
+}
+
+void FOC_Normal_Task(motor_foc_t *foc) {
+	switch (foc->state) {
+		case START:
+			FOC_STM_NextState(CURRENT_CALIBRATE);
+			break;
+		case CURRENT_CALIBRATE:
+			FOC_STM_NextState(READY_TO_RUN);
+			break;
+		case READY_TO_RUN:
+			foc_pwm_start(true);
+			FOC_STM_NextState(RAMPINT_START);
+			ramp_exc(&foc->start_ramp);
+			foc_overide_vdq(true);
+			break;
+		case RAMPINT_START:
+			foc_overide_set_vdq(0.0f, ramp_get_target(&foc->start_ramp));
+			if (ramp_complete(&foc->start_ramp)) {
+				FOC_STM_NextState(RUNNING);
+			}
+			break;
+		case RUNNING:
+			Foc_Speed_PI_Control(foc);
+			break;
+		case ANY_STOP:
+			foc_clear();
+			FOC_STM_NextState(IDLE);
+			break;
+		default:
+			break;
+	}
+
+}

+ 2 - 1
Application/FOC/foc_task.h

@@ -1,6 +1,7 @@
 #ifndef _FOC_TASK_H__
 #define _FOC_TASK_H__
 #include "foc_type.h"
-void foc_task(motor_foc_t *foc);
+void FOC_Fast_Task(motor_foc_t *foc);
+void FOC_Normal_Task(motor_foc_t *foc);
 #endif /* _FOC_TASK_H__ */
 

+ 22 - 13
Application/FOC/foc_type.h

@@ -3,7 +3,7 @@
 #include "libs/types.h"
 #include "math/fast_math.h"
 #include "pi_controller.h"
-
+#include "ramp_ctrl.h"
 typedef struct _alphabeta {
 	float alpha;
 	float beta;
@@ -39,12 +39,13 @@ typedef struct _phase_time {
 typedef enum {
 	IDLE = 0,
 	START = 1,
-	CHARGER_BOOT_CAP = 2,
-	READY_TO_RUN = 3,
-	OPEN_LOOP = 4,
-	RUNNING = 5,
-	ANY_STOP = 6
-}foc_state_t;
+	CURRENT_CALIBRATE = 2,
+	CHARGER_BOOT_CAP = 3,
+	READY_TO_RUN = 4,
+	RAMPINT_START = 5,
+	RUNNING = 6,
+	ANY_STOP = 7
+}FOCState;
 
 typedef enum {
 	FOC_MODE_OPEN_LOOP, //开环
@@ -66,10 +67,10 @@ typedef struct current_sample {
 }current_samp_t;
 
 typedef struct _override {
-	bool is_override_theta;
+	bool is_theta;
 	float theta;
-	bool is_override_v_dq;
-	dq_t v_dq;
+	bool is_vdq;
+	dq_t vdq;
 }override_param_t;
 
 typedef struct foc_s {
@@ -86,13 +87,21 @@ typedef struct foc_s {
 	PI_ctrl_t    PI_id;
 	PI_ctrl_t    PI_iq;
 	PI_ctrl_t    PI_speed;
-	volatile foc_state_t state;
+	volatile FOCState state;
 	volatile foc_mode_t mode;
-	override_param_t override_p;
-	bool gate_output;
+	override_param_t override;
+	bool mosGate;
+	ramp_t start_ramp; //电机启动的电流ramp
+	ramp_t speed_ramp; //改变速度的ramp,比如油门变化需要设置speed_ramp
 	u16  hall_table[8];
 }motor_foc_t;
 
+typedef enum {
+	NoError = 0,
+	STMNotAllow = 1,
+	
+}FError;
+
 #define degree_2_pi(d) ((float)d * M_PI / 180.0f)
 #define pi_2_degree(d) ((float)d * 180.0f / M_PI)
 

+ 68 - 0
Application/FOC/hall_sensor.c

@@ -3,6 +3,7 @@
 #include "libs/task.h"
 #include "math/fast_math.h"
 #include "hall_sensor.h"
+#include "foc/foc.h"
 
 #define HALL_READ_TIMES 7
 /* 
@@ -48,6 +49,73 @@ float hall_sensor_get_speed(void) {
 }
 
 
+int hall_sensor_calibrate(float current, u16 *hall_table){
+	foc_pwm_start(true);
+
+	foc_overide_set_theta(0.0f);
+	foc_overide_theta(true);
+
+	foc_overide_set_vdq(0.0f, 0.0f);
+	foc_overide_vdq(true);
+		
+	for (int i = 0;i < 1000;i++) {
+		foc_overide_set_vdq((float)i * current / 1000.0f, 0.0f);
+		task_udelay(1000);
+	}
+	float sin_hall[8];
+	float cos_hall[8];
+	int hall_iterations[8];
+	memset(sin_hall, 0, sizeof(sin_hall));
+	memset(cos_hall, 0, sizeof(cos_hall));
+	memset(hall_iterations, 0, sizeof(hall_iterations));
+
+	// Forwards
+	for (int i = 0;i < 3;i++) {
+		for (int j = 0;j < 360;j++) {
+			foc_overide_set_theta(j);
+			task_udelay(10 * 1000);
+
+			int hall = get_hall_stat(7);
+			float s, c;
+			normal_sincosf(degree_2_pi(j), &s, &c);
+			sin_hall[hall] += s;
+			cos_hall[hall] += c;
+			hall_iterations[hall]++;
+		}
+	}
+
+	// Reverse
+	for (int i = 0;i < 3;i++) {
+		for (int j = 360;j >= 0;j--) {
+			foc_overide_set_theta(j);
+			task_udelay(10 * 1000);
+
+			int hall = get_hall_stat(7);
+			float s, c;
+			normal_sincosf(degree_2_pi(j), &s, &c);
+			sin_hall[hall] += s;
+			cos_hall[hall] += c;
+			hall_iterations[hall]++;
+		}
+	}
+	foc_pwm_start(false);
+	foc_overide_theta(false);
+	foc_overide_vdq(false);
+	int fails = 0;
+	for(int i = 0;i < 8;i++) {
+		if (hall_iterations[i] > 30) {
+			float ang = pi_2_degree(atan2f(sin_hall[i], cos_hall[i]));
+			fast_norm_angle(&ang);
+			hall_table[i] = (u16)ang;
+		} else {
+			hall_table[i] = 0xFFFF;
+			fails++;
+		}
+	}
+	return fails == 2;	
+}
+
+
 void hall_sensor_handler(void) {
 	u8 state_now = get_hall_stat(HALL_READ_TIMES);
 	float theta_now = _hall_table[state_now];

+ 1 - 0
Application/FOC/hall_sensor.h

@@ -30,6 +30,7 @@ typedef struct {
 void hall_sensor_init(void);
 float hall_sensor_get_theta(void); //return degree
 float hall_sensor_get_speed(void); //return rpm
+int hall_sensor_calibrate(float current, u16 *hall_table);
 
 #endif /* _HALL_SENSOR_H__ */
 

+ 9 - 0
Application/FOC/ramp_ctrl.c

@@ -4,6 +4,7 @@
 static void ramp_timer_handler(timer_t *timer);
 
 void ramp_ctrl_init(ramp_t *ramp, float start, float final, u32 duration_ms){
+	ramp->start_point = start;
 	ramp->target = start;
 	ramp->final_point = final;
 	ramp->duration_ms = duration_ms;
@@ -14,6 +15,10 @@ void ramp_ctrl_init(ramp_t *ramp, float start, float final, u32 duration_ms){
 	ramp->timer.handler = NULL;
 }
 
+void ramp_clear(ramp_t *ramp) {
+	ramp_ctrl_init(ramp, ramp->start_point, ramp->final_point, ramp->duration_ms);
+}
+
 void ramp_exc(ramp_t *ramp){
 	if (ramp->timer.handler == NULL) {
 		ramp->timer.handler = ramp_timer_handler;
@@ -25,6 +30,10 @@ float ramp_get_target(ramp_t *ramp){
 	return ramp->target;
 }
 
+bool ramp_complete(ramp_t *ramp) {
+	return ramp->target == ramp->final_point;
+}
+
 static void ramp_timer_handler(timer_t *timer) {
 	ramp_t *ramp = (ramp_t *)timer;
 	float target = ramp->target + ramp->steps;

+ 4 - 0
Application/FOC/ramp_ctrl.h

@@ -4,6 +4,7 @@
 #include "libs/task.h"
 typedef struct {
 	timer_t timer;
+	float start_point;
 	float final_point;
 	float target;
 	u32   duration_ms;
@@ -11,7 +12,10 @@ typedef struct {
 }ramp_t;
 
 void ramp_ctrl_init(ramp_t *ramp, float start, float final, u32 durations);
+void ramp_clear(ramp_t *ramp);
 void ramp_exc(ramp_t *ramp);
 float ramp_get_target(ramp_t *ramp);
+bool ramp_complete(ramp_t *ramp);
+
 #endif /* _RAMP_CTRL_H__ */
 

+ 30 - 26
Application/Hal/hal.c

@@ -85,36 +85,38 @@ void HAL_GPIO_init(void){
   	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-  	HAL_GPIO_Init(HALL_3_GROUP, &GPIO_InitStruct);	
+  	HAL_GPIO_Init(HALL_3_GROUP, &GPIO_InitStruct);
+
+  	/*Configure GPIO pin : Start_Stop_Pin */
+  	GPIO_InitStruct.Pin = Start_Stop_Pin;
+  	GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  	GPIO_InitStruct.Pull = GPIO_NOPULL;
+  	HAL_GPIO_Init(Start_Stop_GPIO_Port, &GPIO_InitStruct);	
 }
 
 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
 {
-  GPIO_InitTypeDef GPIO_InitStruct = {0};
-  if(htim_base->Instance==TIM1)
-  {
-  /* USER CODE BEGIN TIM1_MspInit 0 */
-
-  /* USER CODE END TIM1_MspInit 0 */
-    /* Peripheral clock enable */
-    __HAL_RCC_TIM1_CLK_ENABLE();
-
-    __HAL_RCC_GPIOA_CLK_ENABLE();
-    /**TIM1 GPIO Configuration
-    PA11     ------> TIM1_BKIN2
-    */
-    GPIO_InitStruct.Pin = M1_OCP_Pin;
-    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-    GPIO_InitStruct.Pull = GPIO_PULLUP;
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-    GPIO_InitStruct.Alternate = GPIO_AF12_TIM1;
-    HAL_GPIO_Init(M1_OCP_GPIO_Port, &GPIO_InitStruct);
-
-  /* USER CODE BEGIN TIM1_MspInit 1 */
-
-  /* USER CODE END TIM1_MspInit 1 */
-  }
-
+  	GPIO_InitTypeDef GPIO_InitStruct = {0};
+  	if(htim_base->Instance==TIM1)
+  	{
+    	/* Peripheral clock enable */
+    	__HAL_RCC_TIM1_CLK_ENABLE();
+
+    	__HAL_RCC_GPIOA_CLK_ENABLE();
+    	/**TIM1 GPIO Configuration
+    	PA11     ------> TIM1_BKIN2
+    	*/
+    	GPIO_InitStruct.Pin = M1_OCP_Pin;
+    	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    	GPIO_InitStruct.Pull = GPIO_PULLUP;
+    	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    	GPIO_InitStruct.Alternate = GPIO_AF12_TIM1;
+    	HAL_GPIO_Init(M1_OCP_GPIO_Port, &GPIO_InitStruct);
+  	}
+	else if (htim_base->Instance == TIM6)
+  	{
+		__HAL_RCC_TIM6_CLK_ENABLE();
+  	}
 }
 
 void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
@@ -161,6 +163,8 @@ void HAL_NVIC_Init(void){
 	HAL_NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 5, 0);
 	/* ADC1_IRQn interrupt configuration */
 	HAL_NVIC_SetPriority(ADC1_IRQn, 7, 0);
+	/* TIM6 used to produces update event every 10ms to run foc slow task */
+	HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 9, 0);
 	/* HALL EXTI configuration */
 	HAL_NVIC_SetPriority(EXTI3_IRQn, 8, 0);
 	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);

+ 3 - 0
Application/Hal/hal.h

@@ -2,6 +2,9 @@
 #define _HAL_H__
 #include "stm32f3xx_hal.h"
 
+#define Start_Stop_Pin GPIO_PIN_13
+#define Start_Stop_GPIO_Port GPIOC
+
 #define PWM_UH_Pin GPIO_PIN_8
 #define PWM_UH_GPIO_Port GPIOA
 #define PWM_VH_Pin GPIO_PIN_9

+ 28 - 0
Application/Hal/tim4.c

@@ -0,0 +1,28 @@
+#include "hal/hal.h"
+#include "hal/tim4.h"
+#include "stm32f3xx_ll_tim.h"
+
+static TIM_HandleTypeDef timx;
+void TIM4_Init(void){
+	timx.Instance = TIM6;
+	timx.Init.Prescaler = 7200; //72000000 / 7200 = 10000 // 10us
+	timx.Init.Period = 100; //10ms
+	timx.Init.RepetitionCounter = 0;
+	timx.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+	if (HAL_TIM_Base_Init(&timx) != HAL_OK)
+	{
+	  Error_Handler();
+	}	
+}
+void TIM4_Enable(void){
+	LL_TIM_SetCounter( timx.Instance, 0);
+	LL_TIM_EnableCounter(timx.Instance);
+	LL_TIM_ClearFlag_UPDATE(timx.Instance);
+	LL_TIM_EnableIT_UPDATE(timx.Instance);
+	HAL_NVIC_EnableIRQ(TIM6_DAC1_IRQn);
+}
+void TIM4_Disable(void){
+	LL_TIM_DisableCounter(timx.Instance);
+	HAL_NVIC_DisableIRQ(TIM6_DAC1_IRQn);
+}
+

+ 7 - 0
Application/Hal/tim4.h

@@ -0,0 +1,7 @@
+#ifndef _TIM4_H__
+#define _TIM4_H__
+void TIM4_Init(void);
+void TIM4_Enable(void);
+void TIM4_Disable(void);
+#endif /* _TIM4_H__ */
+

+ 75 - 47
Project/Motor_PMSM.uvoptx

@@ -222,6 +222,10 @@
           <Name>System Viewer\TIM1</Name>
           <WinId>35905</WinId>
         </Entry>
+        <Entry>
+          <Name>System Viewer\TIM6</Name>
+          <WinId>35903</WinId>
+        </Entry>
       </SystemViewers>
       <DebugDescription>
         <Enable>1</Enable>
@@ -251,6 +255,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>2</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\App\app.c</PathWithFileName>
+      <FilenameWithoutPath>app.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -261,7 +277,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>2</FileNumber>
+      <FileNumber>3</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -273,7 +289,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>3</FileNumber>
+      <FileNumber>4</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -285,7 +301,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>4</FileNumber>
+      <FileNumber>5</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -297,7 +313,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>5</FileNumber>
+      <FileNumber>6</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -309,7 +325,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>6</FileNumber>
+      <FileNumber>7</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -321,7 +337,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>7</FileNumber>
+      <FileNumber>8</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -333,7 +349,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>8</FileNumber>
+      <FileNumber>9</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -345,7 +361,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>9</FileNumber>
+      <FileNumber>10</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -357,7 +373,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>10</FileNumber>
+      <FileNumber>11</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -377,7 +393,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>11</FileNumber>
+      <FileNumber>12</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -389,7 +405,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>12</FileNumber>
+      <FileNumber>13</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -401,7 +417,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>13</FileNumber>
+      <FileNumber>14</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -421,7 +437,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>14</FileNumber>
+      <FileNumber>15</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -433,7 +449,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>15</FileNumber>
+      <FileNumber>16</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -445,7 +461,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>17</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -457,7 +473,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -477,7 +493,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -489,7 +505,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -501,7 +517,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>21</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -513,7 +529,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -523,6 +539,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>23</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\Hal\tim4.c</PathWithFileName>
+      <FilenameWithoutPath>tim4.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -533,7 +561,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -545,7 +573,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -557,7 +585,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -569,7 +597,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -581,7 +609,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -593,7 +621,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -605,7 +633,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -617,7 +645,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -629,7 +657,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>32</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -641,7 +669,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>31</FileNumber>
+      <FileNumber>33</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -653,7 +681,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>32</FileNumber>
+      <FileNumber>34</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -665,7 +693,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -677,7 +705,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -689,7 +717,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>35</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -701,7 +729,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -713,7 +741,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>39</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -725,7 +753,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -737,7 +765,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -749,7 +777,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -761,7 +789,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -773,7 +801,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -785,7 +813,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -797,7 +825,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -809,7 +837,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>45</FileNumber>
+      <FileNumber>47</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -821,7 +849,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>46</FileNumber>
+      <FileNumber>48</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -841,7 +869,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>47</FileNumber>
+      <FileNumber>49</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -853,7 +881,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>48</FileNumber>
+      <FileNumber>50</FileNumber>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 10 - 0
Project/Motor_PMSM.uvprojx

@@ -388,6 +388,11 @@
               <FileType>1</FileType>
               <FilePath>..\Application\App\main.c</FilePath>
             </File>
+            <File>
+              <FileName>app.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\App\app.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -508,6 +513,11 @@
               <FileType>1</FileType>
               <FilePath>..\Application\Hal\uart2.c</FilePath>
             </File>
+            <File>
+              <FileName>tim4.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\Hal\tim4.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>