PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC 16F877A LCD-Ansteuerung



Thom24
18.08.2009, 13:19
Hallo
Ich habe ein grosses Problem. Ich bin an einer wichtigen Arbeit bei der ich mit einem PIC 16F877A ein normales LC-Display 2x16 Zeichen ansteuern muss. Ich habe bereits ein Programm geschrieben. Funktioniert jedoch nicht. Wäre sehr froh wenn sich jemand die Zeit nehmen würde und mein Programm anschauen könnte. Ich arbeite mit dem MPLAB IDE in Assembler und benutze zum brennen den MPLAB ICD2. Angeschlossen ist das Display an folgende Ports:
Datenleitungen (8Bit): PORTD
E: PORTE,2
R/W: PORTE,1
RS: PORTE,0

Vielen Dank

PICture
19.08.2009, 21:39
Hallo Thom24!

Ich weiss nicht genau warum, aber der PORTE ist etwas besonderes und deswegen gibt es oft Probleme. Probier zuerst ein anderen PORT und wenn es richtig funktioniert, dann versuche das auf E zu wechseln. Danach musstest du rausfinden können, warum der E nicht geht.

MfG

theborg
19.08.2009, 22:37
wegen den ADCs würde ich mal ins blaue tippen

Yossarian
19.08.2009, 22:45
Hallo
Port D kann im PSP Modus laufen.
Der wird mit einem bit von Port E eingeschaltet.

Mit freundlichen Grüßen
Benno

Thom24
19.08.2009, 23:41
Vielen Dank für die bisherigen Antworten.
Am ADCs sollte es denke ich nicht liegen.
Habe hier mal mein Programm.



list p=16f877, st=OFF, x=OFF, n=0
errorlevel -302
#include <p16f877.inc>

__CONFIG _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _WRT_ENABLE_ON & _XT_OSC & _DEBUG_ON & _CPD_OFF & _LVP_OFF

;-----------------------------------------------------------------------------
;
;--- Variablen
;
Erste equ 0x20 ; Zählregister
Zweite equ 0x21 ; Charakter_Zeiger
W_Stack equ 0x22 ; Retten von Work
S_Stack equ 0x23 ; Retten von Statusregister
Buffer equ 0x24 ; Zwischen-Speicher
;
Del_Reg equ 0x25 ; Zählreg. für Enter
;
Char_Zeiger equ 0x26 ; Charakterzeiger für LCD
;
;--- Konstanten Type Byte
;
Del_Time equ 0xff ; Wartezeit für Subroutine Enter
Zeile_1 equ 0x80 ; 1.Zeichen in 1. Zeile
Zeile_2 equ 0xc0 ; 1.Zeichen in 2. Zeile
;
;--- Konstanten Type Bit
;
Richtung_A equ b'00000000' ; Datenrichtung von Port A
Richtung_B equ b'00000000' ; Datenrichtung von Port B
Richtung_C equ b'00000000' ; Datenrichtung von Port C
Richtung_D equ b'00000000' ; Datenrichtung von Port D
Richtung_E equ b'00000000' ; Datenrichtung von Port E
;
;
;------------------------------------------------------------
; Alle ADC-Eingänge auf Digital I/O schalten
;------------------------------------------------------------

BSF STATUS, RP0 ; auf Bank 1 umschalten
BCF ADCON1, PCFG3 ; PCFG3=0
BSF ADCON1, PCFG2 ; PCFG2=1
BSF ADCON1, PCFG1 ; PCFG1=1
BCF ADCON1, PCFG0 ; PCFG0=0
BCF STATUS, RP0 ; auf Bank 0 zurückschalten
;
;---------------------------------------------------------------
; Programm-Start
;---------------------------------------------------------------
;
org 0x000 ; Startadresse
;
goto Main ; Sprung zum Hauptprogramm
;
org 0x004 ; Interruptvektor
goto ISR ; Zu Interrupt-Service-Routine
;
;---------------------------------------------------------------
; Initialisierung der Port's
;---------------------------------------------------------------
;
Init
bsf STATUS, RP0 ; Schalte in Bank 1
movlw Richtung_A ; Datenrichtung festlegen
movwf TRISA ; TrisA-Register laden
movlw Richtung_B ; Datenrichtung festlegen
movwf TRISB ; TrisB-Register laden
movlw Richtung_C ; Datenrichtung festlegen
movwf TRISC ; TrisC-Register laden
movlw Richtung_D ; Datenrichtung festlegen
movwf TRISD ; TrisD-Register laden
movlw Richtung_E ; Datenrichtung festlegen
movwf TRISE ; TrisE-Register laden
bcf STATUS, RP0 ; Schalte in Bank 0 zurück
;-------------------------------------------------------------
; Initialisierung Display
;------------------------------------------------------------

