Bladeren bron

update single shunt

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 4 jaren geleden
bovenliggende
commit
96a8e29749

+ 1 - 1
Applications/app/app.c

@@ -26,7 +26,7 @@ static void _can_report_info(void) {
 	current_samp_t *s = foc_get_current_sample();
 	can_report_phase_current(0x45, F2I(s->Ia * 1000), F2I(s->Ib * 1000), F2I(s->Ic * 1000));
 	//sys_debug("phase current %f %f %f\n", s->Ia, s->Ib, s->Ic);
-	sys_debug("phase offset %d %d %d %d\n", s->adc_offset_a, s->adc_offset_b, s->adc_offset_c, s->adc_offset_ivbus);
+	sys_debug("phase offset %d %d %d\n", s->adc_offset_a, s->adc_offset_b, s->adc_offset_c);
 }
 
 extern void hall_debug_log(void);

+ 33 - 9
Applications/bsp/adc.c

@@ -1,7 +1,7 @@
 #include "bsp/adc.h"
 #include "libs/utils.h"
 #include "os/co_task.h"
-
+#include "libs/logger.h"
 static void _gpio_init(void);
 
 void adc_init(void){
@@ -13,8 +13,11 @@ void adc_init(void){
 
 	rcu_periph_clock_enable(RCU_ADC0);
 	rcu_periph_clock_enable(RCU_ADC1);
-
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 	adc_mode_config(ADC_DAUL_INSERTED_PARALLEL);
+#else
+	adc_mode_config(ADC_MODE_FREE);
+#endif
     /* ADC scan mode function enable */
     adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
     adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
@@ -28,10 +31,15 @@ void adc_init(void){
     /* configure ADC inserted channel length */
     adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 1);
     /* configure ADC inserted channel trigger */
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE	
     adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC_TRIGGER_NONE);
+#else
+	adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC_TRIGGER_PHASE2);
+#endif
     /* configure ADC inserted channel length */
     adc_channel_length_config(ADC1, ADC_INSERTED_CHANNEL, 1);
     /* configure ADC inserted channel */
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE		
     adc_inserted_channel_config(ADC0, 0, U_PHASE_I_CHAN, ADC_SAMPLE_TIME);
     adc_inserted_channel_config(ADC1, 0, V_PHASE_I_CHAN, ADC_SAMPLE_TIME);
 
