
;======================  Unterprogramme(Funktionen)=================================
; 
; clr_lcd:		   Löscht alle 4 Zeilen
; init_display:    Initialisierung des LC-Displays     
;  _printchar:     Gibt das Zeichen in R7 auf dem Diaplay in ASCII aus            
; _print_hex:      Gibt die Zahl in R7 in HEX auf dem Display aus (00 bis FF)
; _print_lcd:      Schreibt einen String auf das Display (ab Label "TEXT", Ende: 00h)
;  _moveto:        bewegt Cursor an Displayposition (R7->Zeile,R5->Spalte)
; cursor_off:      Cursor unsichtbar
; cursor_on:       Cursor sichtbar
; _print_digit:    Inhalt von R7 wird als zweistellige Dezimalzahl ausgegeben
; _print_digit2:   Inhalt von R7 wird als dreistellige Dezimalzahl ausgegeben
;====================================================================================
;Hilfs-Unterprogramme
; SR_Check_Busy:   Prüft ob Display noch beschäftigt (Busy-Flag) 
; SR_Command:      Schreibt ein Kommando an das Display (Akku)
;====================================================================================

$NOMOD51		        ;Ausschalten der Reg51.inc(sonst Fehlermeldung)
#include <REG936.H>		;Registerdef. 
#include <LCD.h>



                     	;Die Einsprunglabels der Unterprogramme 
PUBLIC  _printchar  	;werden als PUBLIC deklariert und können
PUBLIC  init_display    ;in anderen Modulen verwendet werden      
PUBLIC  _print_hex
PUBLIC  _print_lcd        
PUBLIC  _moveto
PUBLIC  SR_Command
PUBLIC  cursor_off
PUBLIC  cursor_on
PUBLIC  _print_digit
PUBLIC  clr_lcd
PUBLIC  _print_digit2       
       
       
       
				                                                                     

?PR?LCD	SEGMENT  CODE	;"?PR?LCD" ist Name eines rel. Codesegments
	RSEG	?PR?LCD	    ;und beginnt ab hier

;Display löschen
clr_lcd:
	mov   a,#0x01  	   ;Clear Display                   
    lcall  SR_Command                
	lcall del4100us
	ret

;==============================================================================
;***********Unterprogramme*****************************************************
;==============================================================================
; Stringausgabe auf Display
;==============================================================================
;   Übergabewert: dptr in R7(LSB), R6(MSB)
;   Ergebnis: --
;   verw. Reg.: DPTR, ACC, R7
;==============================================================================
; Bemerkungen: Der String muß mit '0' terminiert sein
;==============================================================================
 _print_lcd:                              
  	push  ACC                           
  	push  PSW                            
	mov dph,R6
	mov dpl,R7
  	                        
LAB_Print2:
  	mov   A,#0                           
  	movc  A,@A+DPTR
 	mov R7,A                       
  	cjne  A,#0,LAB_Print1
                
  	pop   PSW                            
  	pop   ACC                            
  	ret                                  
LAB_Print1:
  	                            
  	lcall  _printchar                  
  	inc   DPTR                           
  	sjmp  LAB_Print2                     
                                                                             
;===========================================================================
; HEX-Ausgabe einer Zahl auf dem Display
;=============================================================================
;   Parameter: R7 enthält char-Zahl
;   Ergebnis: ---
;   verw. Reg.: ---
;   glob. Var.: ---
;=============================================================================
; Bemerkungen: Die 8-Bit Zahl in R7
;              wird an der aktuellen Position als XX-Hex im Display ausgegeben.
;=============================================================================
_print_hex:                          
   	push  ACC                           
   	push  PSW
  	push 7
   	mov A,7                             
   	push  ACC                           
                                     
   	swap  A                             
   	anl   A,#0fh                        ; High-Nibble ausmaskieren
   	clr   C                             ;
   	subb  A,#10                         ;
   	jc    M_Pr_BCD_ok1                  ;
   	add   A,#7 
                         
M_Pr_BCD_ok1:                          
   	add   A,#('0'+10)
   	mov 7,A                      
   	lcall  _printchar                   ;high-Nibble fertig.                                       ;
   	pop   ACC                           ;
   	anl   A,#0fh                        ; low-Nibble ausmaskieren
   	clr   C                             ;
   	subb  A,#10                         ;
   	jc    M_Pr_BCD_ok2                  
   	add   A,#7 
                         
M_Pr_BCD_ok2:                          
   	add   A,#('0'+10) 
   	mov 7,A                  
   	lcall  _printchar 
   	pop 7                
   	pop   PSW                           
   	pop   ACC                           
   	ret                                 
                                           
