LCD und RS232 für 16F627A
Mittwoch, 23. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  LCD und RS232 für 16F627A « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: LCD und RS232 für 16F627A  (Gelesen 300 mal)
 
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« am: Februar 17, 2012, 13:10:56 »

Hallo,
ich habe ein ein Programm geschrieben zum Ansteuern eines LCD 4x20.
Zusätzlich habe ich ein Computer Programm in C# geschrieben welches das LCD ansteuert.
Das Programm nutzt COM1 mit 8 Datenbits 1 Stopbit und keine Flusssteuerung.
Die Funktion "LED an" "LED aus" "Text senden" "LCD löschen" funktionieren super. "Curser links" "Curser rechts" "Text links" "Text rechts" machen bei ca 2 von 4 klicks einen fehler,schreibe ich "Hallo" aufs LCD dann erscheint der Text,drücke ich auf Text nach rechts,passiert es ab und zu das ein paar buchstaben des Textes verschwinden. Ein Bsp. "Hallo ich bin das LCD" -Text nach rechts- "H llo ich b n da  LCD"
hoffe mir kann jemand helfen Smiley

anbei ist mein Programm zum Ansteuern was nur über COM1 funktioniert und mit 19,2 kBPS

Code:
list p=16f627A
;**************************************************************
;*   Pinbelegung
;* ----------------------------------
;* PORTA: 0  LCD Display RS
;* 1  LCD Transistor NPN Beleuchtung
;* 2 -
;* 3 -
;* 4 -
;* 5 MCLR
;* 6 Quarz 10MHz
;* 7 Quarz 10MHz
;*
;* PORTB: 0 LCD Display E
;* 1 RS232
;* 2 RS232
;* 3 LCD Display R/W
;* 4 LCD Display D4
;* 5 LCD Display D5
;* 6 LCD Display D6
;* 7 LCD Display D7
;*
;**************************************************************
;
;Florian Ditscher V1.1 14.02.2012
;
; Rs232 mit LCD-Display
;
; Prozessor 16F628
;
; Prozessor-Takt 10 MHz
;
; LCD & Rs232
;
; 41 zum Senden eines Steuerbefehls großes A
; 59 zum Senden eines Textes großes Y
; 7A für LED                               kleine z
;**********************************************************
; Includedatei für den 16F628 einbinden

#include <P16f627A.INC>

ERRORLEVEL      -302     ;SUPPRESS BANK SELECTION MESSAGES


; Configuration 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


;**********************************************************
; Variablennamen vergeben

w_temp equ 0x20
status_temp equ 0x21

Zeichen equ 0x22
DatenSindDa equ 0x23

LcdStatus equ 0x24 ; Puffer für aus dem LCD ausgelesenes Statusbyte
LcdDaten equ 0x25 ; Puffer für zum LCD zu schreibendes Byte

loops equ 0x26 ; Wartezeit für WAIT in Millisekunden
loops2 equ 0x27

ZSpeicher equ 0x28
SteuerBefehl equ 0x29
PrintZeichen equ 0x2A
SteuerungPA equ 0x2B


#define LcdE PORTB,0 ; enable Lcd
#define LcdRw PORTB,3 ; read Lcd
#define LcdRs PORTA,0 ; Daten Lcd (nicht control)
#define LcdPort PORTB ; Datenbus des LCD (obere 4 Bit)

org 0
goto init

;**********************************************************
; Interruptroutine für RS232-Empfang

org 4 ; Interrupt beginnt immer bei Adresse 4
int
movwf w_temp ; status retten
swapf STATUS,w
movwf status_temp

;RS232-Empfänger-Interupt?
btfss PIR1,RCIF
goto intEnde ; Interrupt kam von wo anders

movfw RCREG ; RS232-Register auslesen
movwf Zeichen ; und in den Speicher nach 'Zeichen' schreiben
movwf ZSpeicher

btfss DatenSindDa,1
goto weiter_3
movfw ZSpeicher
movwf SteuerBefehl
bsf DatenSindDa,3
bcf DatenSindDa,1

weiter_3 btfss DatenSindDa,2
goto weiter_4
movfw ZSpeicher
movwf PrintZeichen
bsf DatenSindDa,4
bcf DatenSindDa,2

weiter_4
btfss DatenSindDa,5
goto weiter_8
movfw ZSpeicher
movwf SteuerungPA
bsf DatenSindDa,6
bcf DatenSindDa,5
weiter_8


bsf DatenSindDa,0 ; Kennzeichen für gültige Daten setzen
bcf PIR1,RCIF ; interrupt-Flag löschen

intEnde ; geretteten Status wieder zurückschreiben
swapf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie

;**********************************************************
; Anfangsinitialisierung

init
clrf DatenSindDa

MOVLW 0x07 ;comparators ausschalten damit man PortA Digital nutzen kann
MOVWF CMCON

bsf STATUS,RP0 ;Port B auf Ausgang stellen aus TX und RX muss eingang sein
movlw B'00000110'
movwf TRISB

clrf TRISA
bcf STATUS,RP0

; USART initialisieren
BSF STATUS,RP0 ; Bank1
MOVLW 0x20 ; Sender: RS232
MOVWF TXSTA ;
BCF STATUS,RP0 ; Bank 0
MOVLW 0x90 ; Empfänger: RS232
MOVWF RCSTA ;

