Kaynağa Gözat

1、霍尔角度闭环
2、速度滤波放在1khz内,为了使插值角度更好看,单扇区速度进行滤波。
3、开环拖动一段时间直接切霍尔闭环

zhuts 3 saat önce
ebeveyn
işleme
a883f2f8bc

Dosya farkı çok büyük olduğundan ihmal edildi
+ 2 - 3
Keil_Project/stm32f407_ir2110_keil.uvguix.admin


+ 6 - 6
Keil_Project/stm32f407_ir2110_keil.uvoptx

@@ -982,24 +982,24 @@
     <File>
       <GroupNumber>3</GroupNumber>
       <FileNumber>63</FileNumber>
-      <FileType>1</FileType>
+      <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\motor\foc_run.c</PathWithFileName>
-      <FilenameWithoutPath>foc_run.c</FilenameWithoutPath>
+      <PathWithFileName>..\motor\foc_define_parameter.h</PathWithFileName>
+      <FilenameWithoutPath>foc_define_parameter.h</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
       <FileNumber>64</FileNumber>
-      <FileType>5</FileType>
+      <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\motor\foc_define_parameter.h</PathWithFileName>
-      <FilenameWithoutPath>foc_define_parameter.h</FilenameWithoutPath>
+      <PathWithFileName>..\motor\motor_run.c</PathWithFileName>
+      <FilenameWithoutPath>motor_run.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>

+ 6 - 6
Keil_Project/stm32f407_ir2110_keil.uvprojx

@@ -54,7 +54,7 @@
           <CreateLib>0</CreateLib>
           <CreateHexFile>1</CreateHexFile>
           <DebugInformation>1</DebugInformation>
-          <BrowseInformation>0</BrowseInformation>
+          <BrowseInformation>1</BrowseInformation>
           <ListingPath>.\output\</ListingPath>
           <HexFormatSelection>1</HexFormatSelection>
           <Merge32K>0</Merge32K>
@@ -755,16 +755,16 @@
               <FileType>1</FileType>
               <FilePath>..\motor\stm32_ekf_wrapper.c</FilePath>
             </File>
-            <File>
-              <FileName>foc_run.c</FileName>
-              <FileType>1</FileType>
-              <FilePath>..\motor\foc_run.c</FilePath>
-            </File>
             <File>
               <FileName>foc_define_parameter.h</FileName>
               <FileType>5</FileType>
               <FilePath>..\motor\foc_define_parameter.h</FilePath>
             </File>
+            <File>
+              <FileName>motor_run.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\motor\motor_run.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>

+ 152 - 16
motor/adc.c

@@ -18,11 +18,12 @@
 #include "board_config.h"
 
 
+
 #define _constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
 // 测试变量
 int32_t ia_test,ib_test,ic_test;
 
-float Ua,Ualpha,Ub,Ubeta, Uc, dc_a,dc_b,dc_c,sin_theta;
+float Ua,Ualpha,Ub,Ubeta, Uc, dc_a,dc_b,dc_c;
 //float err;
 
 // 电流和电压变量
@@ -107,6 +108,16 @@ static void get_offset(uint32_t *a_offset, uint32_t *b_offset, uint32_t* c_offse
   }
 }
 
+/**
+ * @brief 开环角度更新
+ */
+static void Angle_OpenLoop_Update(float step)
+{
+    if(get_motor()->direction == MOTOR_CW)
+        get_motor()->eleangle += step;
+    else
+        get_motor()->eleangle -= step;
+}
 
 static void FOC_parm_input(void)
 {
@@ -121,10 +132,10 @@ static void FOC_parm_input(void)
     get_foc_input()->ib = Ib;
     get_foc_input()->ic = Ic;    
 }
-static void FOC_parm_output(void)
-{
-		  EKF_Hz = get_foc_ouput()->EKF[2]/(2.0f*PI) ;
-}
+//static void FOC_parm_output(void)
+//{
+//		  EKF_Hz = get_foc_ouput()->EKF[2]/(2.0f*PI) ;
+//}
 
 
 static void uvw_current_and_vbus_get(float* vbus, double* iu, double* iv, double* iw)
@@ -137,6 +148,123 @@ static void uvw_current_and_vbus_get(float* vbus, double* iu, double* iv, double
 		Ib_test = *iv;
 		Ic_test = *iw;
 }