;==============================================================================
; Ausgabe eines Characters an der aktuellen Cursorposition
;==============================================================================
;     Aufruf: R7 enthält Character
;   Ergebnis: --
; verw. Reg.: --
;==============================================================================
; Bemerkungen:
;==============================================================================
 _printchar:                         
  	push  PSW                            
  	push  ACC
  	mov A,7                          
  	push  ACC                            
  	lcall SR_Check_Busy                  
  	mov   Display,#0                   
  	setb  Display_RS                  
  	clr   DISPLAY_RW;  	
  	anl   A,#0f0h                         
  	orl   Display,A                    
  	setb  Display_E                    
	nop
	nop
	nop
  	clr   Display_E                    
  	mov   Display,#0                   
  	setb  Display_RS                   
  	pop   ACC                            
  	swap  a
  	anl   A,#0f0h                         
  	orl   Display,A                    
  	setb  Display_E                    
	nop
	nop
	nop
  	clr   Display_E                    
  	pop   ACC                            
  	pop   PSW  
    lcall del100us    //lcall del4100us                     
  	ret                                  
                                       
;==============================================================================
; Routine zur Ausgabe eines Kommandos an ein Display
;==============================================================================
;     Aufruf: Kommando im ACC
;   Ergebnis: --
; verw. Reg.: --
;==============================================================================
; Bemerkungen:
;==============================================================================
SR_Command:                            
  push  PSW                            
  push  ACC                            
  push  ACC                            
  lcall SR_Check_Busy                  
  mov   Display,#0                   
  anl   A,#0f0h                         
  orl   Display,A 
  setb  Display_E
  nop
  nop
  nop                    
  clr   Display_E                    
  mov   Display,#0                   
  pop   ACC                            
  swap  a
  anl   A,#0f0h                         
  orl   Display,A
  setb  Display_E                    
  nop
  nop
  nop
  clr   Display_E                    
  pop   ACC                            
  pop   PSW                            
  lcall del100us   //lcall del4100us
  ret                                  
                                       
;==============================================================================
; Bewegt Cursor zu den geforderten Koordinaten im Display
;==============================================================================
;     Aufruf: R7 enthält Zeile (0,1), R5 enthält Spalte (0..40)
;   Ergebnis: --
; verw. Reg.: --
;==============================================================================
; Bemerkungen: R7 enthält Zeile (0..1), R5 enthält Spalte (0..40d)
;==============================================================================


/*****************************************************************************/
/*Anpassung an EA DIP204B-4NLW Display mit KS0073 Controller  (4x20 Zeichen) */
/*																			 */
/*Ersteller: Daniel Simon													 */
/*Datum:     30.11.2006														 */
/*																			 */
/*Adressen																	 */
/*1. Zeile $00..$13															 */
/*2. Zeile $20..$33															 */
/*3. Zeile $40..$53															 */
/*4. Zeile $60..$73															 */
/*****************************************************************************/

_moveto:                             
  	push  0                              
  	push  ACC                            
  	push  B                              
  	push  PSW
  	mov A,R7                            
  	mov   B,#20h 
	mov c,ACC.1		;Bei Zeile 3 oder 4 ist 2.Bit = 1
	JC Zeile        ;somit spring zu Zeile             
  	mul   AB                             
  	add   A,R5 
	ljmp Ende
Zeile:
	clr c
	subb A, #01h
	mul AB
	add A,R5
	add A,#20h	   ;und addiere 0x20 dazu
Ende:                          
  	setb  ACC.7                          
  	lcall SR_Command                     
  	pop   PSW                            
  	pop   B                              
  	pop   ACC                            
  	pop   0                                  
;===============================================================  
  
                                ;       
;==============================================================================
; Warten, bis Display bereit für nächsten Befehl
;==============================================================================
;   Aufruf: --
;   Ergebnis: Rücksprung, wenn Display nicht mehr Busy
;   verw. Reg.: --
;==============================================================================
; Bemerkungen:
;==============================================================================
SR_Check_Busy:                         
  	push  PSW                           
  	push  Display                      
  	mov   Display,#0                   
  	setb  Display_RW                  
  	clr   DISPLAY_RS
LAB_Display_Busy:                      
  	setb  Display_E 
	nop
	nop 
	nop        
  	mov   C,Display_busy               ; erster Lesezyklus
	nop	
  	clr   Display_E                    
  	setb  Display_E                    ; zweiter Lesezyklus
	nop
	nop
	nop
  	clr   Display_E                    
  	jc    LAB_Display_Busy               
  	clr   DISPLAY_RW
  	pop   Display                      ; Wiederherstellen von RS und RnW
  	pop   PSW                           
  	ret                                  
                                       
;==============================================================================
; Initialisierung des Displays
;==============================================================================
;   Aufruf: kein Parameter
;   Ergebnis: keines
; verw. Reg.: ACC
;==============================================================================
; Bemerkungen:
;==============================================================================



