hiho...

ich habe jetzt sozusagen 2 programmteile die ich noch innernander verschachteln muesste....

1. LCD ausgabe und tastatur eingabe...
Code:
	list p=16f877
;**************************************************************
;*  	Pinbelegung
;*	----------------------------------	
;*	PORTA: 	0 -
;*		1 -
;*		2 -
;*		3 -
;*		4 -
;*		5 -
;*		6 -
;*		7 -
;*
;*	PORTB:	0 LCD Display E
;*		1 			Keyboard 1 4 7 *
;*		2 LCD Display RS	Keyboard 2 5 8 0
;*		3 LCD Display R/W	Keyboard 3 6 9 #
;*		4 LCD Display D4 	---------I I I I
;*		5 LCD Display D5	-----------+ I I
;*		6 LCD Display D6	-------------+ I
;*		7 LCD Display D7	---------------+
;*	
;**************************************************************
; Tastatur mit LCD-Display
;
; Prozessor 16F877 
;
; Prozessor-Takt 4 MHz
;
; LCD & Keyboard am PortB
;
;**********************************************************
; Includedatei für den 16F877 einbinden

	#include <P16f877.INC>

	


; Konfiguration festlegen:
; Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein LV-programming
	__CONFIG	_PWRTE_ON & _WDT_OFF & _HS_OSC & _BODEN_OFF & _LVP_OFF


; Variablen festlegen
loops		equ	0x20	; Wartezeit für WAIT in Millisekunden
loops2		equ	0x21	; interner timer für wait
LcdStatus	equ	0x22	; Puffer für aus dem LCD ausgelesenes Statusbyte
LcdDaten	equ	0x23	; Puffer für zum LCD zu schreibendes Byte
Taste		equ	0x24	; Tastaturpuffer


; Konstanten festlegen
; das demonstriert die Nutzung des define-Kommandos im Assembler
; für LCD-Pins
#define	LcdE	PORTB,0		; enable Lcd
#define	LcdRw	PORTB,3		; read Lcd
#define	LcdRs	PORTB,2		; Daten Lcd (nicht control)	
#define LcdPort PORTB		; Datenbus des LCD (obere 4 Bit)
				; für Tastatur-Anschluß
#define	KRow1	PORTB,1		;Keyboard 1 4 7 *
#define	KRow2	PORTB,2		;Keyboard 2 5 8 0
#define	KRow3	PORTB,3		;Keyboard 3 6 9 #
#define	KLine1	PORTB,4		;Keyboard 1 2 3
#define	KLine2	PORTB,5		;Keyboard 4 5 6
#define	KLine3	PORTB,6		;Keyboard 7 8 9
#define	KLine4	PORTB,7		;Keyboard * 0 #

; Konstanten für OPTIN_REG and INTCON
; diese Werte werden im Programm wärend der Initialisierung verwendet
; sie hier abzulegen vereinfacht spätere Änderungen
Ini_con Equ	B'00000000'	; Interupt disable
Ini_opt	Equ	B'00000010'	; pull-up


;********************************************************
; Das Programm beginnt mit der Initialisierung

Init	bsf     STATUS, RP0	; Bank 1
	movlw   Ini_opt     	; pull-up Wiederstände ein
	movwf   OPTION_REG 
	movlw	B'00000000'	; PortB alle outputs 
	movwf	TRISB
	bcf     STATUS, RP0	; Bank 0
	clrf	PORTB		
	movlw   Ini_con     	; Interupt disable
	movwf   INTCON   

;Display initialisieren
	call	InitLcd

mainloop
	call	Tastfrei	; darauf warten, das keine Taste gedrückt ist	
	call	WAIT		

press
	call	Tastatur	; wird nun eine Taste gedrückt?
	movfw	Taste		; Tastencode nach w; Taste=0 dann Z=1  
	btfsc	STATUS, Z	; skip wenn Taste<>0 
	goto	press		; Tastencode=0 d.h. keine Taste gedrückt, weiter warten

	call	OutLcdDaten	; Tastencode am LCD ausgeben
	goto	mainloop	; auf ein neues