+
+
+/**
+ * @brief 修改后的motor_run()函数
+ * @note 集成了完整的开环→闭环切换逻辑
+ */
+void motor_run(void)
+{
+    uvw_current_and_vbus_get(&Vbus, &Ia, &Ib, &Ic);
+    //Hall_TypeDef* hall = Hall_Get();
+		//MotorParam_t* motor = get_motor();
+
+// Hall_Update_Interpolated_Angle();
+  if(speed_close_loop_flag==0)         //速度环闭环切换控制,电机刚启动时速度环不闭环
+  {                                    //并且电流参考值缓慢增加(防冲击),速度达到一定值
+    if((Iq_ref<MOTOR_STARTUP_CURRENT)) //速度切入闭环
+    {                                  //电流环在电机运行过程中全程闭环
+      Iq_ref += 0.00003f;              //角度在电机刚启动时就闭环运行,无需强拖,得益于卡尔曼滤波做
+    }                                  //状态观测器低速性能比教好
+    else
+    {
+      speed_close_loop_flag=1;
+    }
+  }
+  else
+  {
+    if(speed_close_loop_flag==1)
+    {
+      if(Iq_ref>(MOTOR_STARTUP_CURRENT/2.0f))
+      {
+        Iq_ref -= 0.001f;
+      }
+      else
+      {
+        speed_close_loop_flag=2;
+      }
+    }
+  }
+  
+//     if(FOC_Output.EKF[2]>SPEED_LOOP_CLOSE_RAD_S)      //无感方式运行,状态观测器得到角度和速度信息
+//  {
+//    FOC_Input.Id_ref = 0.0f;
+//    Speed_Fdk = FOC_Output.EKF[2];
+//    FOC_Input.Iq_ref = Speed_Pid_Out;
+//  }
+//  else
+//  {
+//    FOC_Input.Id_ref = 0.0f;
+//    FOC_Input.Iq_ref = Iq_ref;
+//    Speed_Pid.I_Sum = Iq_ref;
+//  }
+//  FOC_Input.theta = FOC_Output.EKF[3];
+//  FOC_Input.speed_fdk = FOC_Output.EKF[2];
+//	EKF_Hz = FOC_Output.EKF[2]/(2.0f*PI);
+//  FOC_Input.Id_ref = 0.0f;               
+//  FOC_Input.Tpwm = PWM_TIM_PULSE_TPWM;         //FOC运行函数需要用到的输入信息
+//  FOC_Input.Udc = Vbus;
+//  FOC_Input.Rs = Rs;
+//  FOC_Input.Ls = Ls;
+//  FOC_Input.flux = flux;
+//  
+//  FOC_Input.ia = Ia;
+//  FOC_Input.ib = Ib;
+//  FOC_Input.ic = Ic;           
+ // foc_algorithm_step();       //整个FOC运行函数(包括无感状态观测器,电流环,SVPWM,坐标变换,电机参数识别)
+    // ========== FOC参数设置 ==========
+    FOC_parm_input();
+		get_foc_input()->Iq_ref = 1.0f;
+		Hall_Update_Interpolated_Angle();
+		static uint16_t cnt = 0;
+		if(cnt <= 10000)
+		{
+			cnt++;
+			theta += 0.01f;
+			if(theta >= 2* PI)
+			{
+				theta -= 2 * PI;
+			}
+			if(theta < 0.0f)
+			{
+				theta += 2 * PI;
+			}
+			get_foc_input()->theta = theta;
+			
+		}else
+		{
+			get_foc_input()->theta = Hall_Get()->angle;
+		}
+			
+  
+    // ========== 执行FOC算法 ==========
+     motor_foc_openloop_run();
+    //motor_ekf_closeloop_run();
+    // ========== PWM输出更新 ==========
+    if(motor_start_stop == 1 )//&& motor->ctrl_state != CTRL_STATE_IDLE)
+    {
+        PWM_TIM->CCR1 = (u16)(FOC_Output.Tcmp1);
+        PWM_TIM->CCR2 = (u16)(FOC_Output.Tcmp2);
+        PWM_TIM->CCR3 = (u16)(FOC_Output.Tcmp3);
+    }
+    else
+    {
+        PWM_TIM->CCR1 = PWM_TIM_PULSE >> 1;
+        PWM_TIM->CCR2 = PWM_TIM_PULSE >> 1;
+        PWM_TIM->CCR3 = PWM_TIM_PULSE >> 1;
+    }
+    
+    // ========== 停止命令处理 ==========
+//    if(motor_start_stop == 0 && motor->ctrl_state != CTRL_STATE_IDLE && 
+//       motor->ctrl_state != CTRL_STATE_STOPPING)
+//    {
+//        motor->ctrl_state = CTRL_STATE_STOPPING;
+//    }
+}
+
+
+#if 0
 /**
  * @brief   电机运行函数
  * @note    在PWM中断中调用,频率10kHz
@@ -223,20 +351,28 @@ void motor_run(void)
     FOC_parm_input();
 		
     FOC_parm_output();
-		
+		if(get_motor()->direction == MOTOR_CW)
+			get_motor()->eleangle += 0.01f;  // 使用 float 后缀
+		else if(get_motor()->direction == MOTOR_CCW)
+			get_motor()->eleangle -= 0.01f;
+//		if(speed_close_loop_flag == 2)	
+//		{
+//			if(get_motor()->direction == MOTOR_CW)
+//				get_motor()->eleangle += Hall_Get()->angle_add;  // 使用 float 后缀
+//			else if(get_motor()->direction == MOTOR_CCW)
+//				get_motor()->eleangle -= Hall_Get()->angle_add;
+//		}			
 	
-
-		theta += 0.005f;  // 使用 float 后缀
-		if(theta >= 2.0f * PI)
+		
+		if(get_motor()->eleangle >= 2.0f * PI)
 		{
-				theta -= 2.0f * PI;
-		}
-		// 额外保护
-		if(theta < 0.0f || theta > 100.0f)  // 异常保护
+				get_motor()->eleangle -= 2.0f * PI;
+		}else if(get_motor()->eleangle <= 0.0f * PI)
 		{
-				theta = 0.0f;
+				get_motor()->eleangle += 2.0f * PI;
 		}
-		get_foc_input()->theta = theta;
+		
+		get_foc_input()->theta = get_motor()->eleangle;
 		get_foc_input()->Id_ref = Id_ref;
 		get_foc_input()->Iq_ref = Iq_ref;
 		
@@ -260,7 +396,7 @@ void motor_run(void)
     //communication_task();
 }
 
-
+#endif
 
 /**
  * @brief   ADC中断处理函数

+ 7 - 7
motor/foc_algorithm.c

@@ -18,19 +18,19 @@
 // 注:Vq和Vd是控制器输出,用于控制电机的q轴和d轴电压
 // Iq和Id是反馈电流,分别控制电机的转矩和磁场
 // 控制器参数通过自动调优获得
-real32_T D_PI_I = 200.F;          // D轴积分系数
-real32_T D_PI_KB = 1.0F;          // D轴反馈系数
+real32_T D_PI_I = 1282.8F;          // D轴积分系数
+real32_T D_PI_KB = 15.0F;         // D轴反馈系数 (抗饱和积分项)
 real32_T D_PI_ISUM_MAX = 12.0f;   // D轴最大积分限幅
 real32_T D_PI_ISUM_MIN = -12.0f;  // D轴最小积分限幅
 real32_T D_PI_LOW_LIMIT = -24.0F; // D轴输出下限
-real32_T D_PI_P = 1.0F;           // D轴比例系数
+real32_T D_PI_P = 2.199F;          // D轴比例系数
 real32_T D_PI_UP_LIMIT = 24.0F;   // D轴输出上限
-real32_T Q_PI_I = 200.F;          // Q轴积分系数
+real32_T Q_PI_I = 1282.8F;          // Q轴积分系数
 real32_T Q_PI_ISUM_MAX = 12.0f;   // Q轴最大积分限幅
 real32_T Q_PI_ISUM_MIN = -12.0f;  // Q轴最小积分限幅
-real32_T Q_PI_KB = 1.0F;          // Q轴反馈系数
+real32_T Q_PI_KB = 15.0F;         // Q轴反馈系数
 real32_T Q_PI_LOW_LIMIT = -24.0F; // Q轴输出下限
-real32_T Q_PI_P = 1.0F;           // Q轴比例系数
+real32_T Q_PI_P = 2.199F;         // Q轴比例系数
 real32_T Q_PI_UP_LIMIT = 24.0F;   // Q轴输出上限
 
 
@@ -225,7 +225,7 @@ void Current_PID_Calc(real32_T ref_temp, real32_T fdb_temp,
         (err* (output - pre_out) <= 0)) {
         pid->I_Sum += err * FOC_PERIOD;
     }
-    
+    // pid->I_Sum += err * FOC_PERIOD + (output - pre_out) * pid->B_Gain;
 //    if (pid->I_Sum > pid->Max_Integral) pid->I_Sum = pid->Max_Integral;
 //    if (pid->I_Sum < pid->Min_Integral) pid->I_Sum = pid->Min_Integral;
      // vd = R*id + Ld*(did/dt) - ωe*Lq*iq      // 电压方程

+ 1 - 0
motor/foc_algorithm.h

@@ -302,5 +302,6 @@ extern CURRENT_PID_DEF* get_currd_pid(void);
 extern CURRENT_PID_DEF* get_currq_pid(void);
 	
 extern CURRENT_DQ_DEF* get_curr_dq(void);
+
 #endif                                
 

+ 2 - 2
motor/foc_define_parameter.h

@@ -17,8 +17,8 @@
 #define VBUS 24.0f
 
 // 选择FOC类型:霍尔传感器FOC或无传感器FOC
-#define HALL_FOC_SELECT          // 使用霍尔传感器的FOC模式
-//#define SENSORLESS_FOC_SELECT    // 使用无传感器的FOC模式
+//#define HALL_FOC_SELECT          // 使用霍尔传感器的FOC模式
+#define SENSORLESS_FOC_SELECT    // 使用无传感器的FOC模式
 
 // 电机参数(基于TG5P40电机)
 #define RS_PARAMETER     0.445f           // 定子电阻 (Ω)

+ 85 - 20
motor/hall_sensor.c

@@ -5,8 +5,9 @@
  **********************************/
 #include "main.h"
 #include "hall_sensor.h"