init_display: 			 
             lcall del4100us
			 lcall del4100us
			 lcall del4100us
			 mov   Display,#0x30         ;Function set -8bit-
			 nop
			 setb DISPLAY_E
			 nop
			 nop
			 nop
			 clr DISPLAY_E
             lcall del4100us
			 lcall del4100us
			 lcall del4100us

		     mov   Display,#0x30         
			 nop
			 setb DISPLAY_E
			 nop
			 nop
			 nop
			 clr DISPLAY_E
             lcall del4100us
			 							 
			 mov   Display,#0x30         
			 nop
			 setb DISPLAY_E
			 nop
			 nop
			 nop
			 clr DISPLAY_E				  //Init 3   //Programmiermodus
             lcall del4100us
			 

			 mov   Display,#0x20 	;Function Set: 4-Bit        
			 nop
			 setb DISPLAY_E
			 nop
			 nop
			 nop
			 clr DISPLAY_E
             lcall del4100us
			 
			 
             mov   a,#0x28     	;Function Set: 4 Bit, 2 Zeilen, 5x7 Punkte                
             lcall  SR_Command                
			 lcall del4100us			 

			 mov   a,#0x24     	;Function Set: 4 Bit, RE = 1                
             lcall  SR_Command                
		     lcall del4100us

			 mov   a,#0x09     	;Extendet Function Set: 4 Zeilen, 5x7 Punkte                
             lcall  SR_Command                
			 lcall del4100us

			 mov   a,#0x20     	;Fuction Set: 4 Bit, 5x7 Punkte               
             lcall  SR_Command                
			 lcall del4100us

			 mov   a,#0x0C      ;Display ein,Cursor aus                   
             lcall  SR_Command                
			 lcall del4100us

			 mov   a,#0x01  	;Clear Display                   
             lcall  SR_Command                
			 lcall del4100us

			 mov   a,#0x06  	;Entry Mode Set: Cursor wird inkrementiert                   
             lcall  SR_Command                
			 lcall del4100us
		      
             ret

del100us:    ;********************
             ; Etwas warten (400 Cycles eq. 108us LPC)
             ; nutzt r7     (eq. 400us @12MhzLAB537 )
             ;********************
             mov   r7,#200
del1:        djnz  r7,del1
             ret

del4100us:   mov   r6,#50                  ;delay 5,5 ms(LPC)
del2:        lcall del100us
             djnz  r6,del2
             ret

             ret                      

;==============================================================================
; Cursor ein-/ausschalten
;==============================================================================
;     Aufruf: kein Parameter
;   Ergebnis: keines
; verw. Reg.: --
;==============================================================================
; Bemerkungen:
;==============================================================================
cursor_off:  	push    ACC            ;
                mov     A,#0CH         ;
                lcall   SR_COMMAND     ;
                pop     ACC            ;
                ret                    ;
                                       ;
cursor_on:   	push    ACC            ;
                mov     A,#0EH         ;
                lcall   SR_COMMAND     ;
                pop     ACC            ;
                ret                    ;
 
;=============================================================================
; Bemerkungen: Die zweistellige BCD-Zahl, deren LSB durch R0 bestimmt wird,
;              wird an der aktuellen Position im Display ausgegeben.
;              Es wird vorher ein Leerzeichen ausgegeben.
;=============================================================================
SR_Print_BCD:                          
   	push  0                             
   	push  ACC                           
   	push  PSW                           
   	mov   R0,A                          ; sichern
   	swap  A                             
   	anl   A,#0fh                        ; low-Nibble ausmaskieren
   	add   A,#'0'                        
   	lcall  _printchar                 
   	mov   A,R0                                                
   	anl   A,#0fh                        ; low-Nibble ausmaskieren
   	add   A,#'0'                        
   	lcall  _printchar                 
   	pop   PSW                           
   	pop   ACC                           
   	pop   0                             
   	ret                                 
                                                                                                         
;***********************************************************
;SUBROUTIN _print_digit 
;************************************************************



_print_digit:   PUSH    PSW                   
                PUSH    B
                PUSH    ACC                   ;UEBERGABE AKKU
		mov A,R7
                
			/*	MOV     B,#100                ;ACC := (ACC DIV B)+48
                DIV     AB
                ADD     A,#48
		mov R7,A
                LCALL  _printchar             ;WRITE 100

                MOV     A,B                  ;ACC := (ACC DIV B)+48	 */
                MOV     B,#10
                DIV     AB
                ADD     A,#48
		mov R7,A
                LCALL    _printchar          ;WRITE 10

                MOV     A,B                  ;ACC := ACC + 48
                ADD     A,#48
		mov R7,A
                LCALL    _printchar          ;WRITE 1

                POP     ACC                  ;RESTORE REGISTERS
                POP     B
                POP     PSW
                RET			




_print_digit2:   PUSH    PSW                   
                PUSH    B
                PUSH    ACC                   ;UEBERGABE AKKU
		mov A,R7
                
				MOV     B,#100                ;ACC := (ACC DIV B)+48
                DIV     AB
                ADD     A,#48
		mov R7,A
                LCALL  _printchar             ;WRITE 100

                MOV     A,B                  ;ACC := (ACC DIV B)+48	 
                MOV     B,#10
                DIV     AB
                ADD     A,#48
		mov R7,A
                LCALL    _printchar          ;WRITE 10

                MOV     A,B                  ;ACC := ACC + 48
                ADD     A,#48
		mov R7,A
                LCALL    _printchar          ;WRITE 1

                POP     ACC                  ;RESTORE REGISTERS
                POP     B
                POP     PSW
                RET			
END 