; USART Baudrate einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'7' ; Set Baud rate 19,2 kBPS bei 10 MHz
MOVWF SPBRG
BCF TXSTA, BRGH ; BRGH=0
BCF STATUS,RP0 ; Bank 0

;Interrupts vorbereiten
BSF STATUS,RP0 ; Bank1
BSF PIE1,RCIE ; Enable receive interrupts
BCF STATUS,RP0 ; Bank 0
clrf PIR1 ; alle Interruptflags löschen
 
BSF INTCON,GIE ; generell Interrupts erlauben
BSF INTCON,PEIE ; Interrupts von Peripheriegeräten erlauben

call InitLcd



;**********************************************************
; Hauptprogrammschleife
;##########################################################

Main
btfsc DatenSindDa,3
goto weiter_1
movf ZSpeicher,w
sublw h'41'
btfss STATUS,Z
goto weiter_1
bsf DatenSindDa,1
clrf ZSpeicher

weiter_1 btfsc DatenSindDa,4
goto weiter_2
movf ZSpeicher,w
sublw h'59'
btfss STATUS,Z
goto weiter_2
bsf DatenSindDa,2
clrf ZSpeicher

weiter_2
btfsc DatenSindDa,6
goto weiter_7
movf ZSpeicher,w
sublw h'7A'
btfss STATUS,Z
goto weiter_7
bsf DatenSindDa,5
clrf ZSpeicher
weiter_7




btfss DatenSindDa, 0
goto Main

RS232out

btfss PIR1,TXIF ; ist Sender leer ?
goto RS232out ; nein, noch nicht leer
incf Zeichen,w ; um 1 erhöht nach w
movwf TXREG ; und in den RS232-Sender schreiben

btfss DatenSindDa,4
goto weiter_5
movf PrintZeichen,w
call OutLcdDaten
bcf DatenSindDa,4
clrf ZSpeicher
weiter_5
btfss DatenSindDa,3
goto weiter_6
movf SteuerBefehl,w
call SteuerLCD
bcf DatenSindDa,3
clrf ZSpeicher
weiter_6
btfss DatenSindDa,6
goto weiter_9
movf SteuerungPA,w
call PORTAsteuern
bcf DatenSindDa,6
clrf ZSpeicher

weiter_9
bcf DatenSindDa,0
clrf Zeichen

goto Main



;#####################################################################
;########Hauptprogramm Ende###########################################
;#####################################################################

;*****************************************************
; 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
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

WAIT
top     movlw   .250           ; timing adjustment variable (1ms)
        movwf   loops2
top2    nop                    ; warten und nichts tun
        nop
        nop
        nop
nop
        nop
        nop
        decfsz  loops2, F      ; innere Schleife fertig?
        goto    top2           ; nein, noch mal rum
                               ;
        decfsz  loops, F       ; äußere Schleife fertig?
        goto    top            ; nein, noch mal rum
        retlw   0              ; FERTIG und return
InitLcd
movlw D'255' ; 250 ms Pause nach dem Einschalten
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 'O' ; 'OK:' ausgeben
call OutLcdDaten
movlw 'K'
call OutLcdDaten
movlw ':'
call OutLcdDaten
return

SteuerLCD ; hier kann ein Steuerbefehl an das LCD übergeben werden

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
movf SteuerBefehl,w
call OutLcdControl

return

PORTAsteuern ;Ansteuerung der LED auf PortA

btfss SteuerungPA,1
goto weiter_10
bsf PORTA,1
return

weiter_10
bcf PORTA,1

return


end


* LCDRS232.exe (11.5 KB - runtergeladen 11 Mal.)
Gespeichert
Luftlandeapotheker
Newbie
*
Offline Offline

Beiträge: 8


Profil anzeigen
« Antworten #1 am: Februar 28, 2012, 20:13:28 »

Hallo Flo!
Witzig, ich probiere gerade das Gleiche, allerdings mit einem 16F877 und in c.
Von Assembler habe ich leider wenig Ahnung, habe allerdings bei SPRUT folgenden Hinweis gefunden:
Zitat
++ACHTUNG FALLE++
Wird eine Menge Daten ohne Pause gesendet, und als einzige Bremse das TXIF-Flag abgefragt, so kann es am Empfänger der Daten zum Verschlucken von Zeichen kommen, da der Empfänger die Lücke zwischen 2 benachbarten Zeichen nicht erkennt. In diesem Fall empfehle ich nicht TXIF sonder besser TRMT im Register  TXSTA abzufragen. Dieses Bit wird erst gesetzt, wenn das zu sendende Byte komplett herausgeschoben ist. TXSTA liegt in der Bank1 !
Liegt es vielleicht daran?
Oder probiere es mal mit nur 9600 baud.

Viele Grüße
Matthias
Gespeichert
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« Antworten #2 am: Februar 29, 2012, 06:42:08 »

Hallo Matthias,
daran kann es nicht liegen,wenn ich meinen PIC etwas sende (hex) bekomme ich es um 1 erhöht zurück,also muss es wo anders daran liegen.
Danke für die bemühungen.
es grüßt der flo
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.08 Sekunden mit 19 Zugriffen.
 
Top! Top!