![]() |
|||
| 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.