PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Attiny15 Akku auswerten



rogerberglen
23.10.2019, 18:49
Würde gerne einen Akku mit einem Attiny15 überwachen. Damit das Ganze an den Schaltschwellen nicht hin und her zappelt. habe ich mal folgenden Code aufgesetzt. Bin mir aber nicht sicher ob ich Alles bedacht habe. Oder gibts es eine einfachere Möglichkeit Schaltstufen festzulegen?
Der folgende Programmteil wird zusammen mit einer Tasterabfrage aufgerufen und nur ca. alle 2Sekunden ausgeführt. ADPause ist FFFF.
Der Übergabewert vom AD-Wandler ist mit ADLAR = 1 ausgerichtet, so dass ich nur die Werte von 0 bis 256 zum Vergleich hernehme.



; ************************************************** *****
; * Akku prüfen mit A/D-Wandler *
; ************************************************** *****


AkkuCheck:


dec YL ; Low-Byte des Durchlaufzählers -1
brne AkkuCheckEnde ; Nicht 0, dann Sprung zum Ende.
dec YH ; Sonst High-Byte des Durchlaufzählers -1
brne AkkuCheckEnde ; Nicht 0, dann Sprung zum Ende
ldi YL, low (ADPause) ; Sonst Zählerstartwert low und high
ldi YH, high (ADPause) ; mit Anfangswert wieder laden.


AkkuCheck1:


sbrs Status, ADFirst ; Ist 1.Durchlauf gesetzt?
rjmp AkkuCheck2 ; Nein, dann weiter
cbr Status, 1<<ADFirst ; Sonst Kennung 1. Durchlauf löschen.


AkkuCheck2:


in TMP1, ADCSR ; AD-Kontrollregister einlesen
sbr TMP1, 1<<ADEN | 1<<ADSC | 1<<ADPS2 |1<<ADPS1 | 1<<ADPS0 ; und AD-Wandler einschalten.
out ADCSR, TMP1 ; Warten damit sich die Referenzspannung
rcall Wait12ms ; stabilisieren kann.


ADFertig:


sbic ADCSR, ADSC ; Solange warten bis die AD-Wandlung
rjmp ADFertig ; abgeschlossen ist.
in ZL, ADCL ; und AD-Ergebnis auslesen (zuerst Low-Byte).
in ZH, ADCH ; Es wird nur das High-Byte weiterverwendet.
cbi ADCSR, ADEN ; AD-Wandler abschalten.


; *****************************************
; * Akku leer Erkennung *
; *****************************************


cpi ZH, AkkuLeer ; Meßwert > Vorgabewert?
brcc Hysterese1 ; Ja, dann Offset.
sbrc Status, AkkuLow ; Wurde Akku leer bereits erkannt?
rjmp AkkuCheckEnde ; Dann Sprung zum AkkuCheck Ende
in TMP1, PORTB ; PortB einlesen und grüne Led durch
sbr TMP1, 1<<PORTB3 ; Ausgabe einer 1 an PB3 ausschalten.
cbr TMP1, 1<<PORTB4 ; Rote Led durch Ausgabe einer 0 an PB4.
out PORTB, TMP1 ; einschalten und ausgeben.
cbr Status, 1<<AkkuReady | 1<<AkkuFull ; Andere Kennungen in Status löschen
sbr Status, 1<<AkkuLow ; Kennung Akku leer in Status setzen
in TMP1, TCCR1 ; PWM-Timer Steuerregister laden und
cbr TMP1, 1<<COM1A1 | 1<<COM1A0 | 1<<CS12 | 1<<CS11 | 1<<CS10 ; diesen ausschalten.
out TCCR1, TMP1 ; Alles Speichern.
in TMP1, PORTB ; Falls Scheinwerfer-LED Ausgang geschaltet
cbr TMP1, 1<<PORTB1 ; ist, diesen auf jeden Fall ausschalten.
out PORTB, TMP1 ; Lampen-LED wird sonst zerstört!
rjmp AkkuCheckEnde ; und Sprung zum Abfrageende.


; *****************************************
; * Hysterese 1.Zustand zu 2.Zustand *
; *****************************************


Hysterese1:


cpi ZH, AkkuLeer + OffSet ; Zu Vergleichswert einen Offset addieren
brcc AkkuR ; In diesem Bereich wird keine Veränderung
rjmp AkkuCheckEnde ; des Akkustatus vorgenommen.


; *****************************************
; * Akku bereit Erkennung *
; *****************************************


AkkuR:


cpi ZH, AkkuBereit ; Meßwert > Vorgabewert?
brcc Hysterese2 ; Ja, dann zur AkkuOK Abfrage
sbrc Status, AkkuReady ; Wurde Akku bereit bereits erkannt?
rjmp AkkuCheckEnde ; Dann Sprung zum AkkuCheck Ende
in TMP1, PORTB ; PortB einlesen und beide Led's durch
sbr TMP1, 1<<PORTB4 | 1<<PORTB3 ; Ausgabe einer 1 an PB3 + PB4
out PORTB, TMP1 ; ausschalten und ausgeben.
cbr Status, 1<<AkkuLow | 1<<AkkuFull ; Andere Kennungen in Status löschen
sbr Status, 1<<AkkuReady ; Kennung Akku bereit in Status setzen
rjmp AkkuCheckEnde ; und Sprung zum Abfrageende.


; *****************************************
; * Hysterese 2.Zustand zu 3.Zustand *
; *****************************************


Hysterese2:


cpi ZH, AkkuBereit + Offset ; Zu Vergleichswert einen Offset addieren
brcc AkkuOK ; In diesem Bereich wird keine Veränderung
rjmp AkkuCheckEnde ; des Akkustatus vorgenommen.


; *****************************************
; * Akku voll Erkennung *
; *****************************************

AkkuOK:


cpi ZH, AkkuVoll ; Meßwert > Vorgabewert?
brlo AkkuCheckEnde ; Ja, dann zum Abfrageende
sbrc Status, AkkuFull ; Wurde Akku voll bereits erkannt?
rjmp AkkuCheckEnde ; Dann Sprung zum AkkuCheck Ende
in TMP1, PORTB ; PortB einlesen und rote Led durch
sbr TMP1, 1<<PORTB4 ; Ausgabe einer 1 an PB4 ausschalten.
cbr TMP1, 1<<PORTB3 ; Grüne Led durch Ausgabe einer 1 an
out PORTB, TMP1 ; PB3 einschalten und ausgeben.
cbr Status, 1<<AkkuReady | 1<<AkkuLow ; Andere Kennungen in Status löschen
sbr Status, 1<<AkkuFull ; Kennung Akku voll in Status setzen


AkkuCheckEnde:


ret ; Rücksprung