k4be il y a 4 ans
Parent
commit
87df55eeed
11 fichiers modifiés avec 265 ajouts et 15 suppressions
  1. 3 0
      ltspice/.gitignore
  2. 1 0
      soft/.gitignore
  3. 5 1
      soft/Makefile
  4. 78 0
      soft/ads1224.c
  5. 21 0
      soft/ads1224.h
  6. 22 6
      soft/display.c
  7. 1 1
      soft/display.h
  8. 113 7
      soft/main.c
  9. 6 0
      soft/main.h
  10. 12 0
      soft/sed1335.c
  11. 3 0
      soft/sed1335.h

+ 3 - 0
ltspice/.gitignore

@@ -0,0 +1,3 @@
+*.log
+*.net
+*.raw

+ 1 - 0
soft/.gitignore

@@ -3,3 +3,4 @@
 *.map
 *.elf
 *.hex
+*.eep

+ 5 - 1
soft/Makefile

@@ -1,5 +1,5 @@
 PRG            = SZM2
-OBJ            = main.o 1wire.o gtext.o sed1335.o ds18b20.o display.o i2c.o dac8571.o
+OBJ            = main.o 1wire.o gtext.o sed1335.o ds18b20.o display.o i2c.o dac8571.o ads1224.o
 MCU_TARGET     = atmega644p
 OPTIMIZE       = -Os
 # -mcall-prologues
@@ -36,6 +36,8 @@ bin:  $(PRG).bin
 srec: $(PRG).srec
 %.hex: %.elf
 	$(OBJCOPY) -j .text -j .data -O ihex $< $@
+%.eep: %.elf
+	$(OBJCOPY) --change-section-lma .eeprom=0 -j .eeprom -O ihex $< $@
 %.srec: %.elf
 	$(OBJCOPY) -j .text -j .data -O srec $< $@
 %.bin: %.elf
@@ -61,3 +63,5 @@ reset:
 	$(AVRDUDE)
 fuses:
 	$(AVRDUDE) -U lfuse:w:0xff:m -U hfuse:w:0x11:m -U efuse:w:0xfd:m -B100
+eeprom: $(PRG).eep
+	$(AVRDUDE) -U eeprom:w:$(PRG).eep -B100

+ 78 - 0
soft/ads1224.c

@@ -0,0 +1,78 @@
+#include "ads1224.h"
+#include "main.h"
+
+volatile unsigned char ads1224_read_wait = 0;
+volatile float adc_val;
+volatile unsigned char adc_data_ready;
+
+void ads1224_mux(unsigned char input){
+	if(input&1){
+		PORTB |= ADC_MUX0;
+	} else {
+		PORTB &= ~ADC_MUX0;
+	}
+	if(input&2){
+		PORTB |= ADC_MUX1;
+	} else {
+		PORTB &= ~ADC_MUX1;
+	}
+}
+
+void ads1224_init(void){
+	// configure pin change interrupt on PB6/PCINT14
+	PCICR |= _BV(PCIE1);
+	PCMSK1 |= _BV(PCINT14);
+	
+	// configure mux outputs
+	DDRB |= ADC_MUX1 | ADC_MUX0; // MUX1 is SS so set it before SPI init!
+	
+	// configure SPI
+	DDRB |= _BV(PB7); // SCK as output
+	SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPHA);
+	SPSR = _BV(SPI2X); // CLK/2
+	
+	ads1224_read_wait = 1;
+}
+
+void ads1224_data_read(void){
+	static unsigned char avg_count = 0;
+	static signed long int buf = 0;
+	unsigned char i;
+	union {
+		signed long int out;
+		unsigned char d[4];
+	} ads1224_out;
+	
+	for(i=3; i>0; i--){
+		while(!(SPSR & _BV(SPIF)));
+		if(i > 1)
+			SPDR = 0;
+		ads1224_out.d[i] = SPDR;
+	}
+	
+	SPCR = 0; // addidtional sck pulse
+	PORTB |= _BV(PB7);
+	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;
+	}
+	
+	ads1224_read_wait = 1;
+}
+
+ISR(PCINT1_vect){
+	PORTB ^= _BV(PB2);
+	if(ads1224_read_wait && !(PINB & _BV(PB6))){
+		ads1224_read_wait = 0;
+		SPDR = 0; // start SPI transaction
+		ads1224_data_read();
+	}
+	PORTB ^= _BV(PB2);
+}
+

+ 21 - 0
soft/ads1224.h

@@ -0,0 +1,21 @@
+#ifndef ADS1224_H
+#define ADS1224_H
+
+#include <avr/io.h>
+
+#define ADC_MUX0 _BV(PB3)
+#define ADC_MUX1 _BV(PB4)
+
+#define AIN1	0
+#define AIN2	1
+#define AIN3	2
+#define AIN4	3
+
+extern volatile float adc_val;
+extern volatile unsigned char adc_data_ready;
+
+void ads1224_data_read(void);
+void ads1224_init(void);
+void ads1224_mux(unsigned char input);
+
+#endif

+ 22 - 6
soft/display.c