+#include "motor_define.h"
 
-
+#define SPEED_FILTER_DEPTH 8
 
 Hall_TypeDef Hall = {0};  // 全局实例
 
@@ -15,46 +16,110 @@ Hall_TypeDef* Hall_Get(void)
     return &Hall;
 }
 
+static float speed_history[SPEED_FILTER_DEPTH] = {0};
+
+static uint8_t speed_idx = 0;
+
+float Get_Filtered_Speed(void)
+{
+    speed_history[speed_idx++] =(Hall.speed[0]+Hall.speed[1]+Hall.speed[2]+Hall.speed[3]+Hall.speed[4]+Hall.speed[5])/6.0f;
+    if(speed_idx >= SPEED_FILTER_DEPTH) speed_idx = 0;
+    
+    float sum = 0;
+    for(int i=0; i<SPEED_FILTER_DEPTH; i++)
+        sum += speed_history[i];
+    return sum / SPEED_FILTER_DEPTH;
+}
+
+
 /**
  * @brief   TIM5中断处理函数
  * @note    处理霍尔传感器信号中断,计算电机角度和速度
  */
 void TIM5_IRQHandler(void)
 {
-  float temp;
 
   if(TIM_GetFlagStatus(TIM5, TIM_FLAG_CC1) == SET)
   {
-			Hall.ccr = (float)TIM_GetCapture1(TIM5);
-			TIM_ClearFlag(TIM5, TIM_FLAG_CC1);
+		Hall.ccr = (float)TIM_GetCapture1(TIM5);
+		TIM_ClearFlag(TIM5, TIM_FLAG_CC1);
+		
+		Hall.state_last = Hall.state; // 记录上次状态
 		
-//    hall_angle_add = (float)HALL_ANGLE_FACTOR / temp;
-//    hall_speed     = (float)HALL_SPEED_FACTOR / temp;
-
     uint8_t W = GPIO_ReadInputDataBit(HALL_CH3_GPIO_PORT, HALL_CH3_PIN); // 需要根据实际进行修改
     uint8_t V = GPIO_ReadInputDataBit(HALL_CH2_GPIO_PORT, HALL_CH2_PIN);
     uint8_t U = GPIO_ReadInputDataBit(HALL_CH1_GPIO_PORT, HALL_CH1_PIN);
     Hall.state = U;		//计算扇区
 		Hall.state |= V << 1;
 		Hall.state |= W << 2;
-
+		
     switch(Hall.state)
     {
-			// 645132
-      case 0x06: Hall.angle = 0.0f;              break;
-      case 0x04: Hall.angle = PI / 3.0f;         break;
-      case 0x05: Hall.angle = 2 * PI / 3.0f;     break;
-      case 0x01: Hall.angle = PI;                break;
-      case 0x03: Hall.angle = 4 * PI / 3.0f;     break;
-      case 0x02: Hall.angle = 5 * PI / 3.0f;     break;
+			// CW 645132 CCW 623154
+      case 0x06: 
+				Hall.theta[0]  = 0.4506f; 
+			  Hall.angle = Hall.theta[0];
+				Hall.count[0] = Hall.ccr;
+				Hall.speed[0]  = (Hall.speed[0]+( 2.0f * PI + Hall.theta[0]-Hall.theta[5]) / (Hall.count[0] / HALL_SPEED_FACTOR))/2.0f; // 电弧度
+			  Hall.angle_add = Hall.speed[0] / HALL_SAMPLE_FREQ; // 速度乘电流环单次时间 速度*0.0001s 单次电流环插值间隔
+			
+			break;
+      case 0x04:
+				Hall.theta[1]  = 0.4506f + PI / 3;  
+				Hall.angle = Hall.theta[1]  ;			
+				Hall.count[1] = Hall.ccr;
+				Hall.speed[1]  = (Hall.speed[1]+(Hall.theta[1]-Hall.theta[0]) / (Hall.count[1] / HALL_SPEED_FACTOR))/2.0f;  
+				Hall.angle_add = Hall.speed[1] / HALL_SAMPLE_FREQ;
+			break;
+			case 0x05: 
+				Hall.theta[2]  = 0.4506f + 2.0f * PI / 3;
+			  Hall.count[2] = Hall.ccr;
+				Hall.angle = Hall.theta[2]  ;
+				Hall.speed[2]  =  (Hall.speed[2]+ (Hall.theta[2]-Hall.theta[1]) / (Hall.count[2] / HALL_SPEED_FACTOR))/2.0f;  
+				Hall.angle_add = Hall.speed[2] / HALL_SAMPLE_FREQ;
+			break;
+      case 0x01: 
+				Hall.theta[3]  = 0.4506f + PI;  
+				Hall.angle = Hall.theta[3];			
+				Hall.count[3] = Hall.ccr;
+				Hall.speed[3]  = (Hall.speed[3] +  (Hall.theta[3]-Hall.theta[2]) / (Hall.count[3] / HALL_SPEED_FACTOR))/2.0f;  
+				Hall.angle_add = Hall.speed[3] / HALL_SAMPLE_FREQ;
+			break;
+      case 0x03: 
+				Hall.theta[4]  = 0.4506f + 4.0f * PI / 3; 
+			  Hall.angle = Hall.theta[4] ;
+				Hall.count[4] = Hall.ccr;
+				Hall.speed[4]  =   (Hall.speed[4]+(Hall.theta[4]-Hall.theta[3]) / (Hall.count[4] / HALL_SPEED_FACTOR))/2.0f;  
+				Hall.angle_add = Hall.speed[4] / HALL_SAMPLE_FREQ;
+			break;
+      case 0x02:
+				Hall.theta[5]  = 0.4506f + 5.0f * PI / 3; 
+			  Hall.angle = Hall.theta[5]  ;
+				Hall.count[5] = Hall.ccr;
+				Hall.speed[5]  =  (Hall.speed[5]+ (Hall.theta[5]-Hall.theta[4]) / (Hall.count[5] / HALL_SPEED_FACTOR))/2.0f;   
+				Hall.angle_add = Hall.speed[5] / HALL_SAMPLE_FREQ;
+			break;
       default: break;
     }
     
-    Hall.angle += PHASE_SHIFT_ANGLE;
-    
-    if(Hall.angle < 0)    Hall.angle += 2*PI;
-    if(Hall.angle > 2*PI) Hall.angle -= 2*PI;
+  }
+}
 