;*****************************************************
;+++LCD-Routinen**************************************
;*****************************************************
;LCD initialisieren, Begrüßung ausgeben

InitLcd
	movlw	D'255'		
	movwf	loops	
	call	WAIT		

	movlw	B'00110000'	; 1
	movwf	LcdPort
	bsf	LcdE
	nop	
	bcf	LcdE
	
	movlw	D'50'		; 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'00000001'	; löschen und cusor home
	call	OutLcdControl	
	movlw	B'00101000'	; 5 function set, 4-bit  2-zeilig,  5x7
	call	OutLcdControl	
	movlw	B'00001000'	; 6 display off
	call	OutLcdControl
	movlw	B'00000110'	; 7 entry mode, increment, disable display-shift
	call	OutLcdControl
	movlw	B'00000011'	; 8 cursor home, cursor home
	call	OutLcdControl
	movlw	B'00001111'	; 9 display on
	call	OutLcdControl

	movlw	'B'		
	call	OutLcdDaten
	movlw	'i'
	call	OutLcdDaten
	movlw	'n'
	call	OutLcdDaten
	movlw	'i'
	call	OutLcdDaten
	movlw	'_'
	call	OutLcdDaten
	movlw	'd'
	call	OutLcdDaten
	movlw	'a'
	call	OutLcdDaten
	movlw	'!'
	call	OutLcdDaten

	return

;*****************************************************
; ein Steuerbyte aus W 8-bittig übertragen
Control8Bit
	movwf	LcdPort
	bsf	LcdE
	nop
	bcf	LcdE
	movlw	D'10'
	movwf	loops
	call 	WAIT
	return

;*****************************************************
; darauf warten, daß das Display bereit zur Datenannahme ist
; dazu wird das busy-Bit des LCD abgefragt
LcdBusy
        bsf     STATUS, RP0	; make Port B4..7 input
	movlw	B'11110000'
	iorwf   TRISB, f 
        bcf     STATUS, RP0
BusyLoop		
	bcf	LcdRs		; Steuerregister
	bsf	LcdRw		; Lesen
	bsf	LcdE
	nop
	movf	LcdPort, w	; 4 obere Bits lesen (D7..D4)
	movwf	LcdStatus	; und in LcdStatus speichern
	bcf	LcdE
	nop
	bsf	LcdE
	nop			; 4 untere Bits lesen (D3..D0) und ignorieren
	bcf	LcdE
	btfsc	LcdStatus, 7	; teste bit 7
	goto	BusyLoop
	bcf	LcdRw
        bsf     STATUS, RP0	; make Port B4..7 output
	movlw	B'00001111'
	andwf   TRISB, f    
        bcf     STATUS, RP0
	return	

;*****************************************************
; aus W ein Byte mit Steuerdaten zum Display übertragen
OutLcdControl
	movwf	LcdDaten	; Byte in LcdDaten zwischenspeichern
	call	LcdBusy		; warten bis Display bereit ist
	movf	LcdDaten, w	; Byte zurück nach W holen
	andlw	H'F0'		; low-Teil löschen
	movwf	LcdPort		; Hi-teil Daten schreiben
	bsf	LcdE
	nop
	bcf	LcdE		; Disable LcdBus
	swapf	LcdDaten, w	; Byte verdreht nach W holen
	andlw	H'F0'		; High Teil löschen
	movwf	LcdPort		; Low-teil Daten schreiben
	bsf	LcdE
	nop
	bcf	LcdE		; Disable LcdBus
	return

;*****************************************************
; aus W ein Datenbyte (zum Anzeigen) an's Display übertragen
OutLcdDaten
	movwf	LcdDaten	; Byte in LcdDaten zwischenspeichern
	call	LcdBusy		; warten bis Display bereit ist
	movf	LcdDaten, w	; Byte zurück nach W holen
	andlw	H'F0'		; low-Teil löschen
	movwf	LcdPort		; Hi-teil Daten schreiben
	bsf	LcdRs		; Daten
	bsf	LcdE		; Enable LcdBus
	nop
	bcf	LcdE		; Disable LcdBus	
	swapf	LcdDaten, w	; Byte verdreht nach W holen
	andlw	H'F0'		; High Teil löschen
	movwf	LcdPort		; Low-teil Daten schreiben
	bsf	LcdRs		; Daten
	bsf	LcdE
	nop
	bcf	LcdE		; Disable LcdBus	
	bcf	LcdRs		;
	return