bcf PORTE, 1 ; Schreib-Signal aktivieren
bcf PORTE, 0 ; RS auf Befehlseingabe
movlw 0x38 ; 8-Bit-Modus, 2 Linien
call Enter ; Kommando schreiben und warten
call Enter ; Kommando schreiben und warten
call Enter ; Kommando schreiben und warten
;
movlw 0x0e ; Increment-Modus, Display-Shift
call Enter ; Kommando schreiben und warten
;
movlw 0x02 ;
call Enter ; Kommando schreiben und warten
;
movlw 0x01 ;
call Enter ; Kommando schreiben und warten
;
;--- Initialisieren des LC-Displays beendet
;

return ;

;
;---------------------------------------------------------------
; Unter-Programm: Enter
; Funktion: Erzeugt eine ansteigende und abfallende
; Flanke an Enable Pin 6 von LCD
;---------------------------------------------------------------
;
Enter
movwf PORTD ; Befehl an Port D übertragen
call Delay ; Warten
bsf PORTE, 2 ; Enable auf High setzen
call Delay ; Warten
bcf PORTE, 2 ; Enable auf Low setzen
call Delay ; Warten
;
return ; Zurück
;
;---------------------------------------------------------------
; Unter-Programm: Delay
; Funktion: Wartezeit für Unterprogramm Enter
;---------------------------------------------------------------
;
Delay
movlw Del_Time ; Lade Delay-Zähler
movwf Del_Reg ; ... mit Verweilzeit
;
Delay_1
decfsz Del_Reg, F ; Decrementiere und Springe wenn 0
goto Delay_1
;
return ; Zurück
;
;---------------------------------------------------------------
; Unter-Programm: Sende Text in Zeile 1
;---------------------------------------------------------------
;
Get_Text_00
bcf PORTE, 0 ; RS auf Befehlseingabe
movlw Zeile_1 ; Zeile anwählen
call Enter ; Kommando schreiben und warten
bsf PORTE, 0 ; RS auf Dateneingabe
;
Get_Text_01
clrf Char_Zeiger ; Charakter-Zeiger auf Null
;
Get_Text_02
movfw Char_Zeiger ; Charakter_Zeiger laden
call Text_0 ; Charakter lesen
;
;--- Ist das String-Ende erreicht?
;
iorlw 0x00 ; Oder-Verknüpfung mit Zeichen
btfsc STATUS, 2 ; Sprung, wenn noch nicht fertig
;
;--- Ende von String erreicht. Unterprogramm verlassen
;
goto Get_Text_03 ; Sprung zum Schluss
call Enter ; Kommando schreiben und warten
incf Char_Zeiger, F ; Charakter_Zeiger um 1 erhöhen
goto Get_Text_02 ; Zum nächsten Charakter
;
Get_Text_03
return ; Zurück
;
;--- Text für die erste Zeile
;
Text_0
andlw 0x0f ; LSB ausmaskieren
addwf PCL, F ; Offset zum PC addieren
;
dt "Alles i.O.", 0x00


;---------------------------------------------------------------
; Unter-Programm: Sende Text in Zeile 2
;---------------------------------------------------------------
;
Get_Text_10
bcf PORTE, 0 ; RS auf Befehlseingabe
movlw Zeile_2 ; Zeile anwählen
call Enter ; Kommando schreiben und warten
bsf PORTE, 0 ; RS auf Dateneingabe
;
Get_Text_11
clrf Char_Zeiger ; Charakter-Zeiger auf Null
;
Get_Text_12
movfw Char_Zeiger ; Charakter_Zeiger laden
call Text_1 ; Charakter lesen
;
;--- Ist das String-Ende erreicht?
;
iorlw 0x00 ; Oder-Verknüpfung mit Zeichen
btfsc STATUS, 2 ; Sprung, wenn noch nicht fertig
;
;--- Ende von String erreicht. Unterprogramm verlassen
;
goto Get_Text_13 ; Sprung zum Schluss
call Enter ; Kommando schreiben und warten
incf Char_Zeiger, F ; Charakter_Zeiger um 1 erhöhen
goto Get_Text_12 ; Zum nächsten Charakter
;
Get_Text_13
return ; Zurück
;
;--- Text für die erste Zeile
;
Text_1
andlw 0x0f ; LSB ausmaskieren
addwf PCL, F ; Offset zum PC addieren
;
dt "Alles i.O.", 0x00

;
;---------------------------------------------------------------
; Hauptprogramm
;---------------------------------------------------------------
;
Main
call Init ; Initialisiere das System
;
Main_1
call Get_Text_00 ; Schreiben von Text in Zeile 1
;
Main_2
goto Main_2
;
;---------------------------------------------------------------
; Ende des Programms
;---------------------------------------------------------------
;
end