+// 电流环中调用的角度插值函数
+void Hall_Update_Interpolated_Angle(void)
+{
+    static uint8_t last_state = 0xFF;
     
-  }
+    // 检查状态是否变化
+    if(Hall.state != last_state) {
+        last_state = Hall.state;
+    } 
+    else {
+        // 状态未变化,累加角度
+        Hall.angle += Hall.angle_add;
+    }
+    
+    // 角度归一化
+    if(Hall.angle >= 2*PI) Hall.angle -= 2*PI;
+    if(Hall.angle < 0) Hall.angle += 2*PI;
 }

+ 26 - 16
motor/hall_sensor.h

@@ -15,17 +15,20 @@
 
 typedef struct 
 {
-  uint8_t state;      // 当前稳定霍尔状态
-	uint8_t state_last; //上一个霍尔状态
-	float angle;				//霍尔传感器计算得到的电机角度
-	float angle_add;			//单次电流环时间内角度自增值
-	uint32_t ccr;				
-	float theta[6];				//霍尔传感器六个扇区的角度
-	uint32_t count[6];			//经过六个扇区分别花费的计数值
-	uint32_t last_valid_count[6]; //上一个扇区有效计数值,用于滤波
-	uint8_t flag;				//是否进入闭环控制的标志位
-	float speed[6];				//六个扇区的角速度
-	float Speed;				//电机角速度,是对 speed[6] 取了平均值
+  uint8_t state;           // 当前霍尔状态
+  uint8_t state_last;      // 上一个霍尔状态
+  float angle;             // 霍尔计算得到的电机角度(原始)
+  float angle_add;         // 单次PWM周期角度自增值
+  uint32_t ccr;            // 捕获计数值
+  float theta[6];          // 六个扇区的基准角度
+  uint32_t count[6];       // 各扇区计数值
+  uint32_t last_valid_count[6];  // 上次有效计数值
+  uint8_t flag;            // 进入闭环标志
+  float speed[6];          // 各扇区电弧度
+  float Speed;             // 平均电弧度
+  uint16_t enter_cnt;       // 进入霍尔次数 
+  
+  
 } Hall_TypeDef;
 
 /**
@@ -44,8 +47,8 @@ typedef struct
  * @brief 相位偏移角度
  * @details 设置为60度,转换为弧度
  */