@@ -42,12 +50,20 @@ void adc_init(void){
 	adc_update_insert_sample_time(ADC1, U_PHASE_I_CHAN, ADC_SAMPLE_TIME);
 	adc_update_insert_sample_time(ADC1, V_PHASE_I_CHAN, ADC_SAMPLE_TIME);
 	adc_update_insert_sample_time(ADC1, W_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-
+#else
+	adc_inserted_channel_config(ADC0, 0, VBUS_I_CHAN, ADC_SAMPLE_TIME);
+	adc_inserted_channel_config(ADC1, 0, VBUS_I_CHAN, ADC_SAMPLE_TIME);
+#endif
     /* ADC external trigger enable */
     adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
     adc_external_trigger_config(ADC1, ADC_INSERTED_CHANNEL, ENABLE);
-    adc_interrupt_enable(ADC0, ADC_INT_EOIC);
-
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
+    adc_interrupt_disable(ADC0, ADC_INT_EOIC);
+	adc_interrupt_disable(ADC1, ADC_INT_EOIC);
+#else
+	adc_interrupt_disable(ADC0, ADC_INT_EOIC);
+	adc_interrupt_disable(ADC1, ADC_INT_EOIC);
+#endif
     /* configure ADC regular channel trigger */
     adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
     adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
@@ -86,14 +102,22 @@ void adc_start_insert_convert(void) {
 		adc_flag_clear(ADC1, ADC_FLAG_EOIC);
 	}
     /* enable ADC interrupt */
-    adc_interrupt_enable(ADC0, ADC_INT_EOIC);
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
+	adc_interrupt_enable(ADC0, ADC_INT_EOIC);
+#else
+	adc_interrupt_enable(ADC1, ADC_INT_EOIC);
+#endif
+
 }
 
 void adc_stop_insert_convert(void) {
 	adc_disable_ext_trigger();
-    /* enable ADC interrupt */
-    adc_interrupt_disable(ADC0, ADC_INT_EOIC);
-
+    /* disable ADC interrupt */
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
+	adc_interrupt_disable(ADC0, ADC_INT_EOIC);
+#else
+	adc_interrupt_disable(ADC1, ADC_INT_EOIC);
+#endif
     /* clear the ADC flag */
     adc_flag_clear(ADC0, ADC_FLAG_EOIC);
 	adc_flag_clear(ADC1, ADC_FLAG_EOIC);

+ 50 - 40
Applications/bsp/adc.h

@@ -23,6 +23,7 @@ inserted ADC 由timer0 ch3触发,
 
 #define ADC_SAMPLE_TIME ADC_SAMPLETIME_7POINT5
 #define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_CH3
+#define ADC_TRIGGER_PHASE2 ADC0_1_EXTTRIG_INSERTED_T1_CH0
 #define ADC_TRIGGER_NONE  ADC0_1_2_EXTTRIG_INSERTED_NONE
 #define ADC_TRIGGER_VBUS ADC0_1_EXTTRIG_INSERTED_T1_CH0
 
@@ -30,67 +31,71 @@ inserted ADC 由timer0 ch3触发,
 #define ADC_RANK_CHANNEL(c)  ((c)<<ISO3_OFFSET | (0)<<IL_OFFSET) 
 #define ADC_CALI_RANK_CHANEL(c)  ((c)<<ISO3_OFFSET | (0)<<IL_OFFSET) 
 static u32 adc0_rank_channels[6] = {
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//1, UW, AC
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//2, VW, BC
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//3, VU, BA
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//4, WU, CA
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//5, WV, CB
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//6, UV, AB
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//1, B, BC
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//2, A, AC 
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//3, C, CA
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//4, B, BA
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//5, A, AB
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//6, C, CB
 };
 static u32 adc1_rank_channels[6] = {
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//1, C
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//2, C
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//3, A
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//4, A
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//5, B
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//5, B
 };
 
 
 static u32 volatile * adc_phase_reg1[6] = {
-	&ADC_IDATA0(ADC0),//1, U
-	&ADC_IDATA0(ADC0),//2, V
-	&ADC_IDATA0(ADC0),//3, V
-	&ADC_IDATA0(ADC0),//4, U
-	&ADC_IDATA0(ADC0),//5, V 
-	&ADC_IDATA0(ADC0),//6, V
+	&ADC_IDATA0(ADC0),//1, B
+	&ADC_IDATA0(ADC0),//2, A
+	&ADC_IDATA0(ADC1),//3, A
+	&ADC_IDATA0(ADC0),//4, B
+	&ADC_IDATA0(ADC1),//5, B 
+	&ADC_IDATA0(ADC1),//6, B
 };
 static u32 volatile * adc_phase_reg2[6] = {
-	&ADC_IDATA0(ADC1),//1, W
-	&ADC_IDATA0(ADC1),//2, W
-	&ADC_IDATA0(ADC1),//3, U
-	&ADC_IDATA0(ADC1),//4, W
-	&ADC_IDATA0(ADC1),//5, W
-	&ADC_IDATA0(ADC1),//6, U
+	&ADC_IDATA0(ADC1),//1, C
+	&ADC_IDATA0(ADC1),//2, C
+	&ADC_IDATA0(ADC0),//3, C
+	&ADC_IDATA0(ADC1),//4, A
+	&ADC_IDATA0(ADC0),//5, A
+	&ADC_IDATA0(ADC0),//6, C
 };
 
 static void __inline adc_phase_current_read(u8 sector, s32 *v1, s32 *v2) {
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE	
 	*v1 = (s32)(*adc_phase_reg1[sector]) ;
 	*v2 = (s32)(*adc_phase_reg2[sector]) ;
+#else
+	*v1 = (s32) ADC_IDATA0(ADC0);
+	*v2 = (s32) ADC_IDATA0(ADC1);
+#endif
 }
 
 
 static void __inline adc_current_sample_config(u8 sector) {
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 	ADC_ISQ(ADC0) = adc0_rank_channels[sector];
 	ADC_ISQ(ADC1) = adc1_rank_channels[sector];
+#endif	
 }
 
 
 static void __inline adc_disable_ext_trigger(void) {   
 	ADC_CTL1(ADC0) &= ~ADC_CTL1_ETEIC;
-	//ADC_CTL1(ADC1) &= ~ADC_CTL1_ETEIC;
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE
+	ADC_CTL1(ADC1) &= ~ADC_CTL1_ETEIC;
+#endif
 }
 
 static void __inline adc_enable_ext_trigger(void) {	
 	ADC_CTL1(ADC0) |= ADC_CTL1_ETEIC;
-	//ADC_CTL1(ADC1) |= ADC_CTL1_ETEIC;
-}
-
-static bool __inline adc_is_trigged_vbus(void) {
-	if ((ADC_CTL1(ADC1) & ADC_TRIGGER_VBUS) == ADC_TRIGGER_VBUS) {
-		return true;
-	}
-	return false;
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE	
+	ADC_CTL1(ADC1) |= ADC_CTL1_ETEIC;
+#endif
 }
 
 /* insert len fixed to 2(IL=1), ISQ2 >> ISQ3*/
@@ -117,28 +122,33 @@ static __inline__ void adc_update_insert_sample_time(u32 adc, uint8_t adc_channe
 
 static __inline__ bool adc_eoic_interrupt(void)
 {
-#if 0
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 	if (ADC_STAT(ADC0) & ADC_STAT_EOIC){
 		return true;
 	}
+#endif
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE
 	if (ADC_STAT(ADC1) & ADC_STAT_EOIC){
 		return true;
 	}
-#else
-	if (ADC_STAT(ADC0) & ADC_STAT_EOIC){
-		return true;
-	}
 #endif
-
-
 	return false;
 }
 
 static __inline__ void adc_clear_irq_flags(void) {
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 	ADC_STAT(ADC0) &= ~((u32) ADC_INT_FLAG_EOIC);
+#else
+	ADC_STAT(ADC0) &= ~((u32) ADC_INT_FLAG_EOIC);
+	ADC_STAT(ADC1) &= ~((u32) ADC_INT_FLAG_EOIC);
+#endif
 }
 
 
+static __inline void adc_update_ext_trigger(u32 trigger) {
+	adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, trigger);
+}
+
 void adc_init(void);
 s32 adc_sample_regular_channel(int chan, int times);
 void adc_start_insert_convert(void);

+ 0 - 2
Applications/bsp/bsp.c

@@ -17,9 +17,7 @@ void bsp_init(void){
 	dbg_periph_enable(DBG_TIMER2_HOLD);
 	cpu_counts_enable();
 	timer_count32_init();
-#if LOG_UART==1
 	shark_uart_init(SHARK_UART0);
-#endif
 	normal_task_timer_init();
 }
 

+ 17 - 6
Applications/bsp/bsp.h

@@ -24,7 +24,7 @@
 #define ADC_CLOCK_MHz (30)
 #define NS_PER_TCLK (8) /* (1/120000000 * 1000000000) */
 #define NS_2_TCLK(ns) ((ns/NS_PER_TCLK) + 1) //ns תΪpwmʹ�õ��Ǹ�TIM��clk count
-#define FOC_PWM_FS (16 * 1000)
+#define FOC_PWM_FS (15 * 1000)
 #define FOC_PWM_period (TIM_CLOCK/FOC_PWM_FS)
 #define FOC_PWM_Half_Period (FOC_PWM_period/2)
 
@@ -33,12 +33,15 @@
 
 
 #define HW_DEAD_TIME_NS  1200
-#define HW_RISE_TIME_NS  50
-#define HW_NOISE_TIME_NS 50
+#define HW_RISE_TIME_NS  500
+#define HW_NOISE_TIME_NS 500
 #define TDead NS_2_TCLK(HW_DEAD_TIME_NS/2)/* ����ʱ�� */ 
 #define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
 #define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
-#define TADC   ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TADC   ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1)/* ADC ����ʱ�� */
+#define TSampleMIN (TADC + TDead*2 + TRise) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
 
 #define START_RAMP_DURATION (1000)//ms
 #define SPEED_SAMPLE_INVAL (100) //ת�Ѳɼ��ļ��,ms
@@ -48,8 +51,8 @@
 #define MAX_CURRENT      50.0F
 
 #define pwm_timer TIMER0
-#define adc_timer TIMER0
-#define aux_timer TIMER0
+#define adc_timer TIMER1
+#define aux_timer TIMER2
 
 #define USER_ITMER_BRAKE 0
 
@@ -57,6 +60,14 @@
 #define ADC_IRQ_PRIORITY 1
 #define HALL_IRQ_PRIORITY 2
 
+
+#define THREE_SHUNTS_SAMPLE 1
+#define ONE_SHUNT_SAMPLE 2
+
+#define SHUNT_NUM THREE_SHUNTS_SAMPLE
+
+//#define ENABLE_AUX_TIMER 1
+
 void bsp_init(void);
 void wdog_reload(void);
 void system_reboot(void);

+ 121 - 45
Applications/bsp/pwm.c

@@ -17,17 +17,27 @@ DMA0 ch4 -> timer0 update event
 */
 
 static void _init_pwm_timer(void);
+#ifdef ENABLE_AUX_TIMER
 static void _init_adc_timer(void);
 static void _init_aux_timer(void);
+#endif
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE
+static void timer0_dma_config(void);
+#endif
 static void _pwm_gpio_config(void);
 static void _gpio_brakein_irq_enable(void);
 
+u16 timer_update_buffer[6] = {0};
+
 void pwm_3phase_init(void){
     _init_pwm_timer();
-    if (pwm_timer != adc_timer) {
-		_init_adc_timer();
-		_init_aux_timer();
-    }
+#ifdef ENABLE_AUX_TIMER
+	_init_adc_timer();
+	_init_aux_timer();
+#endif	
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE	
+	timer0_dma_config();
+#endif	
 	_pwm_gpio_config();
 }
 
@@ -124,7 +134,7 @@ static void _init_pwm_timer(void) {
 
     /* chan3 trigger adc O3CPRE is alwary active high, adc trigger is rising */
     timer_channel_output_config(timer,TIMER_CH_3,&timer_ocintpara);
-    timer_channel_output_pulse_value_config(timer,TIMER_CH_3,half_period);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_3,half_period-1);
     timer_channel_output_mode_config(timer,TIMER_CH_3,TIMER_OC_MODE_PWM1);
     timer_channel_output_shadow_config(timer,TIMER_CH_3,TIMER_OC_SHADOW_ENABLE);
 
@@ -145,25 +155,36 @@ static void _init_pwm_timer(void) {
 #else
 	_gpio_brakein_irq_enable();
 #endif
-	if (pwm_timer != adc_timer){
-    	/* select the master slave mode */
-    	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
-    	/* slave mode selection: enabled when time2 is enable*/
-    	timer_slave_mode_select(timer,TIMER_SLAVE_MODE_EVENT);
-    	timer_input_trigger_source_select(timer,TIMER_SMCFG_TRGSEL_ITI2);
-	}else {
-		timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_DISABLE);
-	}
+
+#ifdef ENABLE_AUX_TIMER
+	/* select the master slave mode */
+	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
+	/* slave mode selection: enabled when time2 is enable*/
+	timer_slave_mode_select(timer,TIMER_SLAVE_MODE_EVENT);
+	timer_input_trigger_source_select(timer,TIMER_SMCFG_TRGSEL_ITI2);
+#endif
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE
+	timer_channel_output_shadow_config(timer,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
+	timer_channel_output_shadow_config(timer,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);
+	timer_channel_output_shadow_config(timer,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);
+	
+	timer_dma_transfer_config(TIMER0, TIMER_DMACFG_DMATA_CH0CV, TIMER_DMACFG_DMATC_3TRANSFER);
+	timer_dma_enable(TIMER0, TIMER_DMA_UPD);
+#else
+	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_DISABLE);
+#endif /* ONE_SHUNT_SAMPLE_1 */
+
 	pwm_enable_channel();
-	//timer_primary_output_config(timer,ENABLE);
 
 	timer_interrupt_disable(timer, TIMER_INT_UP);
 	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_UP);
 	nvic_irq_enable(TIMER0_UP_IRQn, TIMER_UP_IRQ_PRIORITY, 0);	
-	
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE	
     timer_enable(timer);
+#endif
 }
 
