; ************************************************************** ; * Datei mit Routinen fuer Tastenbedienung des Akkuladers * ; * (C)2005 by Gerhard Schmidt, info@avr-asm-tutorial.net * ; ************************************************************** ; ; Routine Register Zweck ; --------------------------------------------------------- ; KeyInit rmp,Z,X Initiiert Tasteneingaben, setzt Startwerte ; Keys rmp Fragt gedrueckte Tasten ab ; fuer die Hauptprogrammschleife ; KeyMenueFirst nn Ausgabe des ersten Tastenmenues ; --------------------------------------------------------- ; ; Konstanten ; .EQU pLedO = PORTD ; LEDs sind an Port D angeschlossen .EQU cLedM = 0xF0 ; Alle LED Port Bits gesetzt .EQU pKeyO = PORTD ; Tasten an Port D angeschlossen .EQU pKeyD = DDRD ; Tastenrichtungsregister .EQU pKeyI = PIND ; Tastenlese-Port .EQU cKeyB = 0xE0 ; Drei Tasten an Bits 7, 6 und 5 .EQU cKeyM = 0x1F ; Maske fuer Loeschen der Bits 7, 6, und 5 ; ; ============== Routine zur Initialisierung der Tasten ===== ; ; Initiieren der LEDs, LEDs fuer 4 Sekunden einschalten ; KeyLedInit: ldi ZH,HIGH(sLedC) ; LED PW-Zaehler Null setzen ldi ZL,LOW(sLedC) ldi rmp,5 ; 5 bytes clr R0 KeyLedInit1: st Z+,R0 dec rmp brne KeyLedInit1 in rmp,pLedO cbr rmp,cLedM ; loeschen des LED-Bits, LED an out pLedO,rmp ret ; ; Initiieren der Tasten ; KeyInit: clr rKeyLst ; Loesche letzte Taste clr rKeyRep ; Loesche Zaehler fuer Tastenwiederholung ; ; Loesche die Variablen fuer Tasteneingaben ; KeyReset: ldi XH,HIGH(sKeyJ1) ; Ziel im SRAM ldi XL,LOW(sKeyJ1) ldi ZH,HIGH(2*KeyInitTable) ; Quellentabelle ldi ZL,LOW(2*KeyInitTable) ldi rmp,6 ; 3 Worte, 6 Bytes KeyReset1: lpm ; Lese aus Tabelle adiw ZL,1 st X+,R0 ; in SRAM dec rmp brne KeyReset1 clr rmp ; Setze Kanal = 0 sts sKeyCh,rmp ret ; ; Tabelle fuer Tasteneingabe ; KeyInitTable: .DW KeyM1,0,0 ; ; ===================== Routinen fuer Hauptschleife ============ ; ; bedient die LED-Ausgabe ; KeyLeds: in R0,pLedO ; Speichere aktuellen Ausgabestatus ldi rmp,0x0F ; Loesche alle Ausgabebits, LEDs an and R0,rmp lds rmp,sLedC ; lese LED-Zaehler dec rmp ; zaehle Zaehler herunter brne KeyLeds4 ; nicht Null, keine Zustandspruefung lds R1,sState ; Lese Kanalstatus ldi ZH,HIGH(sLed1) ; Z zeigt auf Kanal ldi ZL,LOW(sLed1) ldi XL,4 ; vier Mal wiederholen KeyLeds1: lsr R1 ; niedriges Statusbit brcs KeyLeds2 ; niedrigstes Statusbit ist Eins ldi XH,32 ; Kanalvergleichswert für 50%-Anzeige lsr R1 ; hoeheres Statusbit lesen brcs KeyLeds3 ; Status=10=load, setze Kanalwert ldi XH,64 ; 00=inactive, spaeter LEDs abschalten rjmp KeyLeds3 ; setze Kanalwert KeyLeds2: ; niedriges Statusbit ist Eins clr XH ; 11=Erhaltungsladung, LED dauernd an lsr R1 ; hoeheres Bit in Carry brcs KeyLeds3 ; setze Kanalwert ldi XH,56 ; 01=Entladen, Led an fuer 8 Zyklen KeyLeds3: ; speichere Kanalwert und wiederhole st Z+,XH ; setze Kanalwert dec XL ; naechster Kanal brne KeyLeds1 ; weiterer Kanal ldi rmp,64 ; 64 Zyklen in Zaehler KeyLeds4: ; vergleiche Kanalwert mit Zaehler sts sLedC,rmp ; speichere Zaehler ldi XH,0x80 ; Maske fuer Setzen eines LED-Bit ldi XL,4 ; vier Kanaele ldi ZH,HIGH(sLed1) ; Z auf Kanalwert setzen ldi ZL,LOW(sLed1) KeyLeds5: ; pruefe ob LED aus sein sollte ld R1,Z+ ; Lese Kanalwert cp R1,rmp ; vergleiche Zaehler und Kanalwert brcs KeyLeds6 ; lasse LED an or R0,XH ; schalte Kanalausgang an = LED aus KeyLeds6: lsr XH ; Maske eine Position rechts dec XL ; naechster Kanal brne KeyLeds5 ; noch ein Kanal out pLedO,R0 ; Setze Ausgabebits ret ; fertig ; ; Keys fragt die Eingabepins auf gedrueckte Tasten ab ; Keys: in R1,pKeyO ; Rette aktuelle Statusbits (LEDs) in R0,pKeyD ; Sichere Richtungsbits mov rmp,R0 ; kopiere Richtungsbits andi rmp,cKeyM ; loesche Richtungsbits out pKeyD,rmp ; Tastenbits als Eingaenge mov rmp,R1 ; Pullup-Widerstaende ori rmp,cKeyB ; Bits auf Eins setzen out pKeyO,rmp ; an Port nop ; warte eine Weile nop nop nop in rmp,pKeyI ; Lese Tastenport out pKeyD,R0 ; Stelle Richtungsbits wieder her out pKeyO,R1 ; Stelle Ausgabezustand wieder her andi rmp,cKeyB ; Isoliere Tastenbits cpi rmp,cKeyB ; alle Tasten inaktiv? brne Keys2 ; nein Keys1: clr rKeyRep ; Wiederholung auf Null mov rKeyLst,rmp ; speichern ret ; fertig Keys2: cp rmp,rKeyLst ; gleich letztem Tastenstatus? brne Keys1 ; nein, loesche Zaehler inc rKeyRep ; erhoehe Zaehler ldi rmp,cKeyRep ; vergleiche mit vorgewaehlter Zahl cp rmp,rKeyRep breq Keys3 ; gleich, mach weiter ret Keys3: ; Taste ok, starte ausgewaehlte Routine mov R0,rKeyLst ; lese die Tasten erneut ldi ZH,HIGH(sKeyJ1) ; zeige auf erste Adresse ldi ZL,LOW(sKeyJ1) Keys4: rol R0 brcc Keys5 adiw ZL,2 ; naechste Adresse rjmp Keys4 Keys5: ld rmp,Z+ ; Lese Sprungadresse und springe ld R0,Z mov R1,R0 ; pruefe ob Adresse Null ist or R1,rmp breq Keys6 push rmp push R0 Keys6: ret ; jump ; ; ================== Allgemeine Routinen fuer Menues ============ ; ; Setze Position auf Menue-Anfang ; KeyMStrt: push ZH ; sichere Z push ZL ldi ZH,3 ; Zeile 4 ldi ZL,9 ; Position 10 rcall LcdPos ; setze Position pop ZL ; stelle Z wieder her pop ZH ret ; ; loescht den Menueteil und setzt die Position auf den Anfang ; KeyMClr: rcall KeyMStrt ldi rmp,' ' mov R0,rmp ldi rmp,11 mov R1,rmp KeyMClr1: rcall LcdR0 dec R1 brne KeyMClr1 rjmp KeyMStrt ; ; Erstes Menue in Zeile 4 ausgeben ; KeyMenueFirst: rcall KeyMStrt ; Setze Position ldi ZH,HIGH(2*KeyTxtMenue) ldi ZL,LOW(2*KeyTxtMenue) rcall LcdDisplZ ldi rmp,17 ; Setze Cursor Position sts sLcdCs,rmp rjmp KeyReset ; initiiere Sprungadresse ; Erstes Menue an LCD KeyTxtMenue: .DB " Menue...",0 ; ; Fehlermeldung falsche Kanalnummer ausgeben ; KeyGetChError: rcall KeyMClr ; Menueteil loeschen ldi ZH,HIGH(2*KeyTxtChErr) ; Fehlertext ldi ZL,LOW(2*KeyTxtChErr) rcall LcdDisplZ ; zeige Text an ldi rmp,18 ; setze Cursor Position sts sLcdCs,rmp ret ; ; Hole Kanalnummer in R0 ; Wenn Kanalnummer nicht zwischen 1 und 4 liegt, gib Fehlermeldung ; aus und kehre mit gesetztem Carry zurueck ; KeyGetChR0: lds R0,sKeyCh ; Lese aktuellen Kanal tst R0 ; = Null? breq KeyGetChR0e push rmp ldi rmp,5 cp R0,rmp ; > 4 ? pop rmp brcc KeyGetChR0e clc ret KeyGetChR0e: rcall KeyGetChError sec ret ; KeyTxtChErr: .DB "Ch error!",0 ; ; Setze gewaehlten Kanal auf den Wert n rmp ; KeyChSet: rcall KeyGetChR0 ; Kanalnmmer in R0 brcs KeyChSet3 ldi ZL,0xFC ; Kanalmaskenbits = 0 KeyChSet1: dec R0 ; Kanal erreicht? breq KeyChSet2 ; ja sec ; setze Carry fuer Maskenrollen rol ZL ; naechster Kanal rol ZL lsl rmp ; schiebe rmp links lsl rmp rjmp KeyChSet1 ; noch mal KeyChSet2: lds ZH,sState ; lade Statusbits and ZH,ZL ; loesche Kanalbits or ZH,rmp ; setze Kanalbits auf Wert in rmp sts sState,ZH ; setze neuen Status KeyChSet3: ret ; ; Setze PWM-Wert des Kanals auf den Wert in rmp ; KeySetPwm: rcall KeyGetChR0 brcs KeySetPwm2 ldi ZH,HIGH(cPwm1S-1) ; loesche PWM-Wert des Kanals ldi ZL,LOW(cPwm1S-1) KeySetPwm1: adiw ZL,1 ; naechster PWM-Kanal dec R0 brne KeySetPwm1 st Z,rmp ; setze PWM-Wert KeySetPwm2: ret ; ; Entlade-Bit des Kanals loeschen ; KeyClrUnl: rcall KeyGetChR0 brcs KeyClrUnl2 ldi rmp,0xF7 ; Maske KeyClrUnl1: sec ; rolle eine 1 ein rol rmp ; rotiere Maske links dec R0 ; naechster Kanal brne KeyClrUnl1 and rPwmOut,rmp ; loesche Entladebit KeyClrUnl2: ret ; fertig ; ; Loesche Kapazitaetszaehler ; KeyClrCap: rcall KeyGetChR0 brcs KeyClrCap1 dec R0 ldi ZH,HIGH(sAdcC) ldi ZL,LOW(sAdcC) add ZL,R0 add ZL,R0 st Z+,rmp st Z+,rmp std Z+6,rmp KeyClrCap1: ret ; ; Hole die Parameter des aktuellen Kanals, setze Adresse und hole ; Dezimalzah, erwartet die Parameter-Basisadresse in X und den ; Maximalwert in Z ; KeyGetParam: rcall KeyGetChR0 brcs KeyGetParam1 dec R0 lsl R0 ; * 8 lsl R0 lsl R0 add XL,R0 ; korrigiere Adresse clr R0 adc XH,R0 ld R0,X+ ; lese LSB sts sKeyNW,R0 ; speichere Dezimalzahl ld R0,X ; lese MSB sts sKeyNW+1,R0 sts sKeyNM,ZL sts sKeyNM+1,ZH KeyGetParam1: ret ; ; Setze die Parameter im aktuellen Kanal ; Erwartet Parameter-Basisadresse in X und Text in Z ; KeySetParam: rcall KeyGetChR0 brcs KeySetParam1 dec R0 lsl R0 ; * 8 lsl R0 lsl R0 add XL,R0 ; korrigiere Adresse clr R0 adc XH,R0 lds rmp,sKeyNW st X+,rmp lds rmp,sKeyNW+1 st X,rmp rcall KeyMClr rcall LcdDisplZ ldi ZH,HIGH(KeyM12a) ldi ZL,LOW(KeyM12a) ijmp KeySetParam1: ret ; ; Nach Beenden eines Menueeintrags zeige Text in X an ; KeyMDone: rcall KeyMClr ; Loesche Menuebereich der LCD rcall LcdDisplZ mov ZH,XH mov ZL,XL ijmp ; ; ================= Behandlung von Menueeintraegen =========== ; ; Ausgabe des Menueeintrags in X, des Menueeintrags in sKeyNC ; KeyMOut: rcall KeyMClr KeyMOut1: mov ZH,XH ; kopiere Menuebeginn nach Z mov ZL,XL lds R1,sKeyNC ; lese Menueeintragnummer KeyMOut2: ; pruefe ob der Menueeintrag erreicht ist tst R1 ; Menueeintraszaehler = 0? brne KeyMOut5 ; nicht erreicht, weiter KeyMOut3: ; Menueeintrag erreicht, Ausgabe des Menuetexts lpm adiw ZL,1 mov rmp,R0 cpi rmp,'#' ; Endezeichen breq KeyMOut4 rcall LcdChar rjmp KeyMout3 KeyMOut4: ; Ausgabe beendet, suche NULL lpm adiw ZL,1 tst R0 brne KeyMOut4 ; Lese die LCD Cursor position und die Sprungadresse lpm adiw ZL,1 sts sLcdCs,R0 lpm adiw ZL,1 sts sKeyJ3,R0 ; speichere in Adresse fuer Taste 3 lpm sts sKeyJ3+1,R0 ret KeyMOut5: ; nicht der gewueschte Eintrag suche naechsten Text lpm adiw ZL,1 tst R0 brne KeyMOut5 adiw ZL,3 lpm ldi rmp,0xFF cp rmp,R0 breq KeyMOut6 dec R1 rjmp KeyMOut2 KeyMOut6: ; starte neu clr R1 sts sKeyNC,R1 rjmp KeyMOut1 ; ; ================= Hole Dezimalzahl Eingabe ============ ; ; ; Zeigt die Dezimalzal in sKeyNW am Ende von Zeile 4 der LCD an ; KeyDecDispl: ; zeige Dezimalzahl an ldi ZH,3 ; Zeile 4 ldi ZL,15 ; Position 16 rcall LcdPos ; Setze LCD Position lds R2,sKeyNW ; lese Dezimalzahl lds R3,sKeyNW+1 rcall LcdDec5 ; schreibe Zahl auf LCD lds ZL,sKeyNC ; setze LCD Cursor Position subi ZL,-15 sts sLcdCs,ZL ldi ZH,3 rjmp LcdPos ; ; Setze die Sprungadresse fuer die Dezimaleingabe und hole Zahl ; erwartet: Textzeiger in Z, Rueckadresse in X, Abbruchadresse ; in sKeyJ1 ; KeyDec: rcall KeyMClr ; loesche Menuebereich rcall LcdDisplZ ; Textausgabe ldi ZH,HIGH(sKeyJR) ; auf Ruecksprungadresse zeigen ldi ZL,LOW(sKeyJR) st Z+,XL st Z+,XH lds XL,sKeyJ1 ; speichere Ruecksprungsadresse lds XH,sKeyJ1+1 st Z+,XL st Z+,XH ldi XL,LOW(KeyDecL) ; Taste 1 Adresse ldi XH,HIGH(KeyDecL) st Z+,XL st Z+,XH ldi XL,LOW(KeyDecU) ; Taste 2 Adresse ldi XH,HIGH(KeyDecU) st Z+,XL st Z+,XH ldi XL,LOW(KeyDecR) ; Taste 3 Adresse ldi XH,HIGH(KeyDecR) st Z+,XL st Z+,XH ldi rmp,4 ; Cursor auf letzte Ziffer sts sKeyNC,rmp rjmp KeyDecDispl ; Zeige Zahl an und setze Cursor ; KeyDecL: ; Linke Taste lds rmp,sKeyNC ; Cursor Position eins links dec rmp cpi rmp,0xFF ; ueber Anfang hinaus? breq KeyDecL1 sts sKeyNC,rmp ; setze Cursor rjmp KeyDecDispl ; Zahlanzeige und Cursor setzen KeyDecL1: lds ZL,sKeyJS ; lese Abbruchadresse lds ZH,sKeyJS+1 ijmp ; springe zur Abbruchroutine ; KeyDecU: ; Mittlere Taste ldi ZH,HIGH(2*KeyDecTbl) ; Z auf Dezimaltabelle ldi ZL,LOW(2*KeyDecTbl) lds rmp,sKeyNC ; plus aktuelle Position lsl rmp ; * 2 add ZL,rmp ; zeige auf Wert in Dezimaltabelle clr rmp adc ZH,rmp lpm ; lese Dezimalwert mov XL,R0 adiw ZL,1 lpm mov XH,R0 lds ZL,sKeyNW ; lese aktuelle Dezimalzahl lds ZH,sKeyNW+1 add ZL,XL ; Addiere beide adc ZH,XH lds XL,sKeyNM ; lese Maximalzahl lds XH,sKeyNM+1 sec cpc ZL,XL ; vergleiche mit Maximum cpc ZH,XH brcs KeyDecU1 clr ZH ; > Max., loesche Zahl clr ZL KeyDecU1: sts sKeyNW,ZL ; speichere Zahl sts sKeyNW+1,ZH rjmp KeyDecDispl ; zeige Dezimalzahl an, setze Cursor ; KeyDecR: ; Rechte Taste lds rmp,sKeyNC ; lese Cursor inc rmp ; naechste Position cpi rmp,5 ; rechts raus? brcc KeyDecR1 ; ja sts sKeyNC,rmp ; speichere Position rjmp KeyDecDispl KeyDecR1: lds ZL,sKeyJR ; lese Sprungadresse lds ZH,sKeyJR+1 ijmp ; springe zum Beenden der Eingabe ; KeyDecTbl: ; Dezimaltabelle .DW 10000 .DW 1000 .DW 100 .DW 10 .DW 1 ; ; ================= Menues ===================== ; ; Menue 1, Auswahl ; KeyM1: ldi XH,HIGH(2*KeyTxtM1) ; Menuetext ldi XL,LOW(2*KeyTxtM1) rcall KeyMOut ; zeige Menuetext an KeyM1a: ldi rmp,LOW(KeyMenueFirst) ; Setze linke Sprungadresse sts sKeyJ1,rmp ldi rmp,HIGH(KeyMenueFirst) sts sKeyJ1+1,rmp ldi rmp,LOW(KeyM1Up) ; Setze mittlere Sprungadresse sts sKeyJ2,rmp ldi rmp,HIGH(KeyM1Up) sts sKeyJ2+1,rmp clr rmp ; beginne mit Menueeintrag 0 sts sKeyNC,rmp ret ; ; Menue 1 Erhoehen Routine ; KeyM1Up: lds rmp,sKeyNC ; naechst hoeherer Menueeintrag inc rmp sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM1) ; zeige mit X auf Menuetabelle ldi XL,LOW(2*KeyTxtM1) rjmp KeyMOut ; ; Menue 11: Auswahl von Akku-Id und Kanal ; KeyM11: clr rmp ; Setze ausgewaehlten Menueeintrag auf 0 sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM11) ; Zeiger X auf Menuetabelle ldi XL,LOW(2*KeyTxtM11) rcall KeyMOut ; Zeige Menueeintrag an KeyM11a: ldi rmp,LOW(KeyM1) ; Setze Sprungadresse fuer linke Taste auf Menue 1 sts sKeyJ1,rmp ldi rmp,HIGH(KeyM1) sts sKeyJ1+1,rmp ldi rmp,LOW(KeyM11Up) ; Setze mittlere Sprungadresse auf M11Up sts sKeyJ2,rmp ldi rmp,HIGH(KeyM11Up) sts sKeyJ2+1,rmp ret ; ; Menue 11 Up Tastenroutine ; KeyM11Up: lds rmp,sKeyNC ; naechster Menueeintrag inc rmp sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM11) ; ausgewaehlter Menuetext ldi XL,LOW(2*KeyTxtM11) rjmp KeyMOut ; Ausgabe des Menueeintrags ; ; Tastenauswahl-Routinen ; KeyM111: ; Waehle Akku-Id rcall KeyGetChR0 ; lese Kanal brcs KeyM111e dec R0 ldi ZH,HIGH(sAdcAI1) ; lese Akku-Id ldi ZL,LOW(sAdcAI1) add ZL,R0 add ZL,R0 ld rmp,Z sts sKeyNW,rmp clr rmp sts sKeyNW+1,rmp lds rmp,sEANm ; lese Anzahl der Id's sts sKeyNM,rmp ; setze Maximaleingabe clr rmp sts sKeyNM+1,rmp ldi XH,HIGH(KeyM111R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM111R) ldi ZH,HIGH(2*KeyTxtM111) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM111) rjmp KeyDec ; hole Dezimalzahl KeyM111e: ret ; KeyTxtM111: .DB "Akku=",0 ; ; Rueckkehr von der Dezimalahleingabe mit Akku-Id ; KeyM111R: rcall KeyGetChR0 brcs KeyM111Re dec R0 ldi ZH,HIGH(sAdcAI1) ldi ZL,LOW(sAdcAI1) add ZL,R0 add ZL,R0 lds rmp,sKeyNW ; kopiere Dezimalzahl in Kanal st Z,rmp rcall IdSetPar ; Setze Parameter ldi XH,HIGH(KeyM11a) ; Sprung zurueck ldi XL,LOW(KeyM11a) ldi ZH,HIGH(2*KeyTxt112R) ldi ZL,LOW(2*KeyTxt112R) rjmp KeyMDone KeyM111Re: ret ; KeyTxt111R: .DB "Akku-Id ok",0,0 ; KeyM112: ; Waehle Kanalnummer aus lds rmp,sKeyCh ; lese Kanal, kopiere nach Dezimalzahleingabe sts sKeyNW,rmp clr rmp sts sKeyNW+1,rmp ldi rmp,4 ; Setze Maximumwert sts sKeyNM,rmp clr rmp sts sKeyNM+1,rmp ldi XH,HIGH(KeyM112R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM112R) ldi ZH,HIGH(2*KeyTxtM112) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM112) rjmp KeyDec ; hole Dezimalzahl ; KeyTxtM112: .DB "Kanal=",0,0 ; ; Setze Kanal auf Eingabezahl ; KeyM112R: lds rmp,sKeyNW ; kopiere Eingabezahl in Kanal sts sKeyCh,rmp ldi XH,HIGH(KeyM11a) ; springe zurueck ldi XL,LOW(KeyM11a) ldi ZH,HIGH(2*KeyTxt112R) ldi ZL,LOW(2*KeyTxt112R) rjmp KeyMDone ; KeyTxt112R: .DB "Kanal ok",0,0 ; KeyM113: ; Direkt laden ldi rmp,LOW(500) sts sKeyNW,rmp ldi rmp,HIGH(500) sts sKeyNW+1,rmp ldi rmp,LOW(9999) sts sKeyNM,rmp ldi rmp,HIGH(9999) sts sKeyNM+1,rmp ldi XH,HIGH(KeyM113R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM113R) ldi ZH,HIGH(2*KeyTxtM113) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM113) rjmp KeyDec ; hole Dezimalzahl ; KeyTxtM113: .DB "Kapaz.=",0 ; KeyM113R: rcall KeyGetChR0 brcs KeyM113Re rcall KeyClrUnl ldi rmp,0x02 ; setze Ladestatus rcall KeyChSet ldi rmp,128 rcall KeySetPwm rcall KeyGetChR0 dec R0 lsl R0 lsl R0 lsl R0 ldi ZH,HIGH(sCh1LC) ; zeige auf Ladestrom ldi ZL,LOW(sCh1LC) add ZL,R0 clr R0 adc ZH,R0 lds XL,sKeyNW ; lese Kapazitaet lds XH,sKeyNW+1 mov R2,XL ; kopiere mov R3,XH lsr R3 ; / 2 ror R2 lsr R3 ; / 4 ror R2 lsr R3 ; / 8 ror R2 st Z+,R2 ; setze Ladestrom st Z+,R3 add XL,R2 ; addiere zur Nennkapazitaet adc XH,R3 st Z+,XL ; setze Kapazitaet st Z+,XH lsl XL ; * 2 rol XH clr rmp rol rmp st Z+,XH ; setze den Erhaltungsstrom st Z,rmp ldi XH,HIGH(KeyM11a) ; Ruecksprungadresse ldi XL,LOW(KeyM11a) ldi ZH,HIGH(2*KeyTxt113D) ; Textausgabe ldi ZL,LOW(2*KeyTxt113D) rjmp KeyMDone KeyM113Re: ret ; KeyTxt113D: .DB "Autoladen",0 ; ; Menue "Setze" Routinen ; KeyM12: clr rmp ; Setze gewaehlten Menueeintrag auf 0 sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM12) ; X zeigt auf Menuetabelle ldi XL,LOW(2*KeyTxtM12) rcall KeyMOut ; Zeige Menueeintrag an KeyM12a: ldi rmp,LOW(KeyM1) ; Setze linke Sprungadresse auf Menue 1 sts sKeyJ1,rmp ldi rmp,HIGH(KeyM1) sts sKeyJ1+1,rmp ldi rmp,LOW(KeyM12Up) ; Setze mittlere Sprungadresse auf M12Up sts sKeyJ2,rmp ldi rmp,HIGH(KeyM12Up) sts sKeyJ2+1,rmp ret ; ; Menue 12 Up Tastenroutine ; KeyM12Up: lds rmp,sKeyNC ; naechster Menueeintrag inc rmp sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM12) ; gewaehlter Menuetext ldi XL,LOW(2*KeyTxtM12) rjmp KeyMOut ; gib Menueeintrag aus ; KeyM121: ldi XH,HIGH(sCh1UV) ; Kanalnummer auf Entladespannung ldi XL,LOW(sCh1UV) ldi ZH,HIGH(1300) ; Maximalwert setzen ldi ZL,LOW(1300) rcall KeyGetParam ; Parameter in X auf Eingabe und Maximum auf Z ldi XH,HIGH(KeyM121R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM121R) ldi ZH,HIGH(2*KeyTxtM121) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM121) rjmp KeyDec; hole Dezimalzahl ; KeyM122: ldi XH,HIGH(sCh1LC) ; Kanalnummer auf Ladestrom ldi XL,LOW(sCh1LC) ldi ZH,HIGH(350) ; Maximalwert ldi ZL,LOW(350) rcall KeyGetParam ; Parameter in X auf Eingabe und Maximum auf Z ldi XH,HIGH(KeyM122R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM122R) ldi ZH,HIGH(2*KeyTxtM122) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM122) rjmp KeyDec; Hole Dezimalzahl ; KeyM123: ldi XH,HIGH(sCh1LW) ; Kanalnummer auf Ladekapazitaet ldi XL,LOW(sCh1LW) ldi ZH,HIGH(9999) ; Maximawert ldi ZL,LOW(9999) rcall KeyGetParam ; Parameter in X auf Eingabe und Maximum auf Z ldi XH,HIGH(KeyM123R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM123R) ldi ZH,HIGH(2*KeyTxtM123) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM123) rjmp KeyDec; hole Dezimalzahl ; KeyM124: ldi XH,HIGH(sCh1MC) ; Kanalnummer auf Erhaltungsstrom ldi XL,LOW(sCh1MC) ldi ZH,HIGH(100) ; Maximalwert ldi ZL,LOW(100) rcall KeyGetParam ; Parameter in X auf Eingabe und Maximum af Z ldi XH,HIGH(KeyM124R) ; Ruecksprungadresse in X ldi XL,LOW(KeyM124R) ldi ZH,HIGH(2*KeyTxtM124) ; Textadresse in Z ldi ZL,LOW(2*KeyTxtM124) rjmp KeyDec; Hole Dezimalzahl ; KeyTxtM121: .DB "Entlade=",0,0 ; KeyTxtM122: .DB "Laden I=",0,0 ; KeyTxtM123: .DB "Kapaz.=",0 ; KeyTxtM124: .DB "Erhalt.=",0,0 ; ; Setze die Entladespannung auf den Wert sKeyNW ; KeyM121R: ldi XH,HIGH(sCh1UV) ; X auf Entladespannung ldi XL,LOW(sCh1UV) ldi ZH,HIGH(2*KeyTxtM121D) ; Z auf Text ldi ZL,LOW(2*KeyTxtM121D) rjmp KeySetParam ; setze Parameter ; ; Setze den Ladestrom auf den Wert in sKeyNW ; KeyM122R: ldi XH,HIGH(sCh1LC) ; X auf Ladestrom ldi XL,LOW(sCh1LC) ldi ZH,HIGH(2*KeyTxtM122D) ; Z auf Text ldi ZL,LOW(2*KeyTxtM122D) rjmp KeySetParam ; setze Parameter ; ; Setze die Nennkapazitaet auf den Wert in sKeyNW ; KeyM123R: ldi XH,HIGH(sCh1LW) ; X auf Kapazitaet ldi XL,LOW(sCh1LW) ldi ZH,HIGH(2*KeyTxtM123D) ; Z auf Text ldi ZL,LOW(2*KeyTxtM123D) rjmp KeySetParam ; setze Parameter ; ; Setze den Erhaltungsstrom auf den Wert in sKeyNW ; KeyM124R: ldi XH,HIGH(sCh1MC) ; X auf Erhaltungsstrom ldi XL,LOW(sCh1MC) ldi ZH,HIGH(2*KeyTxtM124D) ; Z auf Text ldi ZL,LOW(2*KeyTxtM124D) rjmp KeySetParam ; setze Parameter ; KeyTxtM121D: .DB "Entladen ok",0 ; KeyTxtM122D: .DB "Laden ok",0,0 ; KeyTxtM123D: .DB "Kapaz. ok",0 ; KeyTxtM124D: .DB "Erhalt. ok",0,0 ; ; ; Menueeintraege Befehl ausfuehren ; KeyM13: clr rmp sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM13) ; Menuetext ldi XL,LOW(2*KeyTxtM13) rcall KeyMOut ; Zeige Menue an KeyM13a: ldi rmp,LOW(KeyM1) ; Setze linke Sprungadresse sts sKeyJ1,rmp ldi rmp,HIGH(KeyM1) sts sKeyJ1+1,rmp ldi rmp,LOW(KeyM13Up) ; Setze mittlere Sprungadresse sts sKeyJ2,rmp ldi rmp,HIGH(KeyM13Up) sts sKeyJ2+1,rmp ret ; ; Menue 13 Up Tastenroutine ; KeyM13Up: lds rmp,sKeyNC inc rmp sts sKeyNC,rmp ldi XH,HIGH(2*KeyTxtM13) ; Menuetext ldi XL,LOW(2*KeyTxtM13) rjmp KeyMOut ; ; Befehls-Menues, setzt Status auf Wert in sKeyCh ; KeyM131: ; setze sState auf Entladen ldi rmp,0x01 rcall KeyChSet clr rmp rcall KeySetPwm rcall KeyClrCap ldi rmp,0x08 ; setze sState auf Entladen lds R0,sKeyCh KeyM131b: lsl rmp dec R0 brne KeyM131b or rPwmOut,rmp ; setze Entladebit des PWM-Kanals ldi XH,HIGH(KeyM13a) ldi XL,LOW(KeyM13a) ldi ZH,HIGH(2*KeyTxtM131D) ldi ZL,LOW(2*KeyTxtM131D) rjmp KeyMDone ; KeyM132: ; setze sState auf Laden ldi rmp,0x01 rcall KeyChSet rcall KeyClrUnl ; loesche Entladebit rcall KeyClrCap ldi rmp,128 ; setze PWM auf 1100 mV rcall KeySetPwm ldi XH,HIGH(KeyM13a) ldi XL,LOW(KeyM13a) ldi ZH,HIGH(2*KeyTxtM132D) ldi ZL,LOW(2*KeyTxtM132D) rjmp KeyMDone ; KeyM133: ; setze sState auf Erhaltungsladung ldi rmp,0x01 rcall KeyChSet rcall KeyClrUnl ; loesche Entladebit ldi rmp,128 ; setze die PWM auf 1100 mV rcall KeySetPwm ldi XH,HIGH(KeyM13a) ldi XL,LOW(KeyM13a) ldi ZH,HIGH(2*KeyTxtM133D) ldi ZL,LOW(2*KeyTxtM133D) rjmp KeyMDone ; KeyM134: ; loesche sState (Kanal aus) clr rmp rcall KeyChSet rcall KeyClrUnl ; loesche Entladebit clr rmp ; PWM auf Null rcall KeySetPwm rcall KeyClrCap ; Kapazitaet loeschen ldi XH,HIGH(KeyM13a) ldi XL,LOW(KeyM13a) ldi ZH,HIGH(2*KeyTxtM134D) ldi ZL,LOW(2*KeyTxtM134D) rjmp KeyMDone ; KeyTxtM131D: .DB "Entladen",0,0 KeyTxtM132D: .DB "Laden",0 KeyTxtM133D: .DB "Erhalten",0,0 KeyTxtM134D: .DB "Aus",0 ; ; =================== Menuetabellen =================== ; ; Menue 1 ; KeyTxtM1: .DB "Auswahl...# ",0,19 .DW KeyM11 .DB "Setze...# ",0,17 .DW KeyM12 .DB "Befehl...#",0,18 .DW KeyM13 .DW 0xFFFF ; KeyTxtM11: .DB "Akku-Id...# ",0,19 .DW KeyM111 .DB "Kanal...# ",0,17 .DW KeyM112 .DB "Direktlade# ",0,19 .DW KeyM113 .DW 0xFFFF ; KeyTxtM12: .DB "Entlade...# ",0,19 .DW KeyM121 .DB "Laden...# ",0,16 .DW KeyM122 .DB "Kapazit...# ",0,19 .DW KeyM123 .DB "Erhaltg...# ",0,19 .DW KeyM124 .DW 0xFFFF ; KeyTxtM13: .DB "Entlade...# ",0,19 .DW KeyM131 .DB "Lade...#",0,16 .DW KeyM132 .DB "Erhaltg...# ",0,19 .DW KeyM133 .DB "Aus...# ",0,15 .DW KeyM134 .DW 0xFFFF ;