;*****************************************************
;+++Tastatur-Routinen*********************************
;*****************************************************
; warten darauf, daß keine Taste mehr gedrückt ist

Tastfrei			; Warten auf freie Tastatur
	call	Tastatur	; Tastencode nach Taste & W
	movfw	Taste		; wenn code=0 dann Z=1
	btfss	STATUS, Z	; wenn Z=1 dann skip
	goto	Tastfrei	; weiter warten
	return			; Tastatur ist frei

;#define	KRow1	PORTB,1		;Keyboard 1 4 7 *
;#define	KRow2	PORTB,2		;Keyboard 2 5 8 0
;#define	KRow3	PORTB,3		;Keyboard 3 6 9 #
;#define	KLine1	PORTB,4		;Keyboard 1 2 3
;#define	KLine2	PORTB,5		;Keyboard 4 5 6
;#define	KLine3	PORTB,6		;Keyboard 7 8 9
;#define	KLine4	PORTB,7		;Keyboard * 0 #

Tastatur
	; zuerst müssen die Tastaturzeilen-Pins auf Eingang gestellt werden
	bsf     STATUS, RP0	; Bank 1
	movlw   Ini_opt     	; pull-up Widerstände ein
	movwf   OPTION_REG 
	movlw	B'11110000'	; RB0 .. RB3 output, RB4 .. RB7 input
	movwf	TRISB
	bcf     STATUS, RP0	; Bank 0

	; das Enable-Pin des Displays muß auf Low stehen, damit das Display 
	; abgeschaltet ist solange wir die Tastatur abfragen
	clrf	PORTB		; Display inaktiv am Bus

	; w wird auf 0 gesetzt, dieser Wert wird durch ein ASSCI-Zeichen
	; überschrieben, falls eine Taste gedrückt ist
	; falls keine Taste gedrückt ist, bleibt 0 erhalten
	movlw	0		; W=0

	bcf	KRow1		; 1. spalte aktivieren
	bsf	KRow3
	bsf	KRow2

	call	key1		; 1. Spalte abfragen

	bcf	KRow2		; 2.Spalte aktivieren
	bsf	KRow1		; 1.Spalte ausschalten

	call	key2		; 2. Spalte

	bcf	KRow3		; 3. Spalte aktivieren
	bsf	KRow2		; 2. spalte ausschalten

	call	key3		; 3. Spalte
	
	bsf	KRow3		; 3. Spalte ausschalten
	movwf	Taste

	; PortB wieder komplett zu Output machen
	bsf     STATUS, RP0	; Bank 1
	movlw	B'00000000'	; RB1 .. RB7 output
	movwf	TRISB
	bcf     STATUS, RP0	; Bank 0
	return

key1
	btfss	KLine1
	retlw	'1'
	btfss	KLine2
	retlw	'4'
	btfss	KLine3
	retlw	'7'
	btfss	KLine4
	retlw	'*'
	return
key2
	btfss	KLine1
	retlw	'2'
	btfss	KLine2
	retlw	'5'
	btfss	KLine3
	retlw	'8'
	btfss	KLine4
	retlw	'0'
	return
key3
	btfss	KLine1
	retlw	'3'
	btfss	KLine2
	retlw	'6'
	btfss	KLine3
	retlw	'9'
	btfss	KLine4
	retlw	'#'
	return


WAIT
top     movlw   .500           
        movwf   loops2
top2    nop                    ; warten und nichts tun
        nop
        nop
        nop
	nop
        nop
        nop
        decfsz  loops2, F      
        goto    top2           
                               
        decfsz  loops, F       
        goto    top            
        retlw   0              


	end