;**************************************************************
;*  	Pinbelegung
;*	----------------------------------	
;*	PORTA: 	0 - 
;*		1 -
;*		2 -	
;*		3 -
;*		4 Takteingang
;*	PORTB:	0 LCD Display E
;*		1 LCD Display RS		
;*		2 
;*		3 	
;*		4-7 LCD Display D4 .. D7 
;*	
;**************************************************************
;

	list		p=16f716		; list directive to define processor
	#include	<P16F716.inc>		; processor specific variable definitions
	
	__CONFIG    _CP_OFF & _VBOR_25 & _BOREN_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC

; Variablen festlegen
LcdDaten  	Equ	0x20
LcdStatus 	Equ	0x21
loops		EQU	0x22	; Wait-Schleife
loops2		EQU	0x23	; Wait-Schleife
pportb		EQU	0x24


Init
	clrf	PORTA		
	clrf	PORTB
	bsf     STATUS, RP0	; Bank 1
	clrf    OPTION_REG 
	movlw	B'11111000'	; RA0 .. RA2 outputs, RA3, RA4 input 
	movwf	TRISA		; 
	movlw	B'00000000'	; PortB alle outputs 
	movwf	TRISB
	bcf     STATUS, RP0	; Bank 0
	clrf	PORTA		
	clrf	PORTB		
				
	clrf   INTCON   

	call	InitLCD		; Display initialisieren

; am LCD "Hallo" ausgeben
Main	
	movlw	'H'
	movwf	LcdDaten
	call	OutLcdDaten
	movlw	'a'
	movwf	LcdDaten
	call	OutLcdDaten
	movlw	'l'
	movwf	LcdDaten
	call	OutLcdDaten
	movlw	'l'
	movwf	LcdDaten
	call	OutLcdDaten
	movlw	'o'
	movwf	LcdDaten
	call	OutLcdDaten

	movlw	D'255'		; 250 ms Pause nach dem Einschalten
	movwf	loops	
	call	WAIT	

Goto Main

WAIT
top      movlw   .249           ; timing adjustment variable (1ms)  
         movwf   loops2
top2     nop                     ; sit and wait (Schleifenlänge 10T)
         nop
         nop
         nop
         nop
         nop
	 nop			
         decfsz  loops2, F      ; inner loops complete?
         goto    top2           ; no, go again
                                ;
         decfsz  loops, F       ; outer loops complete?
         goto    top            ; no, go again
         retlw   0              ; yes, return from subWAIT

;**************************************************************
; LCD-Routinen
;	
; Initialisierung des LCD-Displays
InitLCD
	movlw	D'255'		; 250 ms Pause nach dem Einschalten
	movwf	loops	
	call	WAIT	

	movlw	B'00110000'	; 1
	movwf	PORTB
	bsf	PORTB,1
	nop	
	nop
	nop
	nop
	bcf	PORTB,1
	movlw	D'150'		; 50 ms Pause
	movwf	loops
	call	WAIT
	
	movlw	B'00110000'	; 2
	call	Control8Bit
	movlw	B'00110000'	; 3
	call 	Control8Bit
	movlw	B'00100000'	; 4
	call 	Control8Bit

	
	movlw	B'00101000'	; 5 function set, 4-bit  2-zeilig,  5x7
	call	OutLcdControl	
	movlw	B'00001000'	; 6 display off
	call	OutLcdControl
	
	movlw	B'00000001'	; löschen und cusor home
	call	OutLcdControl
	
	movlw	B'00000110'	; 7 entry mode, increment, disable display-shift
	call	OutLcdControl
	
	movlw	B'00001100'	; 9 display on
	call	OutLcdControl
	return

; ein Steuerbyte 8-bittig übertragen
Control8Bit
	movwf	PORTB
	bsf	PORTB, 1
	nop
	nop
	nop
	nop
	bcf	PORTB, 1
	movlw	D'5'
	movwf	loops
	call 	WAIT
	return



; ein Byte mit Steuerdaten von LcdDaten zum Display übertragen
OutLcdControl
	movwf	LcdDaten
	movf	LcdDaten, w
	andlw	H'F0'
	movwf	pportb		; Hi-teil Daten schreiben
	movfw	pportb
	movwf	PORTB
;	bsf	pportb, LcdE
	movfw	pportb
	movwf	PORTB
	bsf		PORTB,1
	nop
	nop
	bcf	PORTB,1	; Disable LcdBus
	swapf	LcdDaten, w
	andlw	H'F0'
	movwf	pportb		; Hi-teil Daten schreiben
	movfw	pportb
	movwf	PORTB
;	bsf	pportb, LcdE
	movfw	pportb
	movwf	PORTB
	bsf	PORTB,1
	nop
	nop
	bcf	PORTB,1	; Disable LcdBus
	movlw	D'3'		; 50 ms Pause
	movwf	loops
	call	WAIT
	return

; ein Datenbyte von LCDDaten zum Display übertragen
OutLcdDaten
	movwf	LcdDaten
	movf	LcdDaten, w
	andlw	H'F0'
	movwf	PORTB
	bsf	PORTB,1
	bsf	PORTB,0	; Daten	
	nop
	nop
	bcf	PORTB,1	; Disable LcdBus
	bcf	PORTB,0
	swapf	LcdDaten, w
	andlw	H'F0'
	movwf	PORTB
	bsf		PORTB,1
	bsf		PORTB,0	; Daten	
	movfw	pportb
	movwf	PORTB	
	nop
	nop
	bcf	PORTB,1	; Disable LcdBus	
	bcf	PORTB,0	;
	movlw	D'3'		; 50 ms Pause
	movwf	loops
	call	WAIT
	return
end