Sfoglia il codice sorgente

电流采样

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 anni fa
parent
commit
0dd72cf959

+ 7 - 3
Application/FOC/foc.c

@@ -107,8 +107,9 @@ void foc_current_calibrate(void){
 	mFOC.current_samp.adc_offset_a = 0;
 	mFOC.current_samp.adc_offset_b = 0;
 	mFOC.current_samp.adc_offset_c = 0;
+
 	PWM_Disable_Channels();
-	foc_pwm_start(false);
+	//foc_pwm_start(false);
 
 	task_udelay(10);
 	
@@ -116,13 +117,16 @@ void foc_current_calibrate(void){
 	mFOC.current_samp.is_calibrating = true;
 	mFOC.current_samp.sector = SECTOR_5;
 	foc_pwm_start(true);
-	while(mFOC.current_samp.offset_sample_count == 0){};
+	HAL_ADC1_InJ_StartConvert();
+	while(mFOC.current_samp.offset_sample_count != 0){};
 	
 	foc_pwm_start(false);
+	task_udelay(100);
 	phase_current_init(&mFOC.current_samp);	
 	mFOC.current_samp.sector = SECTOR_1;
 	foc_pwm_start(true);
-	while(mFOC.current_samp.offset_sample_count == 0){};
+	while(mFOC.current_samp.offset_sample_count != 0){};
+	mFOC.current_samp.is_calibrating = false;
 	foc_pwm_start(false);
 	PWM_Enable_Channels();
 }

+ 33 - 0
Application/FOC/foc_task.c

@@ -33,6 +33,37 @@ static void __inline Foc_Dq_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref
 	}
 }
 