+#ifdef ENABLE_AUX_TIMER
 static void _init_adc_timer(void) {
     timer_oc_parameter_struct timer_ocintpara;
     timer_parameter_struct timer_initpara;
@@ -178,23 +199,27 @@ static void _init_adc_timer(void) {
 
     timer_initpara.prescaler        = 0;
     timer_initpara.alignedmode      = TIMER_COUNTER_CENTER_UP;
-    timer_initpara.period          = FOC_PWM_period;
+    timer_initpara.period          = half_period;
     timer_initpara.clockdivision    = TIMER_CKDIV_DIV1;
     timer_initpara.repetitioncounter = 0;
     timer_init(timer,&timer_initpara);
 
-
     timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
     timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
     timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
+	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
     timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
 
     timer_channel_output_config(timer,TIMER_CH_0,&timer_ocintpara);
 
-
-    timer_channel_output_pulse_value_config(timer,TIMER_CH_0,half_period);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_0,half_period-1);
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE	
     timer_channel_output_mode_config(timer,TIMER_CH_0,TIMER_OC_MODE_PWM1);
-    timer_channel_output_shadow_config(timer,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
+#else
+	timer_channel_output_mode_config(timer,TIMER_CH_0,TIMER_OC_MODE_PWM0);
+#endif
+    timer_channel_output_shadow_config(timer,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
 
     /* select the master slave mode */
     timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
@@ -202,28 +227,12 @@ static void _init_adc_timer(void) {
     timer_slave_mode_select(timer,TIMER_SLAVE_MODE_EVENT);
     timer_input_trigger_source_select(timer,TIMER_SMCFG_TRGSEL_ITI2);
 	
-    timer_primary_output_config(timer,ENABLE);
+    //timer_primary_output_config(timer,ENABLE);
 
     /* auto-reload preload enable */
     timer_auto_reload_shadow_enable(timer);
-
-	pwm_disable_channel();
 	
-    timer_enable(timer);
-}
-
-static void _gpio_brakein_irq_enable(void){
-	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_4);
-	exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
-	nvic_irq_enable(EXTI4_IRQn, 4U, 0U);
-	exti_interrupt_flag_clear(EXTI_4);
-	exti_interrupt_enable(EXTI_4);
-
-	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_5);
-	exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
-	nvic_irq_enable(EXTI5_9_IRQn, 4U, 0U);
-	exti_interrupt_flag_clear(EXTI_5);
-	exti_interrupt_enable(EXTI_5);	
+    //timer_enable(timer);
 }
 
 static void _init_aux_timer(void) {
@@ -245,12 +254,62 @@ static void _init_aux_timer(void) {
     /* select the master slave mode */
     timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
     /* timer update event is used as trigger output */
-    timer_master_output_trigger_source_select(timer,TIMER_TRI_OUT_SRC_ENABLE);    
+    timer_master_output_trigger_source_select(timer,TIMER_TRI_OUT_SRC_ENABLE);
+
+	timer_primary_output_config(timer,ENABLE);
+
+	timer_enable(timer);
+}
+
+#endif
+
+#if SHUNT_NUM==ONE_SHUNT_SAMPLE
+static void timer0_dma_config(void)
+{
+    dma_parameter_struct dma_init_struct;
+    rcu_periph_clock_enable(RCU_DMA0);
+
+    /* TIMER0 update */
+    dma_deinit(DMA0, DMA_CH4);
+    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
+    dma_init_struct.memory_addr  = (uint32_t)timer_update_buffer;
+    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
+    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
+    dma_init_struct.number       = 6;
+    dma_init_struct.periph_addr  = (uint32_t)0x40012C4C;
+    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
+    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
+    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
+    dma_init(DMA0, DMA_CH4, &dma_init_struct);
+    dma_circulation_enable(DMA0, DMA_CH4);
+    dma_memory_to_memory_disable(DMA0, DMA_CH4);
+}
+#endif
+
+static void _gpio_brakein_irq_enable(void){
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_4);
+	exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(EXTI4_IRQn, 4U, 0U);
+	exti_interrupt_flag_clear(EXTI_4);
+	exti_interrupt_enable(EXTI_4);
+
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_5);
+	exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(EXTI5_9_IRQn, 4U, 0U);
+	exti_interrupt_flag_clear(EXTI_5);
+	exti_interrupt_enable(EXTI_5);	
 }
 
 
 void pwm_start(void){
-	pwm_update_duty(0, 0, 0, FOC_PWM_Half_Period-1);
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
+	pwm_update_duty(0, 0, 0);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period+1);
+#else
+	pwm_update_duty_dma(0,0,0,0,0,0);
+	dma_channel_enable(DMA0, DMA_CH4);
+	pwm_update_2smaples(FOC_PWM_Half_Period-(2 * TADC + TRise), FOC_PWM_Half_Period-TADC);
+#endif	
 	/* wait for a new PWM period to flush last HF task */
 	timer_flag_clear(pwm_timer, TIMER_FLAG_UP);
 	while ( timer_flag_get(pwm_timer, TIMER_FLAG_UP) == RESET )
