Code:
; Mit dem PIC16F84A sollt auf einem LCD eine Schrift über ein 1x16 Zeichen LCD laufen, die vorher eingegeben wurde.
; Oszillator -> 4MHz Keramikresonator oder Quarz
;
; PORTA 0 TasterUp
; 1 TasterBackward
; 2 TasterForward
; 3 TasterDown
; 4 Prog Jumper (wenn offen dann ProgModus wenn geschlossen Laufmodus)
; Tasten sind High wenn gedrückt
;
; PORTB 0 LCD Enable
; 1
; 2 LCD RS (0=Steuerregister 1=Textpuffer)
; 3 LCD R/W (0=Auf Display schreiben 1=Von Display lesen)
; 4 LCDD4 \
; 5 LCDD5 | LCD 4bit Datenbus
; 6 LCDD6 |
; 7 LCDD7 /
;
list p=16F84A
#include <P16F84A.INC>
__config _CP_OFF && _PWRTE_ON && _WDT_OFF && _XT_OSC
;Variablen
Zaehler equ 0x0C ;Für Delays
Zeichen equ 0x0D ;Für die Nummer des Zeichens in der Tabelle
Tasten equ 0x0E ;Für Tastendruck
Daten equ 0x0F ;Für Abfrage des LCD
SignCount equ 0x10 ;Für CursorPosition und Anzahl der Zeichen
ZeichenHex equ 0x11 ;Aus der Tabelle gelesener Code für das Zeichen
;Constanten bzw Pinzuordnungen
#define TasterUp PORTA,0
#define TasterBackward PORTA,1
#define TasterForward PORTA,2
#define TasterDown PORTA,3
#define Jumper PORTA,4
#define Enable PORTB,0
#define RS PORTB,2
#define RW PORTB,3
org 0x00
;************************************************************************
;Timer und Pins werden Initialisiert
setup
CLRF Zaehler
CLRF Zeichen
CLRF Tasten
CLRF Daten
CLRF SignCount
CLRF ZeichenHex
CLRF PORTA
CLRF PORTB
BSF STATUS,RP0
CLRF TRISB ;PORTB alles Ausgänge
MOVLW 0xFF
MOVWF TRISA ;PORTA alles Eingänge
MOVLW B'10001000' ;Timer0 als Timer, Prescaler 1, PBPullups aus
BCF STATUS,RP0
;************************************************************************
; | |
;************************************************************************
;Das LCD wird initialisiert
LCDInit
;15ms auf Display warten
MOVLW D'15'
MOVWF Zaehler
Delay15
CALL Wait
DECF Zaehler
BTFSS STATUS,Z
GOTO Delay15
;testen ob Busy, dann auf 8Bit Modus stellen
CALL TestBusy
CALL LCD8Bit
MOVLW D'5'
MOVWF Zaehler
;5ms auf Display warten
Delay5
CALL Wait
DECF Zaehler
BTFSS STATUS,Z
GOTO Delay5
;testen ob Busy, dann auf 8Bit Modus stellen
CALL TestBusy
CALL LCD8Bit
;100µs auf Display warten
MOVLW D'20'
MOVWF Zaehler
NOP
DECF Zaehler
BTFSS STATUS,Z
GOTO $-3
;auf 4Bit Modus stellen
CALL TestBusy
CALL LCD8Bit
CALL TestBusy
CALL LCD4Bit
;auf 2Zeilen Modus und 5x8 Darstellung schalten
CALL TestBusy
CALL LCD2col
;LCD löschen
CALL TestBusy
CALL ClearLCD
;Cursor nach rechts, kein Displayshift
CALL TestBusy
CALL SetCursor
;************************************************************************
; | |
;************************************************************************
;Der Jumper wird getestet und entschieden ob Programmiermodus oder normaler Betrieb läuft
ProgModus
BTFSC Jumper ;Sind wir im ProgModus?
GOTO Main ;Nein, auf zur Main
CALL Tastatur ;Ja, frag die Tasten ab und stell den Text ein
CALL TasterService
GOTO ProgModus
;************************************************************************
;************************************************************************
;Hauptprogrammschleife
Main
CALL TestBusy
CALL Roll ;Rollt das Display eine stelle und stell zuvor den Cursor ab
Delay250 ;Wartet etwa eine viertel Sekunde
MOVLW D'250'
MOVWF Zaehler
CALL Wait
GOTO Main ;kehrt zum Anfang von Mainschleife zurück
;************************************************************************
;########################################################################
;Unterprogramme
;************************************************************************
;Roll schaltet den Cursor ab und verschiebt das Display um 1 nach Links
Roll
MOVLW B'00000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'11000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;hier wurde das Display an, der Cursor aus gestellt
CALL TestBusy
MOVLW B'00010000' ;hier wird das Display 1 nach links verschoben
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'10000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;für 1 Millisekunden wird gewartet
Wait
CLRF TMR0
BSF STATUS,RP0
MOVLW B'10000001' ;Timer auf Vorteiler 4
MOVWF OPTION_REG
BCF STATUS,RP0
sub
BTFSS INTCON,T0IF
GOTO sub
BCF INTCON,T0IF
CLRF TMR0
RETURN
;************************************************************************
;************************************************************************
;LCD auf 8Bit Modus stellen
LCD8Bit
MOVLW B'00110000' ;8Bit Modus
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;LCD auf 4Bit Modus stellen
LCD4Bit
MOVLW B'00100000' ;8Bit Modus
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;LCD auf 2Zeilen und 5x8 Modus mit 4Bit Interface stellen
LCD2col
MOVLW B'00100000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'10000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;Löscht den TextPuffer des LCD
ClearLCD
MOVLW B'00000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'00010000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;Stellt das Display auf "rechts nach Zeichen", cursor als blinkender unterstrich
SetCursor
MOVLW B'00000000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'01100000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;hier wurde das Display auf rechtsfortlauf gestellt, kein Displayshift
CALL TestBusy
MOVLW B'00000000' ;hier wird das Display und der blinkende Strichcursor eingeschaltet
MOVWF PORTB
BSF Enable
NOP
BCF Enable
MOVLW B'11100000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable
RETURN
;************************************************************************
;************************************************************************
;Testet das LCD auf sein BusyFlag. Falls gesetzt,bleibt der PIC in TestBusy und testet erneut
TestBusy
BSF STATUS,RP0
MOVLW 0xFF
MOVWF TRISB
BCF STATUS,RP0
CLRF PORTB
BCF RS
BSF RW
NOP
BSF Enable
MOVFW PORTB
MOVWF Daten
BTFSC Daten,7 ;BusyFlag high?
GOTO TestBusy
BSF STATUS,RP0
CLRF TRISB
BCF STATUS,RP0
CLRF PORTB
RETURN
;************************************************************************
;************************************************************************
;Abfrage der Tasten, mit 30sek Entprellung. Die gedrückte Taste wird mit 1 angezeigt
Tastatur
CLRF PORTA
NOP
MOVFW PORTA
MOVWF Tasten
MOVLW D'30'
MOVWF Zaehler
Delay30
CALL Wait
DECF Zaehler
BTFSS STATUS,Z
GOTO Delay30
MOVFW PORTA
ANDWF Tasten
RETURN
;************************************************************************
;************************************************************************
;Bestimmt welche Taste gedrückt wurde und veranlasst Aktion
TasterService
BTFSC Tasten,0
GOTO Up
BTFSC Tasten,1
GOTO Backward
BTFSC Tasten,2
GOTO Forward
BTFSC Tasten,3
GOTO Down
CLRF Tasten
RETURN
;************************************************************************
;************************************************************************
;Aktion bei Taste Forward
Forward
CLRF Tasten
CALL TestBusy
MOVLW B'00010000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;erster Teil gesendet, 4bit
MOVLW B'01000000' ;Cursor nach rechts, erstmal ohne Displayshift
MOVWF PORTB
BSF Enable
NOP
BCF Enable
INCF SignCount
MOVFW SignCount ;wenn mehr als 12 Zeichen auf dem Display sind wird carry gesetzt, dann soll das Displays verschoben werden
SUBLW D'12'
BTFSS STATUS,C
GOTO Main
CALL TestBusy
MOVLW B'00010000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;erster Teil gesendet, 4bit
MOVLW B'11000000' ;Display nach rechts
MOVWF PORTB
BSF Enable
NOP
BCF Enable
GOTO Main
;************************************************************************
;************************************************************************
;Aktion bei Taste Backward
Backward
CLRF Tasten
CALL TestBusy
MOVLW B'00010000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;erster Teil gesendet, 4bit
MOVLW B'00000000' ;Cursor nach links, erstmal ohne Displayshift
MOVWF PORTB
BSF Enable
NOP
BCF Enable
DECF SignCount
MOVFW SignCount ;wenn mehr als 12 Zeichen auf dem Display sind wird carry gesetzt, dann soll das Displays verschoben werden
SUBLW D'12'
BTFSS STATUS,C
GOTO Main
CALL TestBusy
MOVLW B'00010000'
MOVWF PORTB
BSF Enable
NOP
BCF Enable ;erster Teil gesendet, 4bit
MOVLW B'10000000' ;Display nach links
MOVWF PORTB
BSF Enable
NOP
BCF Enable
GOTO Main
;************************************************************************
;************************************************************************
;Aktion bei Taste Up
Up
INCF Zeichen ;Zeichen um eins erhöhen
MOVLW D'104' ;Testen damit nicht hinter die Tabelle gesprungen wird
SUBWF Zeichen,W
BTFSC STATUS,Z
CLRF Zeichen
CALL ZeichenTab ;und aus der Tabelle holen
MOVWF ZeichenHex ;Zwischenspeichern
MOVWF PORTB
BSF RS
BCF RW
CALL TestBusy
NOP
BSF Enable
NOP
BCF Enable ;höchsten 4bit senden
RLF ZeichenHex,F
RLF ZeichenHex,F
RLF ZeichenHex,F
RLF ZeichenHex,F ;4stellen rotieren
MOVFW ZeichenHex
MOVWF PORTB
BSF RS
BCF RW
NOP
BSF Enable
NOP
BCF Enable ;niedrigsten 4bit senden
;jetzt noch verhindern, dass der Cursor weiterspringt
CALL TestBusy
GOTO Backward
;************************************************************************
;************************************************************************
;Aktion bei Taste Down
Down
DECF Zeichen ;Zeichen um eins verringern
MOVLW D'104' ;Testen damit nicht hinter die Tabelle gesprungen wird
SUBWF Zeichen,W
BTFSC STATUS,Z
CLRF Zeichen
CALL ZeichenTab ;und aus der Tabelle holen
MOVWF ZeichenHex ;Zwischenspeichern
MOVWF PORTB
BSF RS
BCF RW
CALL TestBusy
NOP
BSF Enable
NOP
BCF Enable ;höchsten 4bit senden
RLF ZeichenHex,F
RLF ZeichenHex,F
RLF ZeichenHex,F
RLF ZeichenHex,F ;4stellen rotieren
MOVFW ZeichenHex
MOVWF PORTB
BSF RS
BCF RW
NOP
BSF Enable
NOP
BCF Enable ;niedrigsten 4bit senden
;jetzt noch verhindern, dass der Cursor weiterspringt
CALL TestBusy
GOTO Backward
;************************************************************************
;########################################################################
;DatenTabelle
ZeichenTab
MOVFW Zeichen
ADDWF PCL
RETLW 0x20 ;Leerzeichen
RETLW 0x41 ;A
RETLW 0xE1 ;ä
RETLW 0x61 ;a
RETLW 0x42 ;B
RETLW 0x62 ;b
RETLW 0x43 ;C
RETLW 0x63 ;c
RETLW 0x44 ;D
RETLW 0x63 ;d
RETLW 0x45 ;E
RETLW 0x65 ;e
RETLW 0x46 ;F
RETLW 0x66 ;f
RETLW 0x47 ;G
RETLW 0x67 ;g
RETLW 0x48 ;H
RETLW 0x68 ;h
RETLW 0x49 ;I
RETLW 0x69 ;i
RETLW 0x4A ;J
RETLW 0x6A ;j
RETLW 0x4B ;K
RETLW 0x6B ;k
RETLW 0x4C ;L
RETLW 0x6C ;l
RETLW 0x4D ;M
RETLW 0x6D ;m
RETLW 0x4E ;N
RETLW 0x6E ;n
RETLW 0x4F ;O
RETLW 0x6F ;o
RETLW 0xEF ;ö
RETLW 0x50 ;P
RETLW 0x70 ;p
RETLW 0x51 ;Q
RETLW 0x71 ;q
RETLW 0x52 ;R
RETLW 0x72 ;r
RETLW 0x53 ;S
RETLW 0x73 ;s
RETLW 0x54 ;T
RETLW 0x74 ;t
RETLW 0x55 ;U
RETLW 0x75 ;u
RETLW 0xF5 ;ü
RETLW 0x56 ;V
RETLW 0x76 ;v
RETLW 0x57 ;W
RETLW 0x77 ;w
RETLW 0x58 ;X
RETLW 0x78 ;x
RETLW 0x59 ;Y
RETLW 0x79 ;y
RETLW 0x5A ;Z
RETLW 0x7A ;z
RETLW 0xE2 ;ß
RETLW 0x30 ;0
RETLW 0x31 ;1
RETLW 0x32 ;2
RETLW 0x33 ;3
RETLW 0x34 ;4
RETLW 0x35 ;5
RETLW 0x36 ;6
RETLW 0x37 ;7
RETLW 0x38 ;8
RETLW 0x39 ;9
RETLW 0xF7 ;Pi
RETLW 0xF6 ;Summenzeichen
RETLW 0xFD ;Geteilt durch Zeichen
RETLW 0x21 ;!
RETLW 0x3F ;?
RETLW 0x2B ;+
RETLW 0x2D ;-
RETLW 0x2A ;*
RETLW 0x3D ;=
RETLW 0x2F ;/
RETLW 0x25 ;%
RETLW 0x2E ;.
RETLW 0x2C ;,
RETLW 0x3A ;:
RETLW 0x3B ;;
RETLW 0x23 ;#
RETLW 0x24 ;$
RETLW 0x26 ;&
RETLW 0x28 ;(
RETLW 0x29 ;)
RETLW 0x22 ;"
RETLW 0x27 ;'
RETLW 0x50 ;`
RETLW 0x3C ;<
RETLW 0x3E ;>
RETLW 0x7F ;<-
RETLW 0x7E ;->
RETLW 0x5E ;^
RETLW 0x40 ;@
RETLW 0xDF ;°
RETLW 0x5F ;_
RETLW 0x5B ;[
RETLW 0x5D ;]
RETLW 0x7B ;{
RETLW 0x7D ;}
RETLW 0x7C ;|
RETLW 0xFF ;gefüllter Block
;************************************************************************
END
Lesezeichen