+static void __inline DeadTime_Compensation(current_samp_t *c_sample, phase_time_t *time) {
+    /* Dead time compensation */
+    if ( c_sample->ia > 0)
+    {
+      time->A += TDead;
+    }
+    else
+    {
+      time->A -= TDead;
+    }
+
+    if ( c_sample->ib > 0 )
+    {
+      time->B += TDead;
+    }
+    else
+    {
+      time->B -= TDead;
+    }
+
+    if ( c_sample->ic > 0 )
+    {
+      time->C += TDead;
+    }
+    else
+    {
+      time->C -= TDead;
+    }
+	
+}
+
 /* FOC 主控制逻辑 */
 void FOC_Fast_Task(motor_foc_t *foc){
 	current_samp_t *c_sample = &foc->current_samp;
@@ -57,6 +88,8 @@ void FOC_Fast_Task(motor_foc_t *foc){
 	svpwm(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
 	/* 通过扇区和pwm duty 选择合适的3相电流采样点 */
 	sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
+	/* 死区补偿 */
+	DeadTime_Compensation(c_sample, &phase_time);
 	/* 更新duty和采样点到硬件TIM1中 */
 	PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
 }

+ 2 - 2
Application/FOC/foc_type.h

@@ -64,8 +64,8 @@ typedef struct current_sample {
 	float ic;
 	u8    sector;
 	u32   adc_inject_flags;
-	int   offset_sample_count;
-	bool  is_calibrating;
+	volatile int   offset_sample_count;
+	volatile bool  is_calibrating;
 }current_samp_t;
 
 typedef struct _override {

+ 25 - 22
Application/FOC/phase_current.c

@@ -2,7 +2,7 @@
 #include "foc_type.h"
 
 #define NB_OFFSET_SAMPLES 32
-static float __inline adc_to_current(u32 adc){
+static float __inline adc_to_current(int adc){
 	int i_adc = (int)adc;
 	if (i_adc > INT16_MAX){
 		i_adc = INT16_MAX;
@@ -21,19 +21,22 @@ void phase_current_init(current_samp_t *cs) {
 void phase_current_offset(current_samp_t *cs) {
 	u32 phase_current1, phase_current2;
 	HAL_ADC1_Inject_Read(cs->sector, &phase_current1, &phase_current2);
-	cs->offset_sample_count--;
-	if (cs->sector == SECTOR_5 && cs->offset_sample_count >= 0) {
-		cs->adc_offset_a += phase_current1;
-		cs->adc_offset_b += phase_current2;
-		if (cs->offset_sample_count == 0) {
-			cs->adc_offset_a = cs->adc_offset_a / NB_OFFSET_SAMPLES;
-			cs->adc_offset_b = cs->adc_offset_b / NB_OFFSET_SAMPLES;
+
+	if (cs->offset_sample_count > 0) {
+		cs->offset_sample_count--;
+		if (cs->sector == SECTOR_5 && cs->offset_sample_count >= 0) {
+			cs->adc_offset_a += phase_current1;
+			cs->adc_offset_b += phase_current2;
+			if (cs->offset_sample_count == 0) {
+				cs->adc_offset_a = cs->adc_offset_a / NB_OFFSET_SAMPLES;
+				cs->adc_offset_b = cs->adc_offset_b / NB_OFFSET_SAMPLES;
+			}
 		}
-	}
-	if (cs->sector == SECTOR_1 && cs->offset_sample_count >= 0) {
-		cs->adc_offset_c += phase_current2;
-		if (cs->offset_sample_count == 0) {
-			cs->adc_offset_c = cs->adc_offset_c / NB_OFFSET_SAMPLES;
+		if (cs->sector == SECTOR_1 && cs->offset_sample_count >= 0) {
+			cs->adc_offset_c += phase_current2;
+			if (cs->offset_sample_count == 0) {
+				cs->adc_offset_c = cs->adc_offset_c / NB_OFFSET_SAMPLES;
+			}
 		}
 	}
 }
@@ -44,25 +47,25 @@ void phase_current_sample(current_samp_t *cs){
 	if (cs->sector == SECTOR_4 || cs->sector == SECTOR_5) {
 		/* Current on Phase C is not accessible */
       	/* Ia = PhaseAOffset - ADC converted value) */
-		cs->ia = adc_to_current(phase_current1 - cs->adc_offset_a);
-		cs->ib = adc_to_current(phase_current2 - cs->adc_offset_b);
+		cs->ia = -adc_to_current((int)phase_current1 - (int)cs->adc_offset_a);
+		cs->ib = -adc_to_current((int)phase_current2 - (int)cs->adc_offset_b);
 		cs->ic = -(cs->ia + cs->ib);
 	}else if (cs->sector == SECTOR_1 || cs->sector == SECTOR_6) {
 		/* Current on Phase A is not accessible 	*/
 		/* Ib = PhaseBOffset - ADC converted value) */
-		cs->ib = adc_to_current(phase_current1 - cs->adc_offset_b);
-		cs->ic = adc_to_current(phase_current2 - cs->adc_offset_c);
+		cs->ib = -adc_to_current((int)phase_current1 - (int)cs->adc_offset_b);
+		cs->ic = -adc_to_current((int)phase_current2 - (int)cs->adc_offset_c);
 		cs->ia = -(cs->ib + cs->ic);
 	}else if (cs->sector == SECTOR_2 || cs->sector == SECTOR_3) {
 		/* Current on Phase B is not accessible 	*/
 		/* Ia = PhaseAOffset - ADC converted value) */
-		cs->ia = adc_to_current(phase_current1 - cs->adc_offset_a);
-		cs->ic = adc_to_current(phase_current2 - cs->adc_offset_c);
+		cs->ia = -adc_to_current((int)phase_current1 - (int)cs->adc_offset_a);
+		cs->ic = -adc_to_current((int)phase_current2 - (int)cs->adc_offset_c);
 		cs->ib = -(cs->ia + cs->ic);
 	}
 	static int tet_p = 0;
-	if (tet_p++ % 20 == 0) {
-	printf("$%d %d %d;", (int)(cs->ia * 1000), (int)(cs->ib*1000), -(int)(cs->ic*1000));
+	if (tet_p++ % 5 == 0) {
+	printf("$%d %d %d;", (int)(cs->ia * 1000), (int)(cs->ib*1000), (int)(cs->ic*1000));
 		}
 }
 
@@ -75,7 +78,7 @@ u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector){
 		cs->sector = SECTOR_5;
 		return FOC_PWM_Half_Period - 1;
 	}else {
-		u32 low_side_mid_duty = FOC_PWM_period/2 - time->midle;
+		u32 low_side_mid_duty = FOC_PWM_Half_Period - time->midle;
 		u32 delta_duty = low_side_mid_duty - low_side_low_duty;
 		if (delta_duty > low_side_low_duty * 2) {
 			return time->low - TADC;

+ 2 - 2
Application/FOC/svpwm.c

@@ -2,8 +2,8 @@
 #include "math/fast_math.h"
 
 void svpwm(alpha_beta_t *alpha_beta, float vbus, uint32_t PWM_half_period, phase_time_t *phase_out, u8 *sector_out){
-	float alpha = alpha_beta->alpha / (3.0f/2.0f * vbus);
-	float beta  = alpha_beta->beta / (3.0f/2.0f * vbus);
+	float alpha = alpha_beta->alpha / (2.0f/2.0f * vbus);
+	float beta  = alpha_beta->beta / (2.0f/2.0f * vbus);
 	uint32_t sector;
 
 	if (beta >= 0.0f) {

+ 2 - 2
Application/Hal/adc.c

@@ -121,7 +121,7 @@ void HAL_ADC1_Enable(void) {
 		  LL_ADC_Enable(  ADCx );
 		}
 		/* Clear JSQR from CubeMX setting to avoid not wanting conversion*/
-		LL_ADC_INJ_StartConversion( ADCx ); 
+		//LL_ADC_INJ_StartConversion( ADCx ); 
 		//LL_ADC_INJ_StopConversion(ADCx);
 		/* TODO: check if not already done by MX */
 		LL_ADC_INJ_SetQueueMode( ADCx, LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY );
@@ -135,7 +135,7 @@ void HAL_ADC1_Enable(void) {
 
 	HAL_NVIC_EnableIRQ(ADC1_IRQn);
 
-	//HAL_ADC1_InJ_StartConvert();
+	//LL_ADC_INJ_StartConversion( ADCx );
 }
 
 void HAL_ADC1_InJ_StartConvert(void) {

+ 5 - 5
Application/Hal/hal.c

@@ -133,10 +133,10 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     /**ADC1 GPIO Configuration
-    PC0     ------> ADC1_IN6
-    PC1     ------> ADC1_IN7
+    PC0     ------> ADC1_IN6 --> W
+    PC1     ------> ADC1_IN7 --> V
     PC2     ------> ADC1_IN8
-    PA0     ------> ADC1_IN1
+    PA0     ------> ADC1_IN1 --> U
     PA1     ------> ADC1_IN2
     */
     GPIO_InitStruct.Pin = CURR_AMPL_W_Pin|CURR_AMPL_V_Pin|TEMPERATURE_Pin;
@@ -162,9 +162,9 @@ void HAL_NVIC_Init(void){
 	/* TIM1_UP_TIM16_IRQn interrupt configuration */
 	HAL_NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 5, 0);
 	/* ADC1_IRQn interrupt configuration */
-	HAL_NVIC_SetPriority(ADC1_IRQn, 7, 0);
+	HAL_NVIC_SetPriority(ADC1_IRQn, 6, 0);
 	/* TIM6 used to produces update event every 10ms to run foc slow task */
-	HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 9, 0);
+	HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 7, 0);
 	/* HALL EXTI configuration */
 	HAL_NVIC_SetPriority(EXTI3_IRQn, 8, 0);
 	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);

+ 2 - 2
Application/Hal/hal.h

@@ -47,9 +47,9 @@
 #define UART_RX_Pin GPIO_PIN_3
 #define UART_RX_GPIO_Port GPIOA
 
-#define CURRENT_U_ADC_CHANNAL 6
+#define CURRENT_U_ADC_CHANNAL 1
 #define CURRENT_V_ADC_CHANNAL 7
-#define CURRENT_W_ADC_CHANNAL 1
+#define CURRENT_W_ADC_CHANNAL 6
 #define TEMP_SENSOR_ADC_CHANNEL 8
 #define VBUS_SENSOR_ADC_CHANNEL 2
 

+ 5 - 0
Project/Motor_PMSM.uvoptx

@@ -185,6 +185,11 @@
           <WinNumber>1</WinNumber>
           <ItemText>timer_head</ItemText>
         </Ww>
+        <Ww>
+          <count>6</count>
+          <WinNumber>1</WinNumber>
+          <ItemText>mFOC.current_samp</ItemText>
+        </Ww>
       </WatchWindow1>
       <Tracepoint>
         <THDelay>0</THDelay>