@@ -259,13 +318,20 @@ void pwm_start(void){
 	timer_flag_clear(pwm_timer, TIMER_FLAG_UP);
 
 	timer_primary_output_config(pwm_timer,ENABLE);
+#ifdef ENABLE_AUX_TIMER	
+	timer_primary_output_config(adc_timer,ENABLE);
+#endif
 	timer_flag_clear(pwm_timer, TIMER_FLAG_UP);
-	timer_interrupt_enable(pwm_timer, TIMER_INT_UP);
+	//timer_interrupt_enable(pwm_timer, TIMER_INT_UP);
 }
 
 void pwm_stop(void){
+	dma_channel_disable(DMA0, DMA_CH4);
 	timer_primary_output_config(pwm_timer,DISABLE);
-	timer_interrupt_disable(pwm_timer, TIMER_INT_UP);
+#ifdef ENABLE_AUX_TIMER	
+	timer_primary_output_config(adc_timer,DISABLE);
+#endif
+	//timer_interrupt_disable(pwm_timer, TIMER_INT_UP);
 	/* wait for a new PWM period to flush last HF task */
 	timer_flag_clear(pwm_timer, TIMER_FLAG_UP);
 	while ( timer_flag_get(pwm_timer, TIMER_FLAG_UP) == RESET )
@@ -284,12 +350,22 @@ void pwm_enable_output(bool enable) {
 
 /*open low side of the mosfet*/
 void pwm_turn_on_low_side(void)
-{  
-	pwm_update_duty(0, 0, 0, FOC_PWM_Half_Period);
+{
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
+	pwm_update_duty(0, 0, 0);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period+1);
+#else
+	pwm_update_duty_dma(0,0,0,0,0,0);
+	dma_channel_enable(DMA0, DMA_CH4);
+	pwm_update_2smaples(FOC_PWM_Half_Period-(2 * TADC + TRise), FOC_PWM_Half_Period-TADC);
+#endif
 	timer_flag_clear(pwm_timer,TIMER_FLAG_UP);
   	while (timer_flag_get(pwm_timer,TIMER_FLAG_UP) == RESET );
   	/* Main PWM Output Enable */
   	timer_primary_output_config(pwm_timer, ENABLE);
+#ifdef ENABLE_AUX_TIMER	
+	timer_primary_output_config(adc_timer, ENABLE);
+#endif
 }
 
 

+ 27 - 4
Applications/bsp/pwm.h

@@ -15,14 +15,18 @@
 #define ch0_update_duty(duty) 	TIMER_CH0CV(pwm_timer) = (uint32_t)duty
 #define ch1_update_duty(duty) 	TIMER_CH1CV(pwm_timer) = (uint32_t)duty
 #define ch2_update_duty(duty) 	TIMER_CH2CV(pwm_timer) = (uint32_t)duty
-#define update_adc_trigger(time) TIMER_CH3CV(adc_timer) = (uint32_t)time
+#define update_adc_trigger(time) TIMER_CH3CV(pwm_timer) = (uint32_t)time
 
-#define pwm_update_duty(dutyA, dutyB, dutyC, time) \
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
 	do {\
 		ch0_update_duty(dutyA);\
 		ch1_update_duty(dutyB);\
 		ch2_update_duty(dutyC);\
-		update_adc_trigger(time);\
+	}while(0)
+#define pwm_update_2smaples(samp1, samp2) \
+	do { \
+		TIMER_CH3CV(pwm_timer) = (uint32_t)samp1; \
+		TIMER_CH0CV(adc_timer) = (uint32_t)samp2; \
 	}while(0)
 #define update_sample_time(samp1, samp2) do{adc_timer_dma_buf[2] = samp1; adc_timer_dma_buf[0] = samp2;}while(0)
 #define update_distort_chxcv(duty) do {pwm_timer_dma_buf[1] = duty;}while(0)
@@ -30,10 +34,29 @@
 #define enable_pwm_timer_dma() TIMER_DMAINTEN(pwm_timer) |= (uint32_t) TIMER_DMA_CH3D
 #define disable_pwm_timer_dma() TIMER_DMAINTEN(pwm_timer) &= ~((uint32_t) TIMER_DMA_CH3D)
 
-
 #define enable_sample_timer_dma() TIMER_DMAINTEN(adc_timer) |= (uint32_t) TIMER_DMA_CH0D
 #define disable_sample_timer_dma() TIMER_DMAINTEN(adc_timer) &= ~((uint32_t) TIMER_DMA_CH0D)
 
+extern u16 timer_update_buffer[6];
+#define pwm_update_duty_dma(a, b, c, na, nb, nc) \
+	do { \
+		timer_update_buffer[0] = a; \
+		timer_update_buffer[1] = b; \
+		timer_update_buffer[2] = c; \
+		timer_update_buffer[3] = na; \
+		timer_update_buffer[4] = nb; \
+		timer_update_buffer[5] = nc; \
+	}while(0)
+
+#define pwm_clear_updata() \
+	timer_flag_clear(pwm_timer, TIMER_FLAG_UP);
+
+#define pwm_wait_and_clear_updata() \
+	do { \
+		while ( timer_flag_get(pwm_timer, TIMER_FLAG_UP) == RESET ); \
+		timer_flag_clear(pwm_timer, TIMER_FLAG_UP); \
+	}while(0)
+
 void pwm_3phase_init(void);
 void pwm_start(void);
 void pwm_stop(void);

+ 4 - 4
Applications/foc/foc_api.c

@@ -138,7 +138,7 @@ void foc_current_calibrate(void){
 
 	phase_current_init(&g_foc.current_samp);
 	g_foc.current_samp.is_calibrating_offset = true;
-	g_foc.current_samp.sector = SECTOR_1;
+	g_foc.current_samp.sector = SECTOR_5;
 
 	foc_pwm_start(true);
 
@@ -146,14 +146,14 @@ void foc_current_calibrate(void){
 
 	adc_start_insert_convert();
 	while(g_foc.current_samp.offset_sample_count != 0){};
-	
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 	foc_pwm_start(false);
 	cpu_udelay(100);
 	phase_current_init(&g_foc.current_samp);	
-	g_foc.current_samp.sector = SECTOR_5;
+	g_foc.current_samp.sector = SECTOR_1;
 	foc_pwm_start(true);
 	while(g_foc.current_samp.offset_sample_count != 0){};
-
+#endif
 	g_foc.current_samp.is_calibrating_offset = false;
 }
 

+ 20 - 9
Applications/foc/foc_core.c

@@ -150,9 +150,8 @@ void do_motor_foc(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;
-	phase_time_t         phase_time;
-	u32 sample_point;
 
+	pwm_clear_updata();
 	/* 更新电角度 */
 	foc_update_theta(foc);
 	/* 采集相电流 */
@@ -168,14 +167,26 @@ void do_motor_foc(motor_foc_t *foc){
 	/* d-q坐标系到alpha-beta坐标系,输出给svpwm */
 	Rev_Park(&v_dq, foc->motor_stat.theta, &pwm_ab);
 	/* SVPWM,获取三相逆变器的开关时间,用的是pwm1模式,如果是pwm2模式,这个函数需要修改 */
-	svpwm_get_phase_time(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
+	svpwm_get_phase_time(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &c_sample->time, &foc->sector);
 	/* 计算三相电流的采样点 */
-	sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
+	get_phase_sample_point(c_sample, foc->sector);
 	/* 死区补偿 */
-	deadtime_compensation(c_sample, &phase_time);
+	deadtime_compensation(c_sample, &c_sample->time);
 	/* 更新 TIM1的CCR0-2,生成互补pwm, 相电流更新采样点 */
-	pwm_update_duty(phase_time.A, phase_time.B, phase_time.C, sample_point);
-
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE	
+	pwm_update_duty(c_sample->time.A, c_sample->time.B, c_sample->time.C);
+#else
+	pwm_wait_and_clear_updata();
+	pwm_update_duty_dma(c_sample->time.A, c_sample->time.B, c_sample->time.C, c_sample->time.A_next, c_sample->time.B_next, c_sample->time.C_next);
+#endif
+	pwm_update_2smaples(c_sample->time.Samp_p1, c_sample->time.Samp_p2);
+#ifdef ENABLE_AUX_TIMER
+	if (c_sample->time.Samp_p1 < FOC_PWM_Half_Period) {
+		adc_update_ext_trigger(ADC_TRIGGER_PHASE);
+	}else {
+		adc_update_ext_trigger(ADC_TRIGGER_PHASE2);
+	}
+#endif	
 	adc_current_sample_config(c_sample->sector);
 
 	Debug_Log(foc);
@@ -230,8 +241,8 @@ void mc_phase_current_irq(void) {
 	time_measure_start(&g_meas_foc);
 	do_motor_foc(&g_foc);
 	time_measure_end(&g_meas_foc);
-	if (g_meas_foc.intval_time < 66 || g_meas_foc.intval_time > 66) {
-		log_chan_value(1, g_meas_foc.intval_time);
+	if (g_meas_foc.intval_time < 62 || g_meas_foc.intval_time > 62) {
+		//log_chan_value(2, g_meas_foc.intval_time);
 	}
 }
 

+ 13 - 8
Applications/foc/foc_type.h

@@ -38,11 +38,17 @@ typedef struct _motor_s {
 }motor_stat_t;
 
 typedef struct _phase_time {
-	u32 A;
-	u32 B;
-	u32 C;
+	s32 A;
+	s32 B;
+	s32 C;
+	s32 A_next;
+	s32 B_next;
+	s32 C_next;
 	u32 Samp_p1; //单电阻方案两个采样时刻可能不是连续的
 	u32 Samp_p2;
+	u8  sampe_phase_1;
+	u8  sampe_phase_2;
+	u8  boundary3_flags;
 	u32 low;
 	u32 midle;
 	u32 high;
@@ -77,15 +83,14 @@ typedef struct current_sample {
 	s32   adc_offset_a;
 	s32   adc_offset_b;
 	s32   adc_offset_c;
-	s32   adc_offset_ivbus;
 	float Ia;
 	float Ib;
 	float Ic;
-	float   Rds_a; //各相MOS的DS极内阻,在线测量. 单位欧
-	float   Rds_b;
-	float   Rds_c;
-	phase_invert_t vbus_i_invert;
+	float old_Ia;
+	float old_Ib;
+	float old_Ic;
 	u8    sector;
+	phase_time_t time;	
 	volatile int   offset_sample_count;
 	bool  is_calibrating_offset;
 }current_samp_t;

+ 557 - 28
Applications/foc/phase_current.c

@@ -1,5 +1,6 @@
+#include <math.h>
 #include "bsp/adc.h"
-#include "foc_type.h"
+#include "phase_current.h"
 #include "libs/utils.h"
 #include "libs/logger.h"
 
@@ -7,9 +8,9 @@
 
 #define Rvbus  0.0005f
 #define Gvbus (13.1f) //母线电流的运放 
-#define Rds_Defualt  0.005f//欧
+#define Rds_Defualt  0.0025f//欧
 #define Gmos  (1.7f)//mos 电流的运放
-#define Sample_R Rds_Defualt
+#define Sample_R Rvbus
 #define Lower_Pass_p 0.2f
 
 #define VBUS_VOL(adc) (((float)(adc)) * 3.3f / 4096.0f / Gvbus)
@@ -22,8 +23,8 @@ void phase_current_init(current_samp_t *cs) {
 }
 
 
+#if SHUNT_NUM==THREE_SHUNTS_SAMPLE
 void phase_current_offset(current_samp_t *cs) {
-#if 1
 	s32 phase_current1, phase_current2;
 	adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
 	if (cs->offset_sample_count > 0) {
@@ -43,65 +44,593 @@ void phase_current_offset(current_samp_t *cs) {
 			}
 		}
 	}
-#else
-	cs->adc_offset_a = adc_sample_regular_channel(U_PHASE_I_CHAN, 16);
-	cs->adc_offset_a = adc_sample_regular_channel(U_PHASE_I_CHAN, 64);
-
-	cs->adc_offset_b = adc_sample_regular_channel(V_PHASE_I_CHAN, 64);
-	cs->adc_offset_c = adc_sample_regular_channel(W_PHASE_I_CHAN, 64);
-#endif
 }
 
 void phase_current_sample(current_samp_t *cs){
 	s32 phase_current1, phase_current2;
 	adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
-	if (cs->sector == SECTOR_1 || cs->sector == SECTOR_2) {
+	if (cs->sector == SECTOR_4 || cs->sector == SECTOR_5) {
 		/* Current on Phase C is not accessible */
 		/* Ia = PhaseAOffset - ADC converted value) */
-		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), Sample_R);
-		cs->Ia = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_a), Sample_R);
+		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), Rds_Defualt);
+		cs->Ia = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_a), Rds_Defualt);
 		cs->Ic = -(cs->Ia + cs->Ib);
-	}else if (cs->sector == SECTOR_3 || cs->sector == SECTOR_4) {
+	}else if (cs->sector == SECTOR_1 || cs->sector == SECTOR_6) {
 		/* Current on Phase A is not accessible 	*/
 		/* Ib = PhaseBOffset - ADC converted value) */
-		cs->Ic = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_c), Sample_R);
-		cs->Ib = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_b), Sample_R);
+		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), Rds_Defualt);
+		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), Rds_Defualt);
 		cs->Ia = -(cs->Ib + cs->Ic);
