Просмотр исходного кода

ADC - skalibrowany pomiar napięcia i prądu

k4be 4 лет назад
Родитель
Сommit
e075382200
3 измененных файлов с 77 добавлено и 20 удалено
  1. 19 8
      soft/ads1224.c
  2. 12 2
      soft/display.c
  3. 46 10
      soft/main.c

+ 19 - 8
soft/ads1224.c

@@ -4,8 +4,10 @@
 volatile unsigned char ads1224_read_wait = 0;
 volatile float adc_val;
 volatile unsigned char adc_data_ready;
+unsigned char adc_skip_result = 5;
 
 void ads1224_mux(unsigned char input){
+	cli();
 	if(input&1){
 		PORTB |= ADC_MUX0;
 	} else {
@@ -16,6 +18,8 @@ void ads1224_mux(unsigned char input){
 	} else {
 		PORTB &= ~ADC_MUX1;
 	}
+	adc_skip_result = 10;
+	sei();
 }
 
 void ads1224_init(void){
@@ -35,8 +39,8 @@ void ads1224_init(void){
 }
 
 void ads1224_data_read(void){
-	static unsigned char avg_count = 0;
-	static signed long int buf = 0;
+	static unsigned char adc_avg_count = 0;
+	static signed long int adc_buf = 0;
 	unsigned char i;
 	union {
 		signed long int out;
@@ -55,12 +59,19 @@ void ads1224_data_read(void){
 	PORTB &= ~_BV(PB7);
 	SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPHA);
 	
-	buf += ads1224_out.out >> 8;
-	if(++avg_count == 32){
-		adc_val = buf; // interrupt context!
-		avg_count = 0;
-		buf = 0;
-		adc_data_ready = 1;
+	if(adc_skip_result){
+		adc_skip_result--;
+		adc_buf = 0;
+		adc_avg_count = 0;
+		adc_data_ready = 0;
+	} else {
+		adc_buf += ads1224_out.out >> 8;
+		if(++adc_avg_count == 32){
+			adc_val = adc_buf; // interrupt context!
+			adc_avg_count = 0;
+			adc_buf = 0;
+			adc_data_ready = 1;
+		}
 	}
 	
 	ads1224_read_wait = 1;

+ 12 - 2
soft/display.c

@@ -9,16 +9,26 @@ void disp_num(signed long int val, unsigned char dec){
 	} else {
 		putchar(' ');
 	}
-	if(val > 999999){
+	if(val > 99999999){
 		putchar('!');
 		disp = 1;
 	} else {
-		digit = (val/100000)%10;
+		digit = (val/10000000)%10;
 		if(digit){
 			putchar(digit + '0');
 			disp = 1;
 		} else putchar(' ');
 	}
+	digit = (val/1000000)%10;
+	if(digit || disp){
+		putchar(digit + '0');
+		disp = 1;
+	} else putchar(' ');
+	digit = (val/100000)%10;
+	if(digit || disp){
+		putchar(digit + '0');
+		disp = 1;
+	} else putchar(' ');
 	digit = (val/10000)%10;
 	if(digit || disp){
 		putchar(digit + '0');

+ 46 - 10
soft/main.c

@@ -51,10 +51,12 @@ EEMEM struct settings eep_settings = {
 	.coeff_generator_curr_B = 1310,
 	.coeff_disch_curr_A = 65535.0/20,
 	.coeff_disch_curr_B = 1000,
-	.coeff_volt_A = 1,
-	.coeff_volt_B = 0,
-	.coeff_curr_A = 1,
-	.coeff_curr_B = 0,
+	.coeff_volt_A = 1.55337778893448E-07,
+	.coeff_volt_B = -0.092784032021951,
+	.coeff_curr_A = 9.03353481586364E-08,
+	.coeff_curr_B = -0.124868806047484,
+//	.coeff_curr_A = .001,
+//	.coeff_curr_B = 0,
 };
 
 unsigned int vdac = 0;
@@ -114,9 +116,39 @@ void discharge_on(void){
 	DISCH_ON();
 }
 
+#define MEAS_VOLT	0
+#define MEAS_CURR	1
+
+float meas[2];
+signed long int adc_results[2];
+
+unsigned char adc_process_data(void){
+	static unsigned char adc_channel = AIN1;
+	static signed long int adc;
+	if(adc_data_ready){
+		atomic_set_slint(&adc, adc_val);
+		switch(adc_channel){
+			case AIN1:
+				adc_results[MEAS_VOLT] = adc;
+				meas[MEAS_VOLT] = adc * settings.coeff_volt_A + settings.coeff_volt_B;
+				adc_channel = AIN2;
+				ads1224_mux(AIN2);
+				break;
+			case AIN2: default:
+				adc_results[MEAS_CURR] = adc;
+				meas[MEAS_CURR] = adc * settings.coeff_curr_A + settings.coeff_curr_B;
+				adc_channel = AIN1;
+				ads1224_mux(AIN1);
+				break;
+		}
+		adc_data_ready = 0;
+		return 1;
+	}
+	return 0;
+}
+
 void main(void){
 	unsigned char i=0;
-	static signed long int adc;
 /*	unsigned char state = STATE_DEFAULT;
 	unsigned char oldstate = state;*/
 	
@@ -141,7 +173,7 @@ void main(void){
 	
 	charge_on();
 	set_voltage(12.6);
-	set_charge_curr(1.0);
+	set_charge_curr(.8);
 	
 	for(;;){
 		_delay_ms(1);
@@ -152,11 +184,15 @@ void main(void){
 		}
 		dac_update();
 		
-		if(adc_data_ready){
-			adc_data_ready = 0;
-			atomic_set_slint(&adc, adc_val);
+		if(adc_process_data()){
 			cursor(0,1);
-			disp_num((adc * 1.55337778893448E-07 + -0.092784032021951) * 1000, 3);
+			disp_num(meas[MEAS_VOLT] * 1000, 3);
+			putchar('V');
+			clearline();
+			cursor(0,2);
+			disp_num(meas[MEAS_CURR] * 1000, 3);
+		//	disp_num(adc_results[MEAS_CURR], 0);
+			putchar('A');
 			clearline();
 		}
 //		dac8571_set(++dac1, VOLT_DAC);