Moin!
Ich möchte einen LIPO-Akku mit zwei in Reihe geschalteten Zellen mit
einem ATTiny 13 überwachen. Dafür verwende ich den Balancieranschluss
des Akkus, welcher auch den Kontakt zwischen den Zellen aus dem Akku
führt.
Der µC soll die Spannung der einzelnen Zellen auswerten und bei
unterschreiten der 3,0 Volt/Zelle den Ausgang PB0 ausschalten.
Da die Eingänge nur 5 Volt vertragen, der Akku aber bis zu 8,4 Volt hat,
sind eingestellte Potis davor, die die jeweilige Zellenspannung
halbieren.
Die Zelle, die als erste die Mindestmarke erreicht, schaltet den Ausgang
aus. Das Abschalten des Ausgang ist auch das Ende der
while-Schleifenbedingung. Danach soll nur noch für 60 Sekunden die LED
leuchten, die für die passende Zelle eingeschaltet wurde.
Mein Problem ist, das bei unterschreiten einer Zellenspannung beide
LED's leuchten. Folglich beide Bedingungen auslösen. Das kann aber
eigentlich nicht sein, da es immer einen kleinen Unterschied in den
Zellen gibt.
Ich gehe davon aus, dass ADMUX für die ADC-Wandlung nicht richtig
funktioniert. Schaut bitte einmal über das Programm und schreibt mir ob
ich richtig liege oder irgend was übersehe.
Danke...
1 | #define F_CPU 9600000
|
2 | #include <avr/io.h>
|
3 | #include <util/delay.h>
|
4 |
|
5 | //*******************************************
|
6 |
|
7 | unsigned int Spannung = 0;
|
8 | unsigned int Zelle_1 = 0;
|
9 | unsigned int Zelle_2 = 0;
|
10 |
|
11 | //*******************************************
|
12 |
|
13 | void ADC_Wandlung()
|
14 | {
|
15 | ADCSRA |= (1 << ADSC); // erste Wandlung
|
16 | while (ADCSRA & (1 << ADSC)){;} // warte bis ADWdlg. fertig
|
17 | Spannung = ADCW; // Übergabe Wert 1
|
18 | Spannung = 0; // Löschen des Ergebnisses
|
19 |
|
20 | for(int i=0; i<10; i++ ) // Abfrage X mal wiederholen
|
21 | {
|
22 | ADCSRA |= (1 << ADSC); // start Wandlung
|
23 | while (ADCSRA & (1 << ADSC)){;} // warte bis ADWdlg. fertig
|
24 | Spannung += ADCW; // Aufaddieren der Werte
|
25 | }
|
26 |
|
27 | Spannung /= 10; // Mittelwert bilden
|
28 | }
|
29 |
|
30 | //*******************************************
|
31 |
|
32 | int main (void)
|
33 | {
|
34 | DDRB |= (1<<PB0) | (1<<PB1)| (1<<PB2); //
|
35 |
|
36 | // Grundeinstellungen für ADC-Wandlung
|
37 | ACSR |= (1<<ACD); // Ausschalten des Analog Comperator
|
38 | CLKPR = 0x40; // Takt Vorteiler hier 1 Clock Prescale Register
|
39 |
|
40 | ADCSRA |= (1 << ADEN); // Analog-Digital einschalten
|
41 | // ADCSRA |= (1 << ADPS2); // set prescaler
|
42 | ADCSRA |= (1 << ADPS1); // set prescaler
|
43 | // ADCSRA |= (1 << ADPS0); // set prescaler (clock / 2)
|
44 |
|
45 | // ADMUX |= (1 << ADLAR); // 8bit in ADCH
|
46 | // ADMUX |= (1 << REFS0); // Interne Referenzspannung einschalten 1,1 Volt
|
47 |
|
48 | //*******************************************
|
49 |
|
50 | _delay_ms(4900);
|
51 | PORTB |= (1<<PB0);
|
52 |
|
53 | while (( PORTB & 0x01 ) == 0x01 )
|
54 | {
|
55 | ADMUX |= (1 << MUX1); // ADC3 einschalten
|
56 | ADMUX |= (1 << MUX0);
|
57 | ADC_Wandlung();
|
58 | Zelle_1 = Spannung; // Übergabe Wert 1 4,2 Volt
|
59 |
|
60 | ADMUX |= (1 << MUX1); // ADC2 einschalten
|
61 | ADMUX &= ~(1 << MUX0);
|
62 | ADC_Wandlung();
|
63 | Zelle_2 = Spannung; // Übergabe Wert 2 8,4 Volt
|
64 |
|
65 | Zelle_2 -= Zelle_1; // 8,4 Volt - 4,2 Volt
|
66 |
|
67 | if ( Zelle_1 < 307 ) { PORTB &= ~(1<<PB0); PORTB |= (1<<PB1); }
|
68 | if ( Zelle_2 < 307 ) { PORTB &= ~(1<<PB0); PORTB |= (1<<PB2); }
|
69 |
|
70 | _delay_ms(100);
|
71 | }
|
72 |
|
73 | for (unsigned int a = 0; a<60000; a++) { _delay_ms(1); }
|
74 |
|
75 | PORTB &= ~(1<<PB1);
|
76 | PORTB &= ~(1<<PB2);
|
77 |
|
78 | return(0);
|
79 | }
|