-	}else if (cs->sector == SECTOR_5 || cs->sector == SECTOR_6) {
+	}else if (cs->sector == SECTOR_2 || cs->sector == SECTOR_3) {
 		/* Current on Phase B is not accessible 	*/
 		/* Ia = PhaseAOffset - ADC converted value) */
-		cs->Ia = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_a), Sample_R);
-		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), Sample_R);
+		cs->Ia = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_a), Rds_Defualt);
+		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), Rds_Defualt);
 		cs->Ib = -(cs->Ia + cs->Ic);
 	}
-	//log_chan_value(1, (int)(cs->Ia * 1000));
+	{
+		static int count = 0;
+		if (count++ % 3 == 0) {
+			log_chan_value(1, (int)(cs->Ia * 1000));
+		}
+	}
+
 }
 
 
-u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector){
-	u32 low_side_low_duty = FOC_PWM_Half_Period - time->low;	
+void get_phase_sample_point(current_samp_t *cs, u8 sector){
+	phase_time_t *time = &cs->time;
+	u32 low_side_low_duty = FOC_PWM_Half_Period - time->low;
+#if 0	
+	u32 low_side_mid_duty = FOC_PWM_Half_Period - time->midle;
 	cs->sector = sector;
-	//duty > deadtime + max(Rise time, Noise time)
+	time->Samp_p1 = FOC_PWM_Half_Period + 1;
+	time->Samp_p2 = FOC_PWM_Half_Period + 1;	
+	/*底边开mos的时间是2倍的 low_side_low_duty(一个周期)*/
+	if (low_side_low_duty * 2 >= TSampleMIN) { //可以采样
+		if (low_side_low_duty >= (TADC + TDead)) {//可以在pwm的中心点采样
+			time->Samp_p1 = FOC_PWM_Half_Period - 1;
+		}else {
+			u32 Samp_p = time->low + TSampleBefore;
+			if (Samp_p >= FOC_PWM_Half_Period) { //需要在pwm中心点过后采样,需要配置PWM0模式
+				time->Samp_p2 = ( 2u * FOC_PWM_Half_Period ) - Samp_p - (uint16_t) 1;
+			}else {
+				time->Samp_p1 = Samp_p;
+			}
+		}
+	}else if (low_side_mid_duty * 2 >= TSampleMIN){
+		if (low_side_mid_duty >= (TADC + TDead)) {//可以在pwm的中心点采样
+			time->Samp_p1 = FOC_PWM_Half_Period - 1;
+		}else {
+			u32 Samp_p = time->midle + TSampleBefore;
+			if (Samp_p >= FOC_PWM_Half_Period) { //需要在pwm中心点过后采样,需要配置PWM0模式
+				time->Samp_p2 = ( 2u * FOC_PWM_Half_Period ) - Samp_p - (uint16_t) 1;		
+			}else {
+				time->Samp_p1 = Samp_p;
+			}
+		}		
+	}else {
+		//not reached there
+		sys_debug("ERROR!!!!!\n");
+	}
+#else	
 	if (low_side_low_duty > (TDead + MAX(TRise, TNoise))) {
 		cs->sector = SECTOR_1;
-		return FOC_PWM_Half_Period - 1;
+		time->Samp_p1 =  time->low + MAX(TRise, TNoise);
 	}else {
-		log_chan_value(2, 111);
 		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;
+			time->Samp_p1 =  time->low - TADC;
 		}else {
 			u32 sample_point = time->low + (TDead + MAX(TRise, TNoise));
 			if (sample_point >= FOC_PWM_Half_Period) {
 				//这里需要修改触发方式,GD不支持adc设置上升或下降沿触发,考虑切换pwm模式???
 				sample_point = ( 2u * FOC_PWM_Half_Period ) - sample_point - (uint16_t) 1;		
 			}
-			return sample_point;
+			time->Samp_p1 =  sample_point;
 		}
 	}
+#endif	
+}
+#else
+
+#define TBEFOR (TDead + MAX(TRise, TNoise))
+#define TMIN (TDead + MAX(TRise, TNoise) + TADC)
+
+static __inline u8 _get_sample_boundary(current_samp_t *cs, phase_time_t *time) {
+#if 0
+	s32 delta_duty0 = (s32)time->midle - (s32)time->high;
+	s32 delta_duty1 = (s32)time->low - (s32)time->midle;
+
+	if (delta_duty0 <= TMIN && delta_duty1 <= TMIN) {
+		return BOUNDARY_3;
+	}else if (delta_duty0 <= TMIN && delta_duty1 > TMIN) {
+		return BOUNDARY_2;
+	}else if (delta_duty0 > TMIN && delta_duty1 <= TMIN) {
+		return BOUNDARY_1;
+	}else {
+		return REGULAR;
+	}
+#else
+	return REGULAR;
+#endif
+}
+
+static __inline void _get_boundary1_samp(current_samp_t *cs, phase_time_t *time) {
+	s32 delta_duty1 = (s32)time->low - (s32)time->midle;
+	s32 delta_time_inc = (TMIN - delta_duty1);
+	s32 delta_time_dec = min(delta_time_inc, delta_duty1);
+	s32 sample_p;
+	switch(cs->sector) {
+		case SECTOR_1: //AB big and delta small
+			time->Samp_p1 = time->B - TADC;
+			sample_p = time->A;
+			time->A = sample_p + delta_time_inc;
+			time->A_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->A - TADC;
+			time->sampe_phase_1 = SAMP_NIC;
+			time->sampe_phase_2 = SAMP_IA;
+			break;
+		case SECTOR_2://BA big and delta small
+			time->Samp_p1 = time->A - TADC;
+			sample_p = time->B;
+			time->B = sample_p + delta_time_inc;
+			time->B_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->B - TADC;
+			time->sampe_phase_1 = SAMP_NIC;
+			time->sampe_phase_2 = SAMP_IB;		
+			break;
+		case SECTOR_3://BC big and delta small
+			time->Samp_p1 = time->C - TADC;
+			sample_p = time->B;
+			time->B = sample_p + delta_time_inc;
+			time->B_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->B - TADC;
+			time->sampe_phase_1 = SAMP_NIA;
+			time->sampe_phase_2 = SAMP_IB;				
+			break;
+		case SECTOR_4://CB big and delta small
+			time->Samp_p1 = time->B - TADC;
+			sample_p = time->C;
+			time->C = sample_p + delta_time_inc;
+			time->C_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->C - TADC;
+			time->sampe_phase_1 = SAMP_NIA;
+			time->sampe_phase_2 = SAMP_IC;			
+			break;
+		case SECTOR_5://CA big and delta small
+			time->Samp_p1 = time->A - TADC;
+			sample_p = time->C;
+			time->C = sample_p + delta_time_inc;
+			time->C_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->C - TADC;
+			time->sampe_phase_1 = SAMP_NIB;
+			time->sampe_phase_2 = SAMP_IC;			
+			break;
+		case SECTOR_6://AC big and delta small
+			time->Samp_p1 = time->C - TADC;
+			sample_p = time->A;
+			time->A = sample_p + delta_time_inc;
+			time->A_next = sample_p - delta_time_dec;
+			time->Samp_p2 = time->A - TADC;
+			time->sampe_phase_1 = SAMP_NIB;
+			time->sampe_phase_2 = SAMP_IA;				
+			break;
+		default:
+			break;
+	}
+}
+
+static __inline void _get_boundary2_samp(current_samp_t *cs, phase_time_t *time) {
+	s32 delta_duty0 = (s32)time->midle - (s32)time->high;
+	s32 delta_time_dec = (TMIN - delta_duty0);
+	s32 delta_time_inc = min(delta_time_dec, delta_duty0);
+	s32 sample_p;
+	switch(cs->sector) {
+		case SECTOR_1: //BC samll and delta small
+			time->Samp_p2 = time->A - TADC;
+			sample_p = time->C;
+			time->C = sample_p - delta_time_dec;
+			time->C_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->B - TADC;
+			time->sampe_phase_2 = SAMP_IA;
+			time->sampe_phase_1 = SAMP_NIC;		
+			break;
+		case SECTOR_2://AC samll and delta small
+			time->Samp_p2 = time->B - TADC;
+			sample_p = time->C;
+			time->C = sample_p - delta_time_dec;
+			time->C_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->A - TADC;
+			time->sampe_phase_2 = SAMP_IB;
+			time->sampe_phase_1 = SAMP_NIC;			
+			break;
+		case SECTOR_3://CA samll and delta small
+			time->Samp_p2 = time->B - TADC;
+			sample_p = time->A;
+			time->A = sample_p - delta_time_dec;
+			time->A_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->C - TADC;
+			time->sampe_phase_2 = SAMP_IB;
+			time->sampe_phase_1 = SAMP_NIA;				
+			break;
+		case SECTOR_4://BA samll and delta small
+			time->Samp_p2 = time->C - TADC;
+			sample_p = time->A;
+			time->A = sample_p - delta_time_dec;
+			time->A_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->B - TADC;
+			time->sampe_phase_2 = SAMP_IC;
+			time->sampe_phase_1 = SAMP_NIA;			
+			break;
+		case SECTOR_5://AB samll and delta small
+			time->Samp_p2 = time->C - TADC;
+			sample_p = time->B;
+			time->B = sample_p - delta_time_dec;
+			time->B_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->A - TADC;
+			time->sampe_phase_2 = SAMP_IC;
+			time->sampe_phase_1 = SAMP_NIB;			
+			break;
+		case SECTOR_6://CB samll and delta small
+			time->Samp_p2 = time->A - TADC;
+			sample_p = time->B;
+			time->B = sample_p - delta_time_dec;
+			time->B_next = sample_p + delta_time_inc;
+			time->Samp_p1 = time->C - TADC;
+			time->sampe_phase_2 = SAMP_IA;
+			time->sampe_phase_1 = SAMP_NIB;			
+			break;
+		default:
+			break;
+	}
+
+}
+
+
+static __inline void _get_boundary3_samp(current_samp_t *cs, phase_time_t *time) {
+#if 1
+	s32 sample_p;
+	if ((time->boundary3_flags & 1) == 0) {
+		time->boundary3_flags |= 1;
+		sample_p = time->A;
+		time->A = sample_p + TMIN;
+		time->A_next = sample_p - TMIN;
+		time->Samp_p1 = time->A - (2 * TADC + TRise);//dumy trigger
+		time->Samp_p2 = time->A - TADC;
+		time->sampe_phase_1 = SAMP_OLDB;
+		time->sampe_phase_2 = SAMP_IA;			
+	}else {
+		time->boundary3_flags &= ~1;
+		sample_p = time->B;
+		time->B = sample_p + TMIN;
+		time->B_next = sample_p - TMIN;
+		time->Samp_p1 = time->B - (2 * TADC + TRise);//dumy trigger
+		time->Samp_p2 = time->B - TADC;
+		time->sampe_phase_1 = SAMP_OLDA;
+		time->sampe_phase_2 = SAMP_IB;			
+	}
+#else
+	s32 delta_duty0 = (s32)time->midle - (s32)time->high;
+	s32 delta_duty1 = (s32)time->low - (s32)time->midle;
+
+	s32 delta_time_inc1 = (TMIN - delta_duty1);
+	s32 delta_time_dec1 = min(delta_time_inc1, delta_duty1);
+	
+	s32 delta_time_dec2 = (TMIN - delta_duty0);
+	s32 delta_time_inc2 = min(delta_time_dec2, delta_duty0);
+
+	s32 sample_p;
+	switch(cs->sector) {
+		case SECTOR_1: //deltaBC > deltaAB
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->C;
+				time->C = sample_p - delta_time_dec2;
+				time->C_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->B - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->B - TADC;
+				time->sampe_phase_1 = SAMP_OLDB;
+				time->sampe_phase_2 = SAMP_NIC;					
+			}else {
+				sample_p = time->A;
+				time->A = sample_p + delta_time_inc1;
+				time->A_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->A - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->A - TADC;
+				time->sampe_phase_1 = SAMP_OLDC;
+				time->sampe_phase_2 = SAMP_IA;						
+			}
+			break;
+		case SECTOR_2: //deltaAC > deltaBA
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->C;
+				time->C = sample_p - delta_time_dec2;
+				time->C_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->A - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->A - TADC;
+				time->sampe_phase_1 = SAMP_OLDA;
+				time->sampe_phase_2 = SAMP_NIC;					
+			}else {
+				sample_p = time->B;
+				time->B = sample_p + delta_time_inc1;
+				time->B_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->B - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->B - TADC;
+				time->sampe_phase_1 = SAMP_OLDB;
+				time->sampe_phase_2 = SAMP_IB;						
+			}	
+			break;
+		case SECTOR_3: //deltaCA > deltaBC
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->A;
+				time->A = sample_p - delta_time_dec2;
+				time->A_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->C - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->C - TADC;
+				time->sampe_phase_1 = SAMP_OLDC;
+				time->sampe_phase_2 = SAMP_NIA;					
+			}else {
+				sample_p = time->B;
+				time->B = sample_p + delta_time_inc1;
+				time->B_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->B - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->B - TADC;
+				time->sampe_phase_1 = SAMP_OLDA;
+				time->sampe_phase_2 = SAMP_IB;						
+			}		
+			break;
+		case SECTOR_4: //CBA, //deltaBA > deltaCB
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->A;
+				time->A = sample_p - delta_time_dec2;
+				time->A_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->B - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->B - TADC;
+				time->sampe_phase_1 = SAMP_OLDB;
+				time->sampe_phase_2 = SAMP_NIA;					
+			}else {
+				sample_p = time->C;
+				time->C = sample_p + delta_time_inc1;
+				time->C_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->C - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->C - TADC;
+				time->sampe_phase_1 = SAMP_OLDC;
+				time->sampe_phase_2 = SAMP_IC;						
+			}	
+			break;
+		case SECTOR_5: //CAB, //deltaAB > deltaCA
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->B;
+				time->B = sample_p - delta_time_dec2;
+				time->B_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->A - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->A - TADC;
+				time->sampe_phase_1 = SAMP_OLDA;
+				time->sampe_phase_2 = SAMP_NIB;					
+			}else {
+				sample_p = time->C;
+				time->C = sample_p + delta_time_inc1;
+				time->C_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->C - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->C - TADC;
+				time->sampe_phase_1 = SAMP_OLDB;
+				time->sampe_phase_2 = SAMP_IC;						
+			}		
+			break;
+		case SECTOR_6: //ACB, //deltaCB > deltaAC
+			if (delta_duty0 > delta_duty1) {
+				sample_p = time->B;
+				time->B = sample_p - delta_time_dec2;
+				time->B_next = sample_p + delta_time_inc2;
+				time->Samp_p1 = time->C - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->C - TADC;
+				time->sampe_phase_1 = SAMP_OLDC;
+				time->sampe_phase_2 = SAMP_NIB;					
+			}else {
+				sample_p = time->A;
+				time->A = sample_p + delta_time_inc1;
+				time->A_next = sample_p - delta_time_dec1;	
+				time->Samp_p1 = time->A - (2 * TADC + TRise);//dumy trigger
+				time->Samp_p2 = time->A - TADC;
+				time->sampe_phase_1 = SAMP_OLDA;
+				time->sampe_phase_2 = SAMP_IA;						
+			}		
+			break;
+		default:
+			break;
+	}
+#endif
 }
 
