HSG |
|
Details zur Ansteuerung beim Deltawave-Board
processor pic16f877a include p16f877a.inc __config _HS_OSC & _WDT_OFF & _PWRTE_ON ;Variablen ZAEHL1 equ 0x20 ; Hilfsvariable für Warte-Routine ZAEHL2 equ 0x21 ; Hilfsvariable für Warte-Routine ZAEHL3 equ 0x22 ; Hilfsvariable für Warte-Routine Save equ 0x23 ; zum Zwischenspeichern ;Konstanten LCDPort equ PORTD Enable equ 0x3 RW equ 0x2 RS equ 0x1 org 0x00 RESET: clrf STATUS movlw 0x00 movwf PCLATH goto main org 0x10 ;------------------------------------------------------------------ ;Warte-Routine 15,6 ms bei 8,867238 MHz wait15ms: movlw d'0' movwf ZAEHL1 movlw d'45' movwf ZAEHL2 tloop15ms decfsz ZAEHL1,F goto tloop15ms decfsz ZAEHL2,F goto tloop15ms return ;------------------------------------------------------------------- ;Warte-Routine 4,2 ms bei 8,867238 MHz wait4ms: movlw d'0' movwf ZAEHL1 movlw d'12' movwf ZAEHL2 tloop4ms decfsz ZAEHL1,F goto tloop4ms decfsz ZAEHL2,F goto tloop4ms return ;-------------------------------------------------------------------- ;Warte-Routine 2ms bei 8,867238 MHz wait2ms: movlw d'192' movwf ZAEHL1 movlw d'6' movwf ZAEHL2 tloop2ms decfsz ZAEHL1,F goto tloop2ms decfsz ZAEHL2,F goto tloop2ms return ;---------------------------------------------------------------------- ;Warte-Routine 100us bei 8,867238 MHz wait100us: movlw d'72' movwf ZAEHL1 movlw d'1' movwf ZAEHL2 tloop100us decfsz ZAEHL1,F goto tloop100us decfsz ZAEHL2,F goto tloop100us return ;----------------------------------------------------------------------- ; Warte-Routine 40us bei 8,867238 MHz wait40us: movlw d'28' movwf ZAEHL1 tloop40us: decfsz ZAEHL1,F goto tloop40us return ;------------------------------------------------------------------------ ; Inhalt von w an LCD senden (C - Control, Kommando) LCDsendC: movwf Save ; bewahrt das ankommende Byte auf ; obere Hälfte call LCDsndI ; LCDsndI erledigt die Maskierung call wait40us ; 40us warten ; untere Hälfte swapf Save,W ; D0-D3 aus Save --> D4-D7 in w call LCDsndI ; LCDsndI erledigt die Maskierung call wait2ms ; 2ms warten return ;----------------------------------------------------------------------- ; Inhalt von w an LCD senden (D - Daten) LCDsendD: movwf Save ; bewahrt das ankommende Byte auf ; obere Hälfte call LCDsndD ; LCDsndD erledigt die Maskierung call wait40us ; 40us warten ; untere Hälfte swapf Save,W ; D0-D3 aus Save --> D4-D7 in w call LCDsndD ; LCDsndD erledigt die Maskierung call wait2ms ; 2ms warten return ;------------------------------------------------------------------------ ; sendet ein Daten-Nibble zum Display LCDsndD: andlw b'11110000' ; nur die oberen 4 Bits nutzen, RW=0 iorlw b'00000010' ; RS=1 (Daten) goto $+2 ; LCDsndI überspringen ; ------------------------------------------------------------------------ ; sendet ein Kommando-Nibble zum Display LCDsndI: andlw b'11110000' ; nur die oberen 4 Bits nutzen, RW=0, RS=0 ; ------------------------------------------------------------------------ ; jetzt werden die Daten gesendet movwf LCDPort ; Daten --> LCDPort bsf LCDPort,Enable ; Enable-Bit setzen nop ; 450ns warten bcf LCDPort,Enable ; Enable-Bit löschen nop ; 450ns warten return ;-------------------------------------------------------------------------- ;Initialisierung des LCD-Displays initLCD: errorlevel -302 ; unterdrücke Fehlermeldung ; PORTD Bit 1-7 als Ausgang bsf STATUS,5 ; wechsle zu Bank1 movlw b'00000001' ; setze Port D, Bit 1-7 movwf TRISD ; als Ausgang bcf STATUS,5 ; wieder in Bank 0 wechseln errorlevel +302 ; erlaube Fehlermeldung ; 15ms warten call wait15ms ; 8-Bit-Modus einschalten movlw b'00110000' ;0011 senden, D1=RS=0, D2=RW=0 movwf LCDPort bsf LCDPort,Enable nop bcf LCDPort,Enable ; 4,1ms warten call wait4ms ; 8-Bit-Modus einschalten movlw b'00110000' ;0011 senden, D1=RS=0, D2=RW=0 movwf LCDPort bsf LCDPort,Enable nop bcf LCDPort,Enable ; 100us warten call wait100us ; 8-Bit-Modus einschalten movlw b'00110000' ;0011 senden, D1=RS=0, D2=RW=0 movwf LCDPort bsf LCDPort,Enable nop bcf LCDPort,Enable ; 100us warten call wait100us ;100us warten ; 4-Bit-Modus einschalten movlw b'00100000' ;0010 senden, D1=RS=0, D2=RW=0 movwf LCDPort bsf LCDPort,Enable nop bcf LCDPort,Enable ; 100us warten call wait100us ;100us warten ; 2-zeilig, 5x8-Matrix movlw b'00101000' call LCDsendC ; Display aus movlw b'00001000' call LCDsendC ; Display löschen movlw b'00000001' call LCDsendC call wait2ms ; Cursor nach rechts wandernd, kein Shift movlw b'00000010' call LCDsendC ; Display ein movlw b'00001100' call LCDsendC return ;------------------------------------------------ ;------------------------------------------------- main: call initLCD movlw a'H' call LCDsendD movlw a'a' call LCDsendD movlw a'l' call LCDsendD movlw a'l' call LCDsendD movlw a'o' call LCDsendD movlw a' ' call LCDsendD movlw a'W' call LCDsendD movlw a'e' call LCDsendD movlw a'l' call LCDsendD movlw a't' call LCDsendD movlw a'!' call LCDsendD ;Port-Setup errorlevel -302 ; unterdrücke Fehlermeldung bsf STATUS,5 ; wechsle zu Bank1 movlw b'00000000' ; setze Port B, Bit 0-7 movwf TRISB ; als Ausgang bcf STATUS,5 ; wieder in Bank 0 wechseln errorlevel +302 ; erlaube Fehlermeldung ;Port auf 0 movlw 0x0 movwf PORTB ;Zählschleife start: ;warten call wait15ms ;Port B hochzählen incf PORTB,F ;Sprung zum Start goto start end
Die Datei 16f877.inc wurde in das Projekt-Verzeichnis kopiert und in 16f877a.inc umbenannt, da in der Datei der Prozessortyp ebenfalls in 16f877a geändert wurde. Man vermeidet dadurch die Meldung, dass der 'Prozessor-Verify' fehlgeschlagen wäre. Ebenso ist die Verwendung von 'errorlevel -302' und 'errorlevel +302' reine Kosmetik, man kann die Anweisungen auch weglassen.