-// #define PHASE_SHIFT_ANGLE (float)(60.0f/360.0f*2.0f*PI)
-#define PHASE_SHIFT_ANGLE (float)(26.36f/360.0f*2.0f*PI)
+// #define PHASE_SHIFT_ANGLE (float)(30.0f/360.0f*2.0f*PI)
+#define PHASE_SHIFT_RAD (float)(0.f)
 /**
  * @brief 角度计算因子
  * @details 用于将计数值转换为角度增量
@@ -54,9 +57,16 @@ typedef struct
 
 /**
  * @brief 速度计算因子
- * @details 用于将计数值转换为电机速度
+ * @details 用于将计数值转换为电机速度 rad/s
  */
-#define HALL_SPEED_FACTOR (float)((float)HALL_TIM_CLOCK/6.0f)
+#define HALL_SPEED_FACTOR (float)(HALL_TIM_CLOCK )
 
-Hall_TypeDef* Hall_Get(void);
+
+
+
+extern Hall_TypeDef* Hall_Get(void);
+
+extern void Hall_Update_Interpolated_Angle(void);   // 更新插值角度
+
+extern float Get_Filtered_Speed(void); // 速度滤波
 #endif

+ 3 - 3
motor/low_task.c

@@ -132,7 +132,7 @@ void low_control_task(void)
   if(key2_flag == 1)
   {
     Speed_Ref += 5.0f;  // 速度参考值增加5.0转/秒
-		Iq_ref += 0.2;
+		Iq_ref += 0.2f;
     key2_flag = 0;  // 清除按键标志
   }
   