+static __inline void _get_regular_samp(current_samp_t *cs, phase_time_t *time) {
+	time->Samp_p1 = time->midle - TADC;
+	time->Samp_p2 = time->low - TADC;
+	switch(cs->sector) {
+		case SECTOR_1: //ABC
+			time->sampe_phase_1 = SAMP_NIC;
+			time->sampe_phase_2 = SAMP_IA;	
+			break;
+		case SECTOR_2: //BAC
+			time->sampe_phase_1 = SAMP_NIC;
+			time->sampe_phase_2 = SAMP_IB;		
+			break;
+		case SECTOR_3: //BCA
+			time->sampe_phase_1 = SAMP_NIA;
+			time->sampe_phase_2 = SAMP_IB;		
+			break;
+		case SECTOR_4: //CBA
+			time->sampe_phase_1 = SAMP_NIA;
+			time->sampe_phase_2 = SAMP_IC;		
+			break;
+		case SECTOR_5: //CAB
+			time->sampe_phase_1 = SAMP_NIB;
+			time->sampe_phase_2 = SAMP_IC;		
+			break;
+		case SECTOR_6: //ACB
+			time->sampe_phase_1 = SAMP_NIB;
+			time->sampe_phase_2 = SAMP_IA;		
+			break;
+		default:
+			break;
+	}
+
+}
+
+void phase_current_offset(current_samp_t *cs) {
+	s32 phase_current1, phase_current2;
+	adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
+	if (cs->offset_sample_count > 0) {
+		cs->offset_sample_count--;
+		if (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;
+			}
+		}
+	}
+}
+
+void phase_current_sample(current_samp_t *cs){
+	s32 phase_current1, phase_current2;
+	u8  b_curr_a = 0;
+	u8  b_curr_b = 0;
+	u8  b_curr_c = 0;
+	phase_time_t *time = &cs->time;
+	adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
+	phase_current1 -= cs->adc_offset_a;
+	phase_current2 -= cs->adc_offset_b;
+	float current = current_i(VBUS_VOL(abs(phase_current1)), Sample_R);
+	switch (time->sampe_phase_1) {
+		case SAMP_IA:
+			cs->Ia = current;
+			b_curr_a = 1;
+			break;
+		case SAMP_IB:
+			cs->Ib = current;
+			b_curr_b = 1;
+			break;
+		case SAMP_IC:
+			cs->Ic = current;
+			b_curr_c = 1;
+			break;
+		case SAMP_NIA:
+			cs->Ia = -current;
+			b_curr_a = 1;
+			break;
+		case SAMP_NIB:
+			cs->Ib = -current;
+			b_curr_b = 1;
+			break;
+		case SAMP_NIC:
+			cs->Ic = -current;
+			b_curr_c = 1;
+			break;		
+		case SAMP_OLDA:
+			cs->Ia = cs->old_Ia;
+			b_curr_a = 1;
+			break;
+		case SAMP_OLDB:
+			cs->Ib = cs->old_Ib;
+			b_curr_b = 1;
+			break;
+		case SAMP_OLDC:
+			cs->Ic = cs->old_Ic;
+			b_curr_c = 1;
+			break;
+		default:
+			break;
+	}
+
+	current = current_i(VBUS_VOL(abs(phase_current2)), Sample_R);
+
+	switch (time->sampe_phase_2) {
+		case SAMP_IA:
+			cs->Ia = current;
+			b_curr_a = 1;
+			break;
+		case SAMP_IB:
+			cs->Ib = current;
+			b_curr_b = 1;
+			break;
+		case SAMP_IC:
+			cs->Ic = current;
+			b_curr_c = 1;
+			break;
+		case SAMP_NIA:
+			cs->Ia = -current;
+			b_curr_a = 1;
+			break;
+		case SAMP_NIB:
+			cs->Ib = -current;
+			b_curr_b = 1;
+			break;
+		case SAMP_NIC:
+			cs->Ic = -current;
+			b_curr_c = 1;
+			break;		
+		case SAMP_OLDA:
+			cs->Ia = cs->old_Ia;
+			b_curr_a = 1;
+			break;
+		case SAMP_OLDB:
+			cs->Ib = cs->old_Ib;
+			b_curr_b = 1;
+			break;
+		case SAMP_OLDC:
+			cs->Ic = cs->old_Ic;
+			b_curr_c = 1;
+			break;
+		default:
+			break;
+	}
+	if (b_curr_a == 0) {
+		cs->Ia = -(cs->Ib + cs->Ic);
+	}
+	if (b_curr_b == 0) {
+		cs->Ib = -(cs->Ia + cs->Ic);
+	}
+	if (b_curr_c == 0) {		
+		cs->Ic = -(cs->Ia + cs->Ib);
+	}
+	cs->old_Ia = cs->Ia;
+	cs->old_Ib = cs->Ib;
+	cs->old_Ic = cs->Ic;
+	{
+		static int count = 0;
+		if (count++ % 3 == 0) {
+			log_chan_value(1, (int)(cs->Ia * 1000));
+		}
+	}
+}
+
+
+void get_phase_sample_point(current_samp_t *cs, u8 sector){
+	phase_time_t *time = &cs->time;
+	if (cs->is_calibrating_offset) {
+		time->Samp_p1 = FOC_PWM_Half_Period - 2 * TMIN;
+		time->Samp_p2 = FOC_PWM_Half_Period - 1;
+		return;
+	}
+	cs->sector = sector;
+	time->A_next = time->A;
+	time->B_next = time->B;
+	time->C_next = time->C;
+	u8 boundary = _get_sample_boundary(cs, time);
+	if (boundary == BOUNDARY_1) {
+		_get_boundary1_samp(cs, time);
+	}else if (boundary == BOUNDARY_2) {
+		_get_boundary2_samp(cs, time);
+	}else if (boundary == BOUNDARY_3) {
+		_get_boundary3_samp(cs, time);
+	}else { //REGULAR, 直接可以采样
+		_get_regular_samp(cs, time);
+	}
+}
+
+#endif
 void phase_current_adc_triger(current_samp_t *cs){
 	
 	//adc_enable_ext_trigger();

+ 19 - 1
Applications/foc/phase_current.h

@@ -1,10 +1,28 @@
 #ifndef _PHASE_CURRENT_H__
 #define _PHASE_CURRENT_H__
 #include "foc_type.h"
+/* boundary zone definition */
+#define REGULAR         ((uint8_t)0u)
+#define BOUNDARY_1      ((uint8_t)1u)  /* Two small, one big */
+#define BOUNDARY_2      ((uint8_t)2u)  /* Two big, one small */
+#define BOUNDARY_3      ((uint8_t)3u)  /* Three equal        */
+
+#define SAMP_NO 0u
+#define SAMP_IA 1u
+#define SAMP_IB 2u
+#define SAMP_IC 3u
+#define SAMP_NIA 4u
+#define SAMP_NIB 5u
+#define SAMP_NIC 6u
+#define SAMP_OLDA 7u
+#define SAMP_OLDB 8u
+#define SAMP_OLDC 9u
+
+
 void phase_current_init(current_samp_t *cs);
 void phase_current_sample(current_samp_t *cs);
 void phase_current_offset(current_samp_t *cs);
-u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector);
+void get_phase_sample_point(current_samp_t *cs, u8 sector);
 void phase_current_adc_triger(current_samp_t *cs);
 #endif /* _PHASE_CURRENT_H__ */
 

BIN
Simulink/BLDCmotor_FOC_R2017b_fixdt.slxc


BIN
Simulink/DQSVPWM.slx


BIN
Simulink/FOC.slx