Hanna
Sourcecode Batteriemanagementsystem
ad7997.c
gehe zur Dokumentation dieser Datei
1 
14 #include <stdio.h>
15 #include <stdint.h>
16 #include <avr/io.h>
17 #include <avr/interrupt.h>
18 #include <util/delay.h>
19 #include <stdbool.h>
20 
21 #include "twi_master_driver.h"
22 #include "temp_mcp9843.h"
23 #include "ds1388_rtc.h"
24 #include "ad7997.h"
25 #include "general.h"
26 #include "bms_mosfet.h"
27 #include "BMS-Basic.h"
28 
29 TWI_Master_t twiAD7997;
30 
31 int16_t current[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
32 float voltage[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
33 
34 uint8_t bat_nummer2channel[8] = { BAT_NUMMER2CHANNEL_1_1, BAT_NUMMER2CHANNEL_1_2, BAT_NUMMER2CHANNEL_1_3, BAT_NUMMER2CHANNEL_1_4, BAT_NUMMER2CHANNEL_2_1, BAT_NUMMER2CHANNEL_2_2,
35 BAT_NUMMER2CHANNEL_2_3, BAT_NUMMER2CHANNEL_2_4 };
36 
75 void AD7997_init ( void )
76 {
77  TWI_MasterInit ( &twiAD7997, &TWIC, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING ); // TWI Master (PortC) für AD7997 initialisieren
78 
79  PORTA.DIRCLR = I_SGN_1_1 | I_SGN_1_2 | I_SGN_1_3 | I_SGN_1_4 | I_SGN_2_1 | I_SGN_2_2 | I_SGN_2_3 | I_SGN_2_4;
80 
81  AD7997_ADC1_CONVST_PORT.DIRSET = AD7997_ADC1_CONVST_PIN_bm; // CONVST ADC1
82  AD7997_ADC1_CONVST_PORT.AD7997_ADC1_CONVST_PIN_CTRL = PORT_OPC_TOTEM_gc;
83  AD7997_ADC1_CONVST_PORT.OUTCLR = AD7997_ADC1_CONVST_PIN_bm;
84 
85  // Interrupt enable
86  PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm; // enable interrupt levels
87  sei();
88 
89  sendRegData[0] = AD7997_CONFIG_REG;
90  sendRegData[1] = AD7997_CONFIG_MSB;
91  sendRegData[2] = AD7997_CONFIG_LSB;
92  TWI_MasterWrite ( &twiAD7997, AD7997_ADC2_I, &sendRegData[0], 3 );
93  sendRegData[0] = AD7997_CTIMER_REG;
94  sendRegData[1] = AD7997_CTIMER_bm;
95  TWI_MasterWrite ( &twiAD7997, AD7997_ADC2_I, &sendRegData[0], 2 );
96 
97  sendRegData[0] = AD7997_CONFIG_REG;
98  sendRegData[1] = AD7997_CONFIG_MSB;
99  sendRegData[2] = AD7997_CONFIG_LSB;
100  TWI_MasterWrite ( &twiAD7997, AD7997_ADC1_V, &sendRegData[0], 3 );
101  sendRegData[0] = AD7997_CTIMER_REG;
102  sendRegData[1] = AD7997_CTIMER_bm;
103  TWI_MasterWrite ( &twiAD7997, AD7997_ADC1_V, &sendRegData[0], 2 );
104 }
105 
129 {
130 
131  uint16_t reg_current[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
132 
133  for ( int battery_nr = 0; battery_nr < 8; battery_nr++ )
134  {
135  sendRegData[0] = AD7997_READ_SINGLE | (bat_nummer2channel[battery_nr] << 4); // Datenblatt S. 29 Read Cmd für Einzelkanal
136  TWI_MasterWrite ( &twiAD7997, AD7997_ADC2_I, &sendRegData[0], 1 );
137  _delay_us ( 3 ); // Datenblatt S. 29 Wake-up and conversion Time
138  TWI_MasterRead ( &twiAD7997, AD7997_ADC2_I, 2 );
139 
140  reg_current[battery_nr] = ((((uint8_t) twiAD7997.readData[0]) << 8) | ((uint8_t) twiAD7997.readData[1])) >> 2; // 10bit ADC, 1-0 LSB immer 0 => (MSB << 8 & LSB) >> 2
141  reg_current[battery_nr] &= AD7997_RESULT_FLT; // Ergebnis plain binary, filtern mit AD7997_RESULT_FLT
142  current[battery_nr] = (((reg_current[battery_nr] * (REF_VOLTAGE / ADC_RES) * 10.0) / R_MESS) * AD7997_current_vorzeichen ( battery_nr ));
143  }
144 
145  einlese_zeit[ALTE_ZEIT] = einlese_zeit[NEUE_ZEIT];
147  einlese_zeit[NEUE_ZEIT] = now.seconds;
148 
149 // DEBUG
150 // for ( int battery_nr = 0; battery_nr <= 7; battery_nr++ )
151 // {
152 // printf ( "## \x1B[1;33m %02i \x1B[0m\r\n", battery_nr );
153 // printf ( "Direct Voltage : \x1B[1;32m%5.3f V\x1B[0m\r\n", (reg_current[battery_nr]) * REF_VOLTAGE / ADC_RES );
154 // printf ( "Absolute Current: \x1B[1;36m%4i mA\x1B[0m\r\n\n", (current[battery_nr]) );
155 // }
156 // END DEBUG
157 
158 }
159 
168 int AD7997_current_vorzeichen ( uint8_t sensor_nummer )
169 {
170  if ( PORTA.IN & (1 << sensor_nummer) )
171  return (-1);
172  else
173  return (1);
174 
175  return 0;
176 }
177 
212 {
213  uint16_t reg_voltage[8] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
214 
215  for ( int battery_nr = 0; battery_nr < 8; battery_nr++ )
216  {
217  sendRegData[0] = AD7997_READ_SINGLE | (bat_nummer2channel[battery_nr] << 4); // Datenblatt S. 29 Read Cmd für Einzelkanal
218  TWI_MasterWrite ( &twiAD7997, AD7997_ADC1_V, &sendRegData[0], 1 );
219  _delay_us ( 3 ); // Datenblatt S. 29 Wake-up and conversion Time
220  TWI_MasterRead ( &twiAD7997, AD7997_ADC1_V, 2 );
221 
222  reg_voltage[battery_nr] = ((((uint8_t) twiAD7997.readData[0]) << 8) | ((uint8_t) twiAD7997.readData[1])) >> 2; // 10bit ADC, 1-0 LSB immer 0 => (MSB << 8 | LSB) >> 2
223  reg_voltage[battery_nr] &= AD7997_RESULT_FLT; // Ergebnis plain binary, filtern mit AD7997_RESULT_FLT
224  voltage[battery_nr] = reg_voltage[battery_nr] * (REF_VOLTAGE / ADC_RES); // Ref.-Spannung ist 5V => LSB = 5/1024 = 4,88 mV
225  }
226 
227  // Korrektur der Spannung Säule 2
228  for ( int i = 4; i <= 7; i++ )
229  {
230  voltage[i] *= SPANNUNGSTELER_2; // Spannung in Säule 2 zu hoch für Referenzspannung, deshalb wird über Spannungsteiler gemessen => Messwert * SPANNUNGSTELER_2 ist die richtige Spannung
231  }
232 
233  // Korrektur der Spannung Säule 1
234  for ( int i = 0; i <= 3; i++ )
235  {
236  voltage[i] *= SPANNUNGSTELER_1; // Spannung in Säule 1 zu hoch für Referenzspannung, deshalb wird über Spannungsteiler gemessen => Messwert * SPANNUNGSTELER_1 ist die richtige Spannung
237  for ( int k = 4; k <= 7; k++ )
238  {
239  if ( akku_an[k] ) voltage[i] -= voltage[k]; // Spannung der evtl. zugeschaltenen Batterie aus Säule 2 wird abgezogen => Batteriespannung
240  }
241  }
242 
243 // DEBUG
244 // for ( int battery_nr = 0; battery_nr <= 7; battery_nr++ )
245 // {
246 // printf ( "## \x1B[1;33m %02i \x1B[0m\r\n", battery_nr );
247 // printf ( "Direct Voltage : \x1B[1;32m%f V\x1B[0m\r\n", (reg_voltage[battery_nr]) * REF_VOLTAGE / ADC_RES );
248 // printf ( "Absolute Voltage: \x1B[1;36m%f V\x1B[0m\r\n\n", (voltage[battery_nr]) );
249 // }
250 // END DEBUG
251 
252 }
253 
254 void leerlauf_voltage_get_data ( void )
255 {
256  int mess_akku = 4;
257 
258  for ( int i = 4; i <= 7; i++ )
259  {
260  if ( akku[i] ) mess_akku = i;
261  }
262  mosfet_battery ( mess_akku, AKKU_2_AN );
263  _delay_ms ( 1 );
265  mosfet_battery ( mess_akku, AKKU_2_AUS );
266 
267 }
268 
269 ISR(TWIC_TWIM_vect)
270 {
271  TWI_MasterInterruptHandler ( &twiAD7997 );
272 }
273 
#define AD7997_RESULT_FLT
10bit ADC => 2 LSB sind immer 0. RESULT_REG >> 2, dann 10bit - Filter (0x3FF)
Definition: ad7997.h:41
#define AD7997_ADC2_I
Adresse für ADC2 zur Strommessung.
Definition: ad7997.h:26
Konstanten, Filter und Commands für den Temperatursensor MCP 9843.
#define R_MESS
Messwiderstand, 15mOhm.
Definition: ad7997.h:98
Header, Definition der Konstanten und Commands für DS1388.
void DS1388_get_datetime(void)
Die Uhrzeit und das Datum werden ausgelesen.
Definition: ds1388_rtc.c:107
#define AD7997_CONFIG_REG
Registeradresse.
Definition: ad7997.h:32
void TWI_MasterInit(TWI_Master_t *twi, TWI_t *module, TWI_MASTER_INTLVL_t intLevel, uint8_t baudRateRegisterSetting)
Initialise the TWI module.
register8_t readData[TWIM_READ_BUFFER_SIZE]
#define AD7997_CONFIG_MSB
0FF0: Alle 8 Kanäle enabled (Bit 11 - Bit 4 = 1)
Definition: ad7997.h:33
#define AD7997_CONFIG_LSB
D3 FLTR (SDA/SDC = 1 an, default), D2 ALERT EN = 0, D1 BUSY/ALERT = 0, D0 BUSY/ALERT POLARITY = 0 (ac...
Definition: ad7997.h:34
#define SPANNUNGSTELER_2
Faktor zur Umrechnung der Batteriespannung in Säule 2.
Definition: ad7997.h:100
Standard Header Datei, Definition der Batteriekonstanten und Grenzwerte.
#define ADC_RES
10bit Auflösung des ADC
Definition: ad7997.h:97
XMEGA TWI master driver header file.
#define REF_VOLTAGE
Referenzspannung für die ADC; In V7.1 5V, in V7.2 3,3V !
Definition: ad7997.h:96
void AD7997_init(void)
TWI (I2C) und ADC 1/2 werden initialisiert.
Definition: ad7997.c:75
void AD7997_voltage_get_data(void)
Ermittelt die Spannungen der Batterien.
Definition: ad7997.c:211
int AD7997_current_vorzeichen(uint8_t sensor_nummer)
Ermittelt die Stromrichtung der abgefragten Batterie.
Definition: ad7997.c:168
#define AD7997_CTIMER_bm
Cycle Timer = 0x00 für Mode 1 (CONVST-PIN) und Mode 2.
Definition: ad7997.h:59
Definition der Schalterstellungen für die einzelnen MOSFETs.
void TWI_MasterInterruptHandler(TWI_Master_t *twi)
Common TWI master interrupt service routine.
bool TWI_MasterWrite(TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite)
TWI write transaction.
#define AD7997_ADC1_V
Adresse für ADC1 zur Spannungsmessung.
Definition: ad7997.h:27
void AD7997_current_get_data(void)
Ermittelt die Stromstärke in den Batteriestromkreisen.
Definition: ad7997.c:128
TWI master driver struct.
bool TWI_MasterRead(TWI_Master_t *twi, uint8_t address, uint8_t bytesToRead)
TWI read transaction.
Standardheader.
void mosfet_battery(uint8_t batteryNumber, bool set)
Einzelne Akkus werden in den Stromkreis zu- oder abgeschaltet.
Definition: bms_mosfet.c:141
#define SPANNUNGSTELER_1
Faktor zur Umrechnung der Batteriespannung in Säule 1.
Definition: ad7997.h:99
Header für ADC AD7997, Definition der Register und Commands.