@@ -1,7 +1,7 @@
 #include "display.h"
 #include "gtext.h"
 
-void disp_num(signed int val){
+void disp_num(signed long int val, unsigned char dec){
 	unsigned char disp = 0, digit;
 	if(val < 0){
 		putchar('-');
@@ -9,25 +9,41 @@ void disp_num(signed int val){
 	} else {
 		putchar(' ');
 	}
-	digit = val/10000;
-	if(digit){
+	if(val > 999999){
+		putchar('!');
+		disp = 1;
+	} else {
+		digit = (val/100000)%10;
+		if(digit){
+			putchar(digit + '0');
+			disp = 1;
+		} else putchar(' ');
+	}
+	digit = (val/10000)%10;
+	if(digit || disp){
 		putchar(digit + '0');
 		disp = 1;
 	} else putchar(' ');
 	digit = (val/1000)%10;
-	if(digit || disp){
+	if(digit || disp || dec > 2){
 		putchar(digit + '0');
 		disp = 1;
 	} else putchar(' ');
 	digit = (val/100)%10;
-	if(digit || disp){
+	if(dec == 3)
+		putchar(',');
+	if(digit || disp || dec > 1){
 		putchar(digit + '0');
 		disp = 1;
 	} else putchar(' ');
+	if(dec == 2)
+		putchar(',');
 	digit = (val/10)%10;
-	if(digit || disp){
+	if(digit || disp || dec > 0){
 		putchar(digit + '0');
 	} else putchar(' ');
+	if(dec == 1)
+		putchar(',');
 	digit = val%10;
 	putchar(digit + '0');
 }

+ 1 - 1
soft/display.h

@@ -1,4 +1,4 @@
 #pragma once
 
-void disp_num(signed int val);
+void disp_num(signed long int val, unsigned char dec);
 void disp_temp(signed int temp);

+ 113 - 7
soft/main.c

@@ -1,12 +1,14 @@
 #include <avr/io.h>
 #include <util/delay.h>
 #include <avr/pgmspace.h>
+#include <avr/eeprom.h>
 #include "main.h"
 #include "1wire.h"
 #include "gtext.h"
 #include "sed1335.h"
 #include "ds18b20.h"
 #include "dac8571.h"
+#include "ads1224.h"
 
 #include "display.h"
 
@@ -28,12 +30,97 @@ unsigned char getkey(void){
 	return key;
 }
 
+struct settings {
+	float coeff_generator_volt_A;
+	float coeff_generator_volt_B;
+	float coeff_generator_curr_A;
+	float coeff_generator_curr_B;
+	float coeff_disch_curr_A;
+	float coeff_disch_curr_B;
+	float coeff_volt_A;
+	float coeff_volt_B;
+	float coeff_curr_A;
+	float coeff_curr_B;
+};
+
+struct settings settings;
+EEMEM struct settings eep_settings = {
+	.coeff_generator_volt_A = 1597.035901,
+	.coeff_generator_volt_B = 1317.235211,
+	.coeff_generator_curr_A = 65535.0/20,
+	.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,
+};
+
+unsigned int vdac = 0;
+unsigned int cdac = 0;
+
+void dac_update(void){
+	dac8571_set(cdac, CURR_DAC);
+	dac8571_set(vdac, VOLT_DAC);
+}
+
+void set_voltage(float u){
+	vdac = u * settings.coeff_generator_volt_A + settings.coeff_generator_volt_B;
+	dac_update();
+}
+
+void set_charge_curr(float i){
+	cdac = i * settings.coeff_generator_curr_A + settings.coeff_generator_curr_B;
+	dac_update();
+}
+
+void set_discharge_curr(float i){
+	cdac = i * settings.coeff_disch_curr_A + settings.coeff_disch_curr_B;
+	dac_update();
+}
+
+#define CONV_ENABLE _BV(PD5)
+#define DISCH_ENABLE _BV(PD1)
+#define REL_K1 _BV(PD6)
+#define REL_K2 _BV(PD7)
+
+#define K1_ON() {PORTD |= REL_K1;}
+#define K1_OFF() {PORTD &= ~REL_K1;}
+#define K2_ON() {PORTD |= REL_K2;}
+#define K2_OFF() {PORTD &= ~REL_K2;}
+#define POWER_OFF() {PORTD &= ~(CONV_ENABLE | DISCH_ENABLE);}
+#define CONV_ON() {PORTD |= CONV_ENABLE;}
+#define DISCH_ON() {PORTD |= DISCH_ENABLE;}
+
+void output_off(void){
+	cdac = 0;
+	vdac = 0;
+	POWER_OFF();
+	dac_update();
+	K1_OFF();
+	K2_OFF();
+}
+
+void charge_on(void){
+	output_off();
+	K1_ON();
+	CONV_ON();
+}
+
+void discharge_on(void){
+	output_off();
+	K2_ON();
+	DISCH_ON();
+}
+
 void main(void){
 	unsigned char i=0;
+	static signed long int adc;
 /*	unsigned char state = STATE_DEFAULT;
 	unsigned char oldstate = state;*/
-	unsigned int dac1 = 0, dac2 = 32768;
 	
+	eeprom_read_block(&settings, &eep_settings, sizeof(struct settings));
 	
 	OCR2A = 250; // 16ms
 	TCCR2A = _BV(WGM21);
@@ -41,20 +128,39 @@ void main(void){
 	TIMSK2 = _BV(OCIE2A);
 	sei();
 
-	PORTC &= _BV(PC7);
-	DDRB |= _BV(PB2);
+	PORTC &= _BV(PC7);	// KEY
+	DDRB |= _BV(PB2);	// TESTPOINT
+	
+	DDRD |= REL_K1 | REL_K2 | DISCH_ENABLE | CONV_ENABLE;
 	
 	GLCD_Initialize();
 	GLCD_Clear();
+	
+	ads1224_init();
+	ads1224_mux(AIN1);
+	
+	charge_on();
+	set_voltage(12.6);
+	set_charge_curr(1.0);
+	
 	for(;;){
 		_delay_ms(1);
-		if(i = getkey()){
+		if((i = getkey())){
 			cursor(0,0);
-			disp_num(i);
+			disp_num(i, 0);
+			clearline();
+		}
+		dac_update();
+		
+		if(adc_data_ready){
+			adc_data_ready = 0;
+			atomic_set_slint(&adc, adc_val);
+			cursor(0,1);
+			disp_num((adc * 1.55337778893448E-07 + -0.092784032021951) * 1000, 3);
 			clearline();
 		}
-		dac8571_set(++dac1, VOLT_DAC);
-		dac8571_set(++dac2, CURR_DAC);
+//		dac8571_set(++dac1, VOLT_DAC);
+//		dac8571_set(++dac2, CURR_DAC);
 /*		gettemp();
 		control();
 		state = state_processors[state](state);

+ 6 - 0
soft/main.h

@@ -32,5 +32,11 @@ static inline void atomic_set_uint(volatile unsigned int *volatile data, unsigne
 	*data = value;
 	sei();
 }
+static inline void atomic_set_slint(volatile signed long int *volatile data, signed long int value) __attribute__((always_inline));
+static inline void atomic_set_slint(volatile signed long int *volatile data, signed long int value){
+	cli();
+	*data = value;
+	sei();
+}
 
 #endif

+ 12 - 0
soft/sed1335.c

@@ -84,7 +84,9 @@ void GLCD_InitializePorts(void){
 }
 
 void GLCD_WriteData(unsigned char dataToWrite){
+#ifdef SED1335_DISABLE_INT
 	cli();
+#endif
 	SED1335_DATA_PORT = dataToWrite;
 #ifdef SED1335_CS
 	SED1335_CONTROL_PORT &= ~SED1335_CS;
@@ -95,12 +97,16 @@ void GLCD_WriteData(unsigned char dataToWrite){
 #ifdef SED1335_CS
 	SED1335_CONTROL_PORT |= SED1335_CS;
 #endif
+#ifdef SED1335_DISABLE_INT
 	sei();
+#endif
 }
 
 void GLCD_WriteCommand(unsigned char commandToWrite){
 	SED1335_CONTROL_PORT |= SED1335_A0;
+#ifdef SED1335_DISABLE_INT
 	cli();
+#endif
 	SED1335_DATA_PORT = commandToWrite;
 #ifdef SED1335_CS
 	SED1335_CONTROL_PORT &= ~SED1335_CS;
@@ -111,7 +117,9 @@ void GLCD_WriteCommand(unsigned char commandToWrite){
 #ifdef SED1335_CS
 	SED1335_CONTROL_PORT |= SED1335_CS;
 #endif
+#ifdef SED1335_DISABLE_INT
 	sei();
+#endif
 	SED1335_CONTROL_PORT &= ~SED1335_A0;
 }
 
@@ -121,7 +129,9 @@ void GLCD_WriteCommand(unsigned char commandToWrite){
 	SED1335_CONTROL_PORT &= ~SED1335_CS;
 #endif
 	SED1335_CONTROL_PORT |= SED1335_A0;
+#ifdef SED1335_DISABLE_INT
 	cli();
+#endif
 	SED1335_DATA_DIR = 0x00;
 	SED1335_CONTROL_PORT &= ~SED1335_RD;
 	asm("nop");
@@ -130,7 +140,9 @@ void GLCD_WriteCommand(unsigned char commandToWrite){
 #ifdef SED1335_CS
 	SED1335_CONTROL_PORT |= SED1335_CS;
 #endif
+#ifdef SED1335_DISABLE_INT
 	sei();
+#endif
 	SED1335_CONTROL_PORT &= ~SED1335_A0;
 	return tmp;
 }*/

+ 3 - 0
soft/sed1335.h

@@ -42,6 +42,9 @@
 #undef SED1335_CS
 #define SED1335_RES				(1 << PD0)
 
+//disable interrupts when driving LCD
+#undef SED1335_DISABLE_INT
+
 // LCD config values
 #define 	SED1335_M0   			0		//character generator select, 0=cgrom, 1=cgram
 #define 	SED1335_M2   			0		//character height, 0=8px, 1=16px