@@ -140,7 +140,7 @@ void low_control_task(void)
   if(key3_flag == 1)
   {
     Speed_Ref -= 5.0f;  // 速度参考值减少5.0转/秒
-		Iq_ref -= 0.2;
+		Iq_ref -= 0.2f;
     key3_flag = 0;      // 清除按键标志
   }
 }
@@ -153,7 +153,7 @@ void SysTick_Handler(void)
 {
 	 Temp = calculate_temperature(ADC_TO_RT(ADC3ConvertedValue[ADC3_TEMP_INDEX]));
   //rtspeed_ref = 20.0F;  // 速度参考值(已注释)
-
+	Hall_Get()->Speed = Get_Filtered_Speed();
   // 执行速度PID计算
   Speed_Pid_Calc(Speed_Ref, Speed_Fdk, &Speed_Pid_Out, &Speed_Pid);
   

+ 40 - 0
motor/motor_define.h

@@ -0,0 +1,40 @@
+#ifndef __MOTOR_DEFINE_H
+#define __MOTOR_DEFINE_H
+
+
+typedef enum{
+	MOTOR_CW  = 0,
+	MOTOR_CCW = 1,
+	
+}MotorDirection;
+
+typedef enum{
+	MOTOR_SENSOR_LESS = 0,
+	MOTOR_SENSOR_HALL = 1,
+	MOTOR_SENSOR_ENCODER = 2,
+}MotorSensor;
+
+// 状态枚举
+typedef enum {
+    CTRL_STATE_IDLE = 0,
+    CTRL_STATE_STARTUP_RAMP = 1 ,        // 启动电流斜坡
+    CTRL_STATE_OPENLOOP_RUN = 2,        // 开环运行等待达到速度
+    CTRL_STATE_ALIGNMENT = 3,           // 角度对齐阶段
+    CTRL_STATE_TRANSITION_BLENDING = 4, // 过渡融合阶段
+    CTRL_STATE_HALL_CLOSED_LOOP = 5,    // 霍尔闭环运行
+    CTRL_STATE_STOPPING = 6             // 停车处理
+} ControlState_e;
+
+
+typedef struct{
+	MotorDirection direction; // 电机旋转方向 0 CW 1 CCW
+	unsigned char poles; // 电机极数
+	MotorSensor sensor; // 传感器类型 0 无感 1 霍尔 2 编码器
+	float eleangle; // 电机当前电角度
+	ControlState_e ctrl_state; // 当前电机状态
+	
+}MotorParam_t;
+
+extern MotorParam_t* get_motor(void);
+
+#endif

+ 32 - 11
motor/motor_run.c

@@ -1,5 +1,21 @@
 #include "foc_algorithm.h"
 #include "speed_pid.h"
+#include "main.h"
+
+MotorParam_t motor1 = {
+.direction = MOTOR_CW,
+.poles = 4,
+.sensor = MOTOR_SENSOR_HALL,
+.eleangle = 0.0f,
+.ctrl_state = CTRL_STATE_IDLE,
+};
+
+
+MotorParam_t* get_motor(void)
+{
+	return &motor1;
+}
+
 
 FOC_INTERFACE_STATES_DEF FOC_Interface_states;
 
@@ -190,11 +206,12 @@ void foc_algorithm_initialize(void)
  ***************************************/
 void motor_ekf_closeloop_run(void)
 {
-  // 1. 读取三相电流
-  Current_Iabc.Ia = FOC_Input.ia;         // 读取A相电流
-  Current_Iabc.Ib = FOC_Input.ib;         // 读取B相电流
-  Current_Iabc.Ic = FOC_Input.ic;         // 读取C相电流
-  
+	
+		// 1. 读取三相电流
+	Current_Iabc.Ia = FOC_Input.ia;         // 读取A相电流
+	Current_Iabc.Ib = FOC_Input.ib;         // 读取B相电流
+	Current_Iabc.Ic = FOC_Input.ic;         // 读取C相电流
+	
   // 2. 坐标变换
   Clarke_Transf(Current_Iabc,&Current_Ialpha_beta);        // Clarke变换:三相到两相静止
   Angle_To_Cos_Sin(FOC_Input.theta,&Transf_Cos_Sin);     // 计算角度的余弦和正弦值
@@ -265,11 +282,13 @@ void motor_hall_close_run(void)
 
 void motor_foc_openloop_run(void)
 {
-	 // 1. 读取三相电流
-  Current_Iabc.Ia = FOC_Input.ia;         // 读取A相电流
-  Current_Iabc.Ib = FOC_Input.ib;         // 读取B相电流
-  Current_Iabc.Ic = FOC_Input.ic;         // 读取C相电流
-  
+	
+		// 1. 读取三相电流
+	Current_Iabc.Ia = FOC_Input.ia;         // 读取A相电流
+	Current_Iabc.Ib = FOC_Input.ib;         // 读取B相电流
+	Current_Iabc.Ic = FOC_Input.ic;         // 读取C相电流
+	
+ 
   // 2. 坐标变换
   Clarke_Transf(Current_Iabc,&Current_Ialpha_beta);        // Clarke变换:三相到两相静止
   Angle_To_Cos_Sin(FOC_Input.theta,&Transf_Cos_Sin);     // 计算角度的余弦和正弦值
@@ -284,4 +303,6 @@ void motor_foc_openloop_run(void)
 	
 	SVPWM_Calc(Voltage_Alpha_Beta,FOC_Input.Udc,FOC_Input.Tpwm);       // SVPWM计算
 	
-}
+}
+
+

+ 41 - 11
user/main.c

@@ -10,9 +10,8 @@
 #include "led_app.h"
 #include <stdio.h>
 
-#define PRINT_LEN 8
 static __IO uint32_t uwTimingDelay;  // 延时计数器
-uint8_t speed=0; 
+
 /**
  * @brief 简化版时钟信息打印(仅打印关键信息)
  */
@@ -74,21 +73,52 @@ int main(void)
   while (1)
   {
       
-		#define PRINT_LEN 8
+		#define PRINT_LEN 11
 			float data_print[PRINT_LEN] = {0};
 			const uint8_t tail[4] = {0x00, 0x00, 0x80, 0x7f};  // 帧尾
         // 准备打印数据并直接发送到 DMA 缓冲区
       uint8_t dma_tx_buffer[PRINT_LEN * sizeof(float) + 4];
       
 #ifdef OPENLOOP_TEST
-      data_print[0] = theta;
-      data_print[1] = Vbus;
-      data_print[2] = 0;
-      data_print[3] = get_foc_input()->Id_ref;
-      data_print[4] = get_foc_input()->Iq_ref;
-      data_print[5] = get_curr_dq()->Id;
-      data_print[6] = get_curr_dq()->Iq;
-      data_print[7] = Temp;
+//      data_print[0] = theta;
+//      data_print[1] = Vbus;
+//      data_print[2] = 0;
+//      data_print[3] = get_foc_input()->Id_ref;
+//      data_print[4] = get_foc_input()->Iq_ref;
+//      data_print[5] = get_curr_dq()->Id;
+//      data_print[6] = get_curr_dq()->Iq;
+//      data_print[7] = Temp;
+			
+//			data_print[0] = Hall_Get()->count[0];           
+//			data_print[1] = Hall_Get()->count[1];             
+//			data_print[2] = Hall_Get()->count[2];        
+//			data_print[3] = Hall_Get()->count[3];        
+//			data_print[4] = Hall_Get()->count[4];       
+//			data_print[5] = Hall_Get()->count[5];
+//			data_print[6] = Hall_Get()->speed[0];
+//			data_print[7] =  Hall_Get()->speed[1];
+//			data_print[8] = Hall_Get()->speed[2];
+//			data_print[9] = Hall_Get()->speed[3];
+//			data_print[10] = Hall_Get()->speed[4];
+//			data_print[11] = Hall_Get()->speed[5];
+//			data_print[12] = Hall_Get()->state;               
+//			data_print[13] = Hall_Get()->Speed;     
+//			data_print[14] = Hall_Get()->angle;
+//			data_print[15] = Hall_Get()->angle_add;
+//			data_print[16] = theta;
+
+			data_print[0] = Hall_Get()->speed[0];
+			data_print[1] =  Hall_Get()->speed[1];
+			data_print[2] = Hall_Get()->speed[2];
+			data_print[3] = Hall_Get()->speed[3];
+			data_print[4] = Hall_Get()->speed[4];
+			data_print[5] = Hall_Get()->speed[5];
+			data_print[6] = Hall_Get()->state;               
+			data_print[7] = Hall_Get()->Speed;     
+			data_print[8] = Hall_Get()->angle;
+			data_print[9] = Hall_Get()->angle_add;
+			data_print[10] = theta;
+			
 #else
 //      data_print[0] = FOC_Input.ia;
 //      data_print[1] = FOC_Input.ib;

+ 1 - 1
user/main.h

@@ -43,7 +43,7 @@
 #include "low_task.h"
 #include "speed_pid.h"
 #include "uart_communication.h"
-#include "openloop.h"
+#include "motor_define.h"
 /* Exported types ------------------------------------------------------------*/
 /**
  * @brief 布尔类型定义

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor