Przeglądaj źródła

编码器Z信号处理:
通过一个timer直接捕获Z信号,然后通过trigger
out输出给编码器AB信号的timer chan2,chan2选择内部信号捕获,捕获后
counter计数自动写入到chan2 val寄存器

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

kevin 2 lat temu
rodzic
commit
40e4ca341c

+ 1 - 1
Applications/app/app.c

@@ -64,7 +64,7 @@ static void app_print_log(void) {
 	//sample_log();
 	//throttle_log();
 	sys_debug("Trq: %f-%f-%f\n", motor.controller.input_torque.target, motor.controller.input_torque.interpolation, motor.controller.input_torque.step);
-	sys_debug("acc %d\n", get_acc_vol());
+	sys_debug("acc vol: %d\n", get_acc_vol());
 	//F_debug();
 	//eCtrl_debug_log();
 	//sys_debug("enc err %d, %d\n", foc_observer_enc_errcount(), foc_observer_sensorless_stable());

+ 34 - 17
Applications/bsp/gd32/enc_intf.c

@@ -69,15 +69,25 @@ void enc_intf_quadrature_init(u32 rate) {
 	timer_input_capture_config(timer,TIMER_CH_1,&timer_icinitpara);
 
 	timer_quadrature_decoder_mode_config(timer ,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_FALLING, TIMER_IC_POLARITY_RISING);
-	
+
+	/* TIMER CH2 PWM input capture configuration */
+	timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;
+	timer_icinitpara.icselection = TIMER_IC_SELECTION_ITS;
+	timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
+	timer_icinitpara.icfilter	 = 0;
+	timer_input_capture_config(timer, TIMER_CH_2, &timer_icinitpara);
+	timer_input_trigger_source_select(timer, TIMER_SMCFG_TRGSEL_ITI3);//come from trigger out of time3 which captrue the Z singnal and output to me
+
 	/* auto-reload preload enable */
 	timer_auto_reload_shadow_enable(timer);	
 
-	
 	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_UP);
 
-	//timer_interrupt_enable(timer, TIMER_INT_UP);
-	//nvic_irq_enable(ENC_TIMER_IRQ, ENC_TIMER_IRQ_PRIORITY, 0);
+    /* clear channel 0 interrupt bit */
+    timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_CH2);
+    /* channel 0 interrupt enable */
+    timer_interrupt_enable(timer, TIMER_INT_CH2);
+	nvic_irq_enable(ENC_TIMER_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0);
 
 	/* TIMER2 counter enable */
 	timer_enable(timer);
@@ -141,7 +151,7 @@ void enc_intf_z_counter(void) {
 
 	/* TIMER configuration */
 	timer_struct_para_init(&timer_initpara);
-	timer_initpara.prescaler		= TIM_CLOCK/PWM_TIME_CLK - 1;
+	timer_initpara.prescaler		= 0;
 	timer_initpara.alignedmode		= TIMER_COUNTER_EDGE;
 	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
 	timer_initpara.period		   = 65535;
@@ -157,20 +167,20 @@ void enc_intf_z_counter(void) {
 	timer_icinitpara.icfilter	 = CONFIG_PWM_FILTER_NR;
 	timer_input_capture_config(timer, ENC_I_TIMER_CHAN, &timer_icinitpara);
 
-	/* slave mode selection: TIMER */
-	timer_input_trigger_source_select(timer, TIMER_SMCFG_TRGSEL_CI0FE0);
-	timer_slave_mode_select(timer, TIMER_SLAVE_MODE_RESTART);
-
 	/* select the master slave mode */
-	timer_master_slave_mode_config(timer, TIMER_MASTER_SLAVE_MODE_ENABLE);
+	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
+	/* TIMER1 update event is used as trigger output */
+	timer_master_output_trigger_source_select(timer,TIMER_TRI_OUT_SRC_CH0); //ch0 as tirgger out to encoder timer
 
     /* auto-reload preload enable */
     timer_auto_reload_shadow_enable(timer);
-    /* clear channel 0 interrupt bit */
+#if 0
+	/* clear channel 0 interrupt bit */
     timer_interrupt_flag_clear(timer, ENC_I_TIMER_INT_FLG);
     /* channel 0 interrupt enable */
     timer_interrupt_enable(timer, ENC_I_TIMER_IRQ_CH);
 	nvic_irq_enable(ENC_I_TIMER_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0);
+#endif
     /* TIMER2 counter enable */
     timer_enable(timer);
 #endif
@@ -180,21 +190,26 @@ __weak void ENC_TIMER_Overflow(void) {
 
 }
 
+__weak void ENC_ABI_IRQHandler(u32 count) {
+
+}
+
+
 void ENC_TIMER_IRQHandler(void) {
 	if (SET == timer_interrupt_flag_get(ENC_TIMER, TIMER_INT_FLAG_UP)) {
 		timer_interrupt_flag_clear(ENC_TIMER, TIMER_INT_FLAG_UP);
 		ENC_TIMER_Overflow();
 	}
+	if (SET == timer_interrupt_flag_get(ENC_TIMER, TIMER_INT_CH2)) {
+		timer_interrupt_flag_clear(ENC_TIMER, TIMER_INT_FLAG_CH2);
+		ENC_ABI_IRQHandler(TIMER_CH2CV(ENC_TIMER));
+	}
 }
 
 
-__weak void ENC_ABI_IRQHandler(void) {
-
-}
-
 void ABI_I_IRQHandler(void) {
 #ifdef ENC_I_IRQ
-	ENC_ABI_IRQHandler();
+	ENC_ABI_IRQHandler(TIMER_CNT(ENC_TIMER));
 #endif
 }
 
@@ -203,7 +218,9 @@ void ENC_I_IRQHandler(void) {
     if(SET == timer_interrupt_flag_get(ENC_I_TIMER, ENC_I_TIMER_INT_FLG)){
         /* clear channel 0 interrupt bit */
         timer_interrupt_flag_clear(ENC_I_TIMER, ENC_I_TIMER_INT_FLG);
-		ENC_ABI_IRQHandler();
+#if 0
+		ENC_ABI_IRQHandler(TIMER_CNT(ENC_TIMER));
+#endif
     }
 #endif
 }

+ 10 - 17
Applications/foc/motor/encoder.c

@@ -372,6 +372,7 @@ bool encoder_get_cali_error(void) {
 static void encoder_sync_pwm_abs(void) {
 	u32 mask = cpu_enter_critical();
 	ENC_COUNT = g_encoder.pwm_count;
+	g_encoder.pwm_start_cnt = g_encoder.pwm_count;
 	g_encoder.last_cnt = g_encoder.pwm_count;
 	g_encoder.est_pll.observer = (float)g_encoder.pwm_count;
 	g_encoder.abi_angle = g_encoder.pwm_angle;
@@ -383,21 +384,16 @@ static void encoder_sync_pwm_abs(void) {
 }
 
 /*I 信号的中断处理,一圈一个中断*/
-static int abi_I_delta = 0xFFFFFFF;
+//static int abi_I_delta = 0xFFFFFFF;
 static int abi_z_count = 0;
-void ENC_ABI_IRQHandler(void) {
-	g_encoder.z_index_cnt = _abi_count();
-	abi_z_count++;
-#if 0
-	if (!g_encoder.b_index_found){
-		encoder_sync_pwm_abs();
-	}
-	if (g_encoder.z_index_cnt > 10 && g_encoder.z_index_cnt < (g_encoder.cpr - 10)) {
-		if (abi_I_delta == 0xFFFFFFF) {
-			abi_I_delta = g_encoder.z_index_cnt;
-		}
-	}
+void ENC_ABI_IRQHandler(u32 count) {
+#ifdef ENCODER_CC_INVERT
+	g_encoder.z_index_cnt = (g_encoder.cpr -1) - count;
 #else
+	g_encoder.z_index_cnt = count;
+#endif
+	abi_z_count++;
+
 	if (g_encoder.z_index_cnt > 10 && g_encoder.z_index_cnt < 50) {
 		g_encoder.align_cnt = -(g_encoder.z_index_cnt - 5);
 	}else if (g_encoder.z_index_cnt > (g_encoder.cpr - 50) && g_encoder.z_index_cnt < (g_encoder.cpr - 10)) {
@@ -405,11 +401,8 @@ void ENC_ABI_IRQHandler(void) {
 	}else {
 		if (g_encoder.z_index_cnt <=10 || g_encoder.z_index_cnt >= (g_encoder.cpr - 10)) {
 			g_encoder.align_cnt = 0;
-		}else if (g_encoder.enc_maybe_err == ENCODER_NO_ERR){
-			abi_I_delta = g_encoder.z_index_cnt;
 		}
 	}
-#endif
 }
 
 /* 编码器AB信号读书溢出处理 */
@@ -492,7 +485,7 @@ float encoder_get_abi_angle(void) {
 
 void encoder_log(void) {
 	sys_debug("pwm %f, abi %f\n", encoder_get_pwm_angle(), encoder_get_abi_angle());
-	sys_debug("pwm count %d, I count %d,%d,%d\n", g_encoder.pwm_count, abi_I_delta, g_encoder.z_index_cnt, abi_z_count);
+	sys_debug("pwm count %d, I count %d,%d,%d\n", g_encoder.pwm_count, g_encoder.pwm_start_cnt, g_encoder.z_index_cnt, abi_z_count);
 	sys_debug("pwm freq %f, err %d, %f, %f\n", enc_get_pwm_freq(), pwm_duty_err, pwm_err_min, pwm_err_max);
 	if (g_encoder.enc_maybe_err) {
 		sys_debug("E:%d,%d,%d,%d,%d,%d\n", enc_test1, enc_test2, enc_test3, enc_cnt, enc_last_cnt, enc_test4);

+ 1 - 0
Applications/foc/motor/encoder.h

@@ -23,6 +23,7 @@ typedef struct {
 	s16   align_cnt; //z 中断的时候的cnt数,需要计算角度的是时候处理这个align
 	s16   align_step;
 	s16   z_index_cnt;
+	s16   pwm_start_cnt;
 	u32   last_us;
 	s8    direction; //motor running dir, 逆时针 正,顺时针负
 	float est_vel_counts; //每秒多少个计数