Hanna
Sourcecode Kontrollplatine
CP.c
gehe zur Dokumentation dieser Datei
1 
17 #include <avr/io.h>
18 #include <stdio.h>
19 #include <stdint.h>
20 #include <avr/interrupt.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 
25 #include "usartx.h"
26 #include "usb/usb_cdc.h"
27 #include "usb/usb_stdio.h"
28 #include "CP.h"
29 #include "config_clock.h"
30 #include "adc.h"
31 
32 uint32_t sekunden = 0;
33 char laufzeit[8];
34 
39 int main ( void )
40 {
41 
42  init ();
43 
44 // main_usb ();
45  while ( 1 )
46  {
48  werte_berechnen ();
49  terminal_usb ();
50  terminal_usart ();
51  _delay_ms ( WARTEZEIT * 1000 );
52  }
53 
54 }
55 
94 void werte_berechnen ( void )
95 {
96  const float adc_lsb = V_REF / RES_ADC;
97 
98  // Messwerte einlesen
99 
100  V_CHG_1_mess = ADCA_Conversion ( &(ADCA.CH0), 0 ); // XMEGA A-Family Manual S. 288ff
101  if ( V_CHG_1_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
102  V_CHG_1_mess = 0;
103  else
104  V_CHG_1_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
105 
106  I_CHG_1_mess = ADCA_Conversion ( &(ADCA.CH0), 1 );
107  if ( I_CHG_1_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
108  I_CHG_1_mess = 0;
109  else
110  I_CHG_1_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
111 
112  V_CHG_2_mess = ADCA_Conversion ( &(ADCA.CH0), 2 );
113  if ( V_CHG_2_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
114  V_CHG_2_mess = 0;
115  else
116  V_CHG_2_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
117 
118  I_CHG_2_mess = ADCA_Conversion ( &(ADCA.CH0), 3 );
119  if ( I_CHG_2_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
120  I_CHG_2_mess = 0;
121  else
122  I_CHG_2_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
123 
124  V_BAT_mess = ADCA_Conversion ( &(ADCA.CH0), 4 );
125  if ( V_BAT_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
126  V_BAT_mess = 0;
127  else
128  V_BAT_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
129 
130  I_BAT_mess = ADCA_Conversion ( &(ADCA.CH0), 5 );
131  if ( I_BAT_mess < 200 ) // Ist die Messung kleiner 200, liegt keine Spannung an.
132  I_BAT_mess = 0;
133  else
134  I_BAT_mess -= GND_REF; // Offset Korrektur, XMEGA A-Family Manual S. 288ff
135 
136  // Basiswerte berechnen
137  V_CHG_1 = V_CHG_1_mess * adc_lsb * SPANNUNGSTEILER_LADEN;
138  V_CHG_2 = V_CHG_2_mess * adc_lsb * SPANNUNGSTEILER_LADEN;
139  V_BAT = V_BAT_mess * adc_lsb * SPANNUNGSTEILER_BETRIEB;
140 
141  I_CHG_1 = (I_CHG_1_mess * adc_lsb / TS_1101_50) * 1000 / R_MESS; // TS_1101_50: Spannung 50fach verstärkt; *1000 => Strom in mA
142  I_CHG_2 = (I_CHG_2_mess * adc_lsb / TS_1101_50) * 1000 / R_MESS; // TS_1101_50: Spannung 50fach verstärkt; *1000 => Strom in mA
143  I_BAT = (I_BAT_mess * adc_lsb / TS_1101_100) * 1000 / R_MESS; // TS_1101_100: Spannung 100fach verstärkt; *1000 => Strom in mA
144 
145  // Ladungsdifferenz ableiten
146  CHARGE_1 = (float) (I_CHG_1 * WARTEZEIT / 3600); // I in mA, WARTEZEIT in s, C in mAh => I * WARTEZEIT / 3600
147  CHARGE_2 = (float) (I_CHG_2 * WARTEZEIT / 3600); // I in mA, WARTEZEIT in s, C in mAh => I * WARTEZEIT / 3600
148  CHARGE_BAT = (float) (I_BAT * WARTEZEIT / 3600); // I in mA, WARTEZEIT in s, C in mAh => I * WARTEZEIT / 3600
149 
150 }
151 
161 void terminal_usb ( void )
162 {
163  // Terminal mit 6220800 Baud
164  fprintf ( &usbout, "\x1B[2J" );
165  fprintf ( &usbout, "\x1B[2;1HKontrollplatine - Statusanzeige\n\r" );
166  fprintf ( &usbout, "\x1B[34m===================================\x1B[0m\n\n\r" );
167  fprintf ( &usbout, "Betriebszeit: %s\n\n\r", laufzeit );
168  fprintf ( &usbout, "Block 1: Block 2: \n\n\r" );
169  fprintf ( &usbout, "Spannung: %5.2fV Spannung: %5.2fV\n\r", V_CHG_1, V_CHG_2 );
170  fprintf ( &usbout, "Strom: %5imA Strom: %5imA\n\n\r", I_CHG_1, I_CHG_2 );
171  fprintf ( &usbout, "Betrieb: \n\n\r" );
172  fprintf ( &usbout, "Spannung: %5.2fV\n\r", V_BAT );
173  fprintf ( &usbout, "Strom: %5imA\n\n\r", I_BAT );
174 
175  fprintf ( &usbout, "Raw Data:\n\n\r" );
176  fprintf ( &usbout, "Block 1: Block 2: \n\n\r" );
177  fprintf ( &usbout, "Spannung: %5i %5.2fV Spannung: %5i %5.2fV\n\r", V_CHG_1_mess, (float) (V_CHG_1_mess * ADC_LSB), V_CHG_2_mess, (float) (V_CHG_2_mess * ADC_LSB) );
178  fprintf ( &usbout, "Strom: %5i %5.2fV Strom: %5i %5.2fV\n\n\r", I_CHG_1_mess, (float) (I_CHG_1_mess * ADC_LSB), I_CHG_2_mess, (float) (I_CHG_2_mess * ADC_LSB) );
179  fprintf ( &usbout, "Betrieb: \n\n\r" );
180  fprintf ( &usbout, "Spannung: %5i %5.2fV\n\r", V_BAT_mess, (float) (V_BAT_mess * ADC_LSB) );
181  fprintf ( &usbout, "Strom: %5i %5.2fV\n\n\r", I_BAT_mess, (float) (I_BAT_mess * ADC_LSB) );
182 
183 }
184 
190 void terminal_usart ( void )
191 {
192  static bool einmal = true;
193 
194  if ( einmal )
195  {
196  einmal = false;
197  printf ( "Zeit;Ladespannung 1;Ladestrom 1;Ladungsdifferenz 1;Ladespannung 2" );
198  printf ( ";Ladestrom 2;Ladungsdifferenz 2;Betriebsspannung;Betriebsstrom;Ladungsdifferenz\n\r" );
199  }
200 
201  printf ( "%s;%5.2f;%5i;%5.0f;%5.2f;%5i;%5.0f;%5.2f;%5i;%5.0f\n\r", laufzeit, V_CHG_1, I_CHG_1, CHARGE_1, V_CHG_2, I_CHG_2, CHARGE_2, V_BAT, I_BAT, CHARGE_BAT );
202 }
203 
213 void timer_init ( void )
214 {
215 // Timer C0 wird auf einen Takt von 1s eingestellt
216  TCC0.CTRLA = TC_CLKSEL_DIV1024_gc; // Prescaler von 1024
217  TCC0.CTRLB = TC_WGMODE_NORMAL_gc; // Normal Mode
218  TCC0.INTCTRLA = TC_CCAINTLVL_HI_gc; // Priorität des Interrupts im Interrupt Enable-Register A
219  TCC0.PER = 0x7A12; // Timer-Topwert = F_CPU / Prescaler * Sekunden
220 }
221 
226 void init ( void )
227 {
228  // Start 32 MHz CPU Clock.
229  Config32MHzClock ();
230 
231  // Start USB.
232  usb_init ();
233 
234  // Start USART F0.
235  USART_Init ( eUSARTF0, BAUD_A, BAUD_B );
236  USART_Connect ( eUSARTF0, OUT_FILENO );
237 
238  // Timer C0 wird als Zeitgeber 1s initialisiert.
239  timer_init ();
240 
241  // ADC und Messeingänge werden konfiguriert.
242  ADCA_init ();
243  I_sgn_init ();
244 
245  // Interrupts werden eingeschaltet.
246  PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
247  sei();
248 
249 }
250 
256 void laufzeit_berechnen ( void )
257 {
258  uint8_t stunde, minute, sekunde;
259 
260  stunde = sekunden / 3600;
261  minute = (sekunden - stunde * 3600) / 60;
262  sekunde = sekunden - stunde * 3600 - minute * 60;
263 
264  sprintf ( laufzeit, "%02i:%02i:%02i", stunde, minute, sekunde );
265 }
266 
267 ISR(TCC0_OVF_vect)
268 {
269  sekunden++;
270 }
#define RES_ADC
12bit Auflösung
Definition: adc.h:41
#define GND_REF
XMEGA A-Family Manual S. 288ff; Kompensation deltaV mit GND_REF berücksichtigt (0,05*VREF => 200)
Definition: adc.h:39
uint16_t ADCA_Conversion(ADC_CH_t *Channel, char Pin)
Konvertiert die Spannung über Channel, die an Pin anliegt.
Definition: adc.c:66
void ADCA_init(void)
ADC A wird eingestellt.
Definition: adc.c:36
Bibliothek zur USB-Kommunikation von Jürgen W.
void laufzeit_berechnen(void)
Berechnung der Laufzeit.
Definition: CP.c:256
void Config32MHzClock(void)
Einstellung der Systemtakte und der USB-Clock.
Definition: config_clock.c:22
void terminal_usb(void)
Ausgabe der Messwerte auf einem Terminal über USB.
Definition: CP.c:161
Bibliothek zur USB-Kommunikation von Jürgen W.
#define V_REF
XMEGA A-Family Manual S. 288ff; 3,28/1,6 = 2,05.
Definition: adc.h:38
Standardheader.
void init(void)
Hier werden alle Initialisierungen vorgenommen.
Definition: CP.c:226
void timer_init(void)
Timer als Zeitgeber.
Definition: CP.c:213
#define ADC_LSB
LSB 2,05/4096 = 0,000501.
Definition: adc.h:42
void werte_berechnen(void)
ADC wird ausgelesen und die Werte umgerechnet.
Definition: CP.c:94
int main(void)
Main: Ablaufsteuerung.
Definition: CP.c:39
void terminal_usart(void)
Messwertübertragung auf ein Terminal.
Definition: CP.c:190
Standardheader und Auswahl der Übertragungsgeschwindigkeit.
void I_sgn_init(void)
Stromrichtung aus den Strommesssensoren TS1101.
Definition: adc.c:55