;********************************************************************* ; File: 03_LCD_LiIon.INC ; Author: Ottmar ; Date: 21.05.2022 ;********************************************************************* ; Subroutines in file 03_LCD_16F1827_LiPo_1S_Lader_V07.INC ; Out_All_Measurments ; Out_ADC: ; B2D: ; Sub16: ; ADD_16: ; Leading_Zero: ; LcdOut_Table_1: ; Out_ChargeStart: ; Out_ChargeEnd: ; Out_ChargeTime_Start: ; Out_ChargeTime: ;********************************************************************* Out_All_Measurments: CALL Meas_Vdd ;supply voltage to LCD CALL Meas_Vdd_Out ;Ausgabe Vakku im LCD CALL Meas_Vdrain CALL Meas_Vdrain_Out CALL Meas_Vakku ;Vdd-Vdrain=Vakku CALL Meas_Vakku_Out CALL Meas_Vref CALL Meas_Vref_Out CALL Meas_Vshunt CALL Meas_Vshunt_Out ; CALL WiperValue_Out ;Actual Wipervalue (MCP4151.P0W) RETURN Out_ADC: ; btfss Flags,NEW_SEC ; RETURN ; Übergabe im WREG: DDRAM-Adresse z.B. LIN2+.4 ; Ausgabe: Umess = "0,000mV" ; movlw LINE1+d'8' ;Ausgabe in Zeile 1 ab Digit 8 CALL OutDDRAM_Addr ;Instruction+DDRAM-Adr -> LCD ; movf BCD3,w ;Binärzahl->WREG CALL OutLcd_Ascii ;ASCII-Char WREG->Ascii -> LCD ; ; btfss Flags,V_VDD5V ;insert ";" after BCD3 ; ;Vdd mit Kommastelle ausgeben und BCD3=0 setzen ; GOTO out_adc_bcd2 ; movlw "," ; CALL OutLcd_Data ; movlw .0 ;Vdd set BD0=0 ; movwf BCD0 ; out_adc_bcd2: movf BCD2,w CALL OutLcd_Ascii movf BCD1,w CALL OutLcd_Ascii movf BCD0,w CALL OutLcd_Ascii RETURN ;********************************************************************* B2D: ;16Bit Binär zu Dezimal max 4 Stellen ;Die Binärzahl (< 10000) steht in ACb1,ACb0 ;Ergebnis: BCD3, BCD2, s10er, BCD0 ; clrf BCD3 ;Dezimal Tausender clrf BCD2 ; Hunderter clrf BCD1 ; Zehner clrf BCD0 ; Einer ; movlw 0x03 ;Test auf Tausender 1000d = 0x03E8 movwf BCb1 movlw 0xE8 movwf BCb0 CALL B2Da ;Subtrahieren Übertrag addieren movwf BCD3 ; clrf BCb1 ;Test auf hunderter 100d = 0x0064 movlw 0x64 movwf BCb0 call B2Da movwf BCD2 ; clrf BCb1 ;Test auf Zehner 10d = 0x000A movlw 0x0A movwf BCb0 call B2Da movwf BCD1 movfw ACb0 movwf BCD0 ;Rest = Einer RETURN ;********************************************************************* B2Da: clrf cntB2D B2Sb: incf cntB2D, f ;wie oft abgezogen? CALL Sub16 ;f:=f-xw btfss STATUS, C ;zu oft abgezogen? goto B2Sb ;nein: noch einmal CALL ADD_16 ;f:=f+xw decf cntB2D, w ;weil immer 1 zuviel gezählt wird RETURN ;********************************************************************* ;16 Bit Subtraktion, bei Überlauf (neg. Ergebnis) ist C gesetzt Sub16: ;16 bit f:=f-xw bcf Flags,ERR ;Flags,0 löschen movf BCb0,w ;ACb0:=ACb0-BCb0 SUBWF ACb0, f btfsc STATUS,C GOTO Sub16a movlw 0x01 ;borgen von ACb1 SUBWF ACb1,f btfss STATUS,C bsf Flags,ERR ;Flags,0=1 Unterlauf Sub16a: movf BCb1,w ;ACb1:=ACb1-BCb1 SUBWF ACb1,f btfss STATUS,C bsf Flags,ERR ;Flags,0=1 Unterlauf bcf STATUS,C ;C-Flag invertieren btfsc Flags,ERR ;Flags,0=1? Fehler aufgetreten? bsf STATUS,C ;JA RETURN ;Nein, fertig ;********************************************************************* ADD_16: ; 16 Bit adition, ; Acb1:0 = ACb1:0:BCb1:0, C-Flag is set by overflow movf BCb0,w ;xWert_0 nach W addwf ACb0,f ;Bin_Low := Bin_Low + xWert_0 movf BCb1,w ;xWert_1 nach W btfsc STATUS,C ;falls ein Überlauf auftrat: incfsz BCb1,w ;xWert_1+1 nach W addwf ACb1,f ;Bin_High := Bin_High + xWert_1 RETURN ;********************************************************************* Leading_Zero: NOLIST ;Mittels des FSR0 und INDF0 werden die führenden Nullen mit dem ;Wert 240 = "kein Zeichen" überschrieben. Bei der späteren Ausgabe ;des Ascii-Codes wird der Wert 240 + 48 zum Leerzeichen Ascii 32 (" ") ; ;ENHANCED midrange MUC verwenden FSR0 INDF0, FSR1,INDF1, für den ; gesamten Speicherbereich (16Bit) ;STANDARD midrange MUC verwenden nur FSR, INDF für ;Wenn die Register in Page 0 liegen, können FSR0 und INDF0 ohne die ;H-Bytes FSR1, INDF1 verwendet werden. ; LIST ; movlw d'3' ;0-3=4stellig Digit 0 darf nicht movwf cntDig ;mit Leerstelle beschrieben werden. ; movlw LOW BCD3 ;Pointer auf MSB Register-Adresse, page 0 Leading_Zero1 movwf pntr0 ;Aktuelle Adresse zwischenspeichern movwf FSR0 ;Adresse der Variablen ins FSR0 movf INDF0,w ;Variablenwert ins WREG bcf STATUS,Z xorlw d'0' ;Vergleich WREG = 0? btfss STATUS,Z ;z=1? Variable = 0? GOTO Leading_Zero0 ;Nein movf pntr0,w ;aktuelle Adresse des Registers movwf FSR0 ;ins FSR schreiben movlw d'240' ;Ja, in Leerzeichen konvertieren movwf INDF0 ;und in Variable zurückschreiben incf pntr0,w ;Pointer auf Register decfsz cntDig,f ;Bit 0 erreicht? GOTO Leading_Zero1 Leading_Zero0 RETURN ;********************************************************************* LcdOut_Table_1: ;PAGEGRENZEN ÜBERSCHREITENDE LUT NOLIST ; Die Texttabelle kann 1-255 Zeilen umfassen, wobei nur aufeinander ; folgende Zeilen ausgegeben werden können. ; CBLOCK ; pntr1, pntr0 ;Low-pointer auf LUT ; tmpLines ;ZeilenZähler ; ENDC ; Tsbellenformat: ; dt LINE1+.0, "Bin", 80h ; dt LINE2+.0, "Dez", 80h ; ; Aufruf: ; movlw HIGH table_Test ;Zeiger auf LUT (High-Byte der Adresse) ; movwf pntr0 ; ; movlw LOW table_Test ;Zeiger auf LUT (Lowh-Byte der Adresse) ; movwf pntr0 ; movlw .2 ;z.B. 2 Zeilen der LUT ausgeben ; CALL LcdOut_Table_1 ;Liest Bytes aus LUT, gibt Text im LCD aus ; LIST movwf tmpLines ;auszugebende Zeilenzahl incf tmpLines,f ;wegen nachfolgendem "decfsz" (tmpLines-1) ; ;--Prüfen: pntr0=0? Dann muss auch pntr1 decremetniert werden! clrw ;WREG auf 0 setzen xorwf pntr0,w ;Vergleich pntr0 = 0 durchführen btfsc STATUS,Z ;Z=1, pntr0=0? decf pntr1,f ;JA, H-Pointer -1 decf pntr0,f ;L-Pointer-1 wegen incf in LcdOut_GetChar ; lcdout_nextline: ;übertragt DDRAM-Startadresse an das LCD decfsz tmpLines,f ;Z=1, gesamter Text ausgegeben? GOTO $+2 ;NEIN, PCL+2 weiter mit "CALL LcdOut_Char" GOTO lcdout_tableend ;JA, Ausgabe beenden CALL LcdOut_Char ;NEIN, DDRAM-ADr des 1. auszugebendes Digtits CALL OutDDRAM_Addr ;Adressbefehl im WREG an LCD übergeben ; lcdout_nextchar: ;Gibt Ascii-Zeichen in Zeile,Digit aus CALL LcdOut_Char ;Value aus Tabelle befindet sich im WREG ; ; Infolge des Überlaufs bei der Addition im WREG 80h+80h=255->0 bei ; Erreichen des Zeilenendes, setzt das Carryflag C=1. Dies ist bei ; den Ascii codes 0-127 nicht der Fall. addlw 0x80 ;WREG + 128 btfsc STATUS,C ;bit7=1, Zeilenende erreicht? GOTO lcdout_nextline ;JA, neue Zeile,Digit lesen ; ; DAs Zeilenende ist nicht erreicht und der ursprüngliche Wert im ; WREG muss wieder hergestellt werden. Dazu wird zum WREG 7fh (.127) ; addiert. Z.B. Ascii .72 "H": .72+.128(80h)=.200 ; 200+127(7Fh) = 327 = 255 -> .72=Ascii"H" andlw 0x7F ;Nein +127 Zeichen wieder herstellen CALL OutLcd_Data ;Zeichen ausgeben GOTO lcdout_nextchar ; LcdOut_Char: ; Der Wert des Pointers "pntr0" wird in den Programmzähler "PCL" ; übertragen. Hierdurch springt das Programm auf die Adresse(PCL) ; liest dort 1 Byte ins WREG und führt danach den auf "movwf PCL" ; folgenden Befehl (RETURN) ; bcf STATUS,Z incf pntr0,f ;Low-Pointer + 1 btfsc STATUS,Z ;Pagewechsel, Überlauf 255 -> 0 eingetreten? incf pntr1,f ;JA High-Pointer +1 movf pntr1,w ;H-Pointer über WREG movwf PCLATH ;in PCLATH kopieren movf pntr0,w ;Low-Pointer ins WREG und in PCL kopieren movwf PCL ;springt dann nächsten Adresser in der Tabelle lcdout_tableend: ; Rückgabe "Char" im WREG RETURN ;********************************************************************* Out_ChargeTime_Start: movlw LINE4+.0 CALL OutDDRAM_Addr ;LCD-Ausgabe Startzeile+Digit movlw .0 ;schreibt Leerzeichen in Zeile 4, movwf d6 ;entfernt 'Push [START]' lcd_clear_line4: movlw " " ;Leerzeichen CALL OutLcd_Data ;schreibt in LCD in LINE4,Digit(d6) incf d6,f movlw LCD_DIGITS ;LCD4x20 Digits 0-19 subwf d6,w btfss STATUS,Z GOTO lcd_clear_line4 ; ; clear all clock-digits, display "START 00:00:00" movlw LINE4+.0 CALL OutDDRAM_Addr ;LCD-Ausgabe Startzeile+Digit movlw "S" CALL OutLcd_Data movlw "T" CALL OutLcd_Data movlw "A" CALL OutLcd_Data movlw "R" CALL OutLcd_Data movlw "T" CALL OutLcd_Data ; clrf Zstd ;clear all clock-digits clrf Estd clrf Zmin clrf Emin clrf Zsec clrf Esec ; Out_ChargeTime: movlw LINE4+.8 CALL OutDDRAM_Addr ;display clock-digits "hh:mm:ss" movf Zstd,w CALL OutLcd_Ascii movf Estd,w CALL OutLcd_Ascii movlw ":" CALL OutLcd_Data ; movf Zmin,w CALL OutLcd_Ascii movf Emin,w CALL OutLcd_Ascii movlw ":" CALL OutLcd_Data ; movf Zsec,w CALL OutLcd_Ascii movf Esec,w CALL OutLcd_Ascii RETURN ;********************************************************************* Out_Lcd_NoBatt: movlw LINE4+.0 CALL OutDDRAM_Addr ;LCD-Ausgabe Startzeile+Digit movlw .0 ;schreibt Leerzeichen in Zeile 4, movwf d6 ;entfernt 'Push [START]' out_lcd_nobatt_line4: movlw " " ;Leerzeichen CALL OutLcd_Data ;schreibt in LCD in LINE4,Digit(d6) incf d6,f movlw LCD_DIGITS ;LCD4x20 Digits 0-19 subwf d6,w btfss STATUS,Z GOTO out_lcd_nobatt_line4 ; movlw HIGH tbl_no_batt movwf pntr1 movlw LOW tbl_no_batt movwf pntr0 movlw .1 ;Zeilen 1-4 im LCD ausgeben CALL LcdOut_Table_1 RETURN ;********************************************************************* Out_ChargeEnd: movlw LINE4+.0 CALL OutDDRAM_Addr ;LCD-Ausgabe Startzeile+Digit movlw "E" CALL OutLcd_Data movlw "N" CALL OutLcd_Data movlw "D" CALL OutLcd_Data movlw "E" CALL OutLcd_Data movlw "!" CALL OutLcd_Data ; movlw .5 CALL Delay100ms ; movlw LINE4+.0 CALL OutDDRAM_Addr ;LCD-Ausgabe Startzeile+Digit movlw " " CALL OutLcd_Data movlw " " CALL OutLcd_Data movlw " " CALL OutLcd_Data movlw " " CALL OutLcd_Data movlw " " CALL OutLcd_Data ; movlw .5 CALL Delay100ms RETURN ;*********************************************************************