PDA

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



Elo-Azubi
15.03.2006, 15:03
Hallo!

Zuerst stelle ich mich kurz vor.

Ich bin 21 ahre alt und Azubi im Fach Elektroniker für Geräte und Systeme Fachrichtung Funktechnik im 2. Ausbildungsahr.

Im ersten Ausbildungsyahr habe ich eine Alarmanlage entworfen und aufgebaut. Sie überwacht, welche Fenter geöffnet und welche geschlossen sind, wird scharf, wenn alle Fenster geschlossen sind und löst aus, sobald ein Fenster geöffnet wird. Gesteuert wird die Anlage über einen Dämmerungsschalter.

Mit meinem erweitertem Wissen über die Elektronik möchte ich nun diese Alarmanlage optimieren und mit einer Lichtschranke erweitern.

Quasi als I-Tüpfelchen soll auch ein LCD mit in der Anlage werkeln. Ich habe mir vorgestellt, dass es "Betrieb" anzeigen soll, wenn Spannung an der Anlage anliegt, und dann yeweils Anzeigt, welches Fenster Alarm ausgelöst hat, bzw. wenn die Lichtschranke auslöst, soll "Lichtschranke" angezeigt werden.

Zur Ansteuerung des LCD würde ich gern den PIC 16F84(A) verwenden, da im Betrieb ein Brenner und die entsprechende Software dazu vorliegt.

Kann mir yemand helfen den PIC zu programmieren? Bzw. kennt yemand ein wirklich gutes Einsteigertutorial zum PIC? auf www.sprut.de hab ich schon einiges erfahren, aber trotzdem weiß ich leider immernoch nicht, wo genau ich anfangen soll. Ich würde ihn gern in Assemblersprache programmieren wollen, da ich mir da ganz sicher bin, dass mich mein Betrieb auch ein wenig unterstützt.

Wichtig für mich wäre halt ein Step-by-Step um mir über die Assemblersprache und die Auswirkungen der Befehle auf die Ausgänge des PIC`s klar zu werden.

Ich hoffe mir kann yemand helfen. Würde mich auch über Erfahrungberichte freuen!

Gruß Alex

kalledom
15.03.2006, 16:16
PIC Assembler-Beispiele findest Du unter http://www.domnick-elektronik.de/picasm.htm und eine Fehler-Checkliste unter http://www.domnick-elektronik.de/piccheck.htm

Andre_S
15.03.2006, 17:13
....Zur Ansteuerung des LCD würde ich gern den PIC 16F84(A) verwenden, da im Betrieb ein Brenner und die entsprechende Software dazu vorliegt.

Kann mir yemand helfen den PIC zu programmieren? Bzw. kennt yemand ein wirklich gutes Einsteigertutorial zum PIC? auf www.sprut.de hab ich schon einiges erfahren, aber trotzdem weiß ich leider immernoch nicht, wo genau ich anfangen soll. Ich würde ihn gern in Assemblersprache programmieren wollen,...
Gruß Alex

Hallo Alex,

da ist doch Sprut gerade die erste Adresse, da steht doch alles bis ins kleinste Detail beschrieben und bei den Beispielen ist sogar (wenn ich mich recht erinnere) Deine Ansteuerung des LCD mit 16F84 dabei.
Auch die Beschreibung der Befehle und dessen Auswirkungen.
Wo klemmt es den???

Also ich habe damals auch mit der Seite angefangen, noch die Software von Microchip und die Doku für den entsprechenden Pic... (Aber auch das steht alles bei Sprut)

Gruß André

Elo-Azubi
15.03.2006, 20:41
Hi Andre, hallo Kalledom!

Erstmal danke für die Links, die werde ich mir yetzt noch mal anschaun, mal sehn ob ich da auch schon schlauer werde.

Zu Sprut.de

Eine wirklich gute Seite, muss ich schon sagen. Auch die LCD Ansteuerung ist beschrieben. Allerdings schreibt das Programm "HALLO" auf das Display. Meine Funktionen sollan ya abhängig von bestimmten Zuständen sein. Und genau da liegt das Problem. Ich kann den Quelltext zwar recht gut nachvollziehen, aber genau der Ansatz zum umprogrammieren fehlt mir irgendwie.

Ich kenne alle Befehle, die der Pic so versteht... 36 oder wie viele es waren. Zwar nicht auswendig, aber ich hab ne Referenz und natürlich das Datenblatt, in dem die Befehle ya auch erklärt sind.

Vieleicht bin ich auch ein bisschen verwöhnt, denn ich hab bis yetzt nur C++ und Delphi programmiert, indem es ya schon eine IF-Funktion oder CASE Funktion gibt. Und ich bin halt der Meinung, dass ich dem Pic doch sagen können muss: Im Falle dass Eingang X den Wert 1 annimmt, soll auf dem Display (das steht ya auf Sprut.de) "Alarm 1" ausgegeben werden.

Also eigentlich, wenn ich es mir recht überlege, fehlt nur der Bedingungsteil für die Funktion meines Displays!

phaidros
15.03.2006, 23:22
Hallo,
ein IF kennt der PIC (in Assembler) nicht. Statt dessen gibt es Befehle, um ein Bit zu testen und entsprechend des Ergebnisses irgendwohin zu springen.
Angenommen der Zustand deiner Alarmanlage steht in einem Register (z.B. in 0x14) und hat verschiedene Werte von 1 bis 3. Dann gehen folgenden Befehle:

movlw 1 ; W-Register mit 1 laden
xorwf 0x14,w ; W-Register mit Register 0x14 xoren und in W speichern
btfsc STATUS,Z ; Teste, ob das ZERO flag im Status-Register gesetzt ist
goto ALARM1 ; Wenn ja, gehe zu ALARM1
movlw 2 ; W-Register mit 2 laden
xorwf 0x14,w ; W-Register mit Register 0x14 xoren und in W speichern
btfsc STATUS,Z ; Teste, ob das ZERO flag im Status-Register gesetzt ist
goto ALARM2 ; Wenn ja, gehe zu ALARM2
goto ALARM3 ; ok, es kann nur 3 sein. Gehe zu ALARM3

Der xor Befehl setzt immer dann das ZERO flag, wenn die beiden gexorten Werte gleich waren, ansonsten löscht er es.
Und der btfsc Befehl testet ein bestimmtes Bit. Wenn es gelöscht ist, überspringt er den nächsten Befehl. Wenn das Bit gesetzt ist, führt er den nächsten Befehl aus.
Es hilft, den btfsc Befehl beim Programmieren immer gedanklich "auszusprechen", also
"btfsc = bit test flag and skip if clear"
oder (genau der gegenteilige Befehl)
"btfss = bit test flag and skip if set"

Ich hoffe, die Erklärungen helfen.
Gruß
Phaidros

Andre_S
16.03.2006, 06:14
Hallo,

Phaidros hat es sehr schön erklärt, wobei es im Prinzip nichts anderes als ein "IF " auf Bit's ist.
Um es für Deinen Zweck mal ganz einfach darzustellen, Du testet gleich den Port, also Deinen "Eingang", wie Du oben beschrieben hast auf High oder Low.


btfsc PORTB,1 ; Teste, ob Eingang B1 High
call ALARM1 ; wenn ja, gehe zu Unterprogramm ALARM1
NOP ; wenn nein weiter im Programmablauf


Gruß André

Elo-Azubi
16.03.2006, 10:41
Super, danke euch!

So komm ich erstmal ein Stückchen weiter. Ich werd mich mal hinsetzen und das Ganze versuchen irgenwie umzusetzen.


Bin gespannt ob ich es schaffe. Ich poste dann den Quelltext, könnt ihr euch ya mal anschauen, sicher gibt es hier und da noch einiges zu verbessern.

Ich bin euch wirklich dankbar für eure Hilfe!

gruß Alex

Andre_S
16.03.2006, 10:47
Super, danke euch!

So komm ich erstmal ein Stückchen weiter. Ich werd mich mal hinsetzen und das Ganze versuchen irgenwie umzusetzen.


Bin gespannt ob ich es schaffe. Ich poste dann den Quelltext, könnt ihr euch ya mal anschauen, sicher gibt es hier und da noch einiges zu verbessern.

Ich bin euch wirklich dankbar für eure Hilfe!

gruß Alex

dafür ist doch ein Forum da,
probier einfach und wenn Probleme auftreten, dann wieder melden...


Gruß André

Elo-Azubi
20.04.2006, 08:38
Hier hab ich mich jetzt mal rangesetzt und rumprobiert...

Mein STATUS RA ist sicher nicht richtig, weil ich mit Status ja nur die Status-Bits abfragen kann, oder irre ich mich da? Würde mich über meinungen und Verbesserungsvorschläge freuen!

Gruß Alex



list P=16F84.inc

; PORTA: 0 -
; 1 -
; 2 -
; 3 -
; 4 -
; PORTB: 0 LCD Display E
; 1
; 2 LCD Display RS
; 3 LCD Display R/W
; 4-7 LCD Display D4 .. D7

#include <P16f84.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC



w_copy Equ 0x20
s_copy Equ 0x21
LcdDaten Equ 0x22
LcdStatus Equ 0x23
loops EQU 0x24
loops2 EQU 0x25

; Constanten festlegen

PORTControl equ PORTB
PORTData equ PORTB
LcdEnable equ 0
LcdRw equ 3
LcdRs equ 2
Ini_con Equ B'00000000'
Ini_opt Equ B'00000010'



Init bsf STATUS, RP0
movlw Ini_opt
movwf OPTION_REG
movlw B'11111000'
movwf TRISA
movlw B'00000000'
movwf TRISB
bcf STATUS, RP0
clrf PORTA
clrf PORTB

movlw Ini_con
movwf INTCON

call InitLCD

InitLCD
movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

Control8Bit
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable
movlw D'10'
movwf loops
call WAIT
return

OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
return

WAIT
top movlw .110
movwf loops2
top2 nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto top2

decfsz loops, F
goto top
retlw 0

LcdBusy
bsf PORTA, 1
bsf STATUS, RP0
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf PORTControl, LcdRs
bsf PORTControl, LcdRw
bsf PORTControl, LcdEnable
nop
movf PORTData, w
movwf LcdStatus
bcf PORTControl, LcdEnable
nop
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
btfsc LcdStatus, 7
goto BusyLoop
bcf PORTControl, LcdRw
bsf STATUS, RP0
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
bcf PORTA, 1
return

OutLcdDaten
bsf PORTA, 2
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
bcf PORTControl, LcdRs
bcf PORTA, 2
return

end

Bereit

movlw 'B'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'i'
movwf LcdDaten
call OutLcdDaten
movlw 't'
goto Main

Main
BTFSC STATUS, RA0
goto Alarm1
btfsc Status, RA1
goto Alarm2
btfsc Status, RA2
goto Alarm3
btfsc Status, RA3
goto Alarm4
btfsc Status, RA4
goto Alarm5
goto Main

Alarm1
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '1'
movwf LcdDaten
call OutLcdDaten
Goto check1

Alarm2
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '2'
movwf LcdDaten
call OutLcdDaten
Goto check2

Alarm3
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '3'
movwf LcdDaten
call OutLcdDaten
Goto check3

Alarm4
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '4'
movwf LcdDaten
call OutLcdDaten
Goto check4

Alarm5
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '5'
movwf LcdDaten
call OutLcdDaten
Goto check5

check1
btfsc Status, RA0
goto check1
clrdisplay
goto Main

check2
btfsc Status, RA1
goto check2
clrdisplay
goto Main

check3
btfsc Status, RA2
goto check3
clrdislay
goto Main

check4
btfsc Status, RA3
goto check4
clrdisplay
Goto Main

check5
btfsc Status, RA4
goto check5
clrdisplay
Goto Main

clrdisplay

movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdE
nop
bcf PORTB, LcdE

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

Elo-Azubi
20.04.2006, 09:56
Nochmal ich ;)

Ich hab den Quelltext nochmal geändert, nachdem ich hier offensichtlich großen Müll reingepostet hatte. Hier kommt er-



list P=16F84.inc

; PORTA: 0 -
; 1 -
; 2 -
; 3 -
; 4 -
; PORTB: 0 LCD Display E
; 1
; 2 LCD Display RS
; 3 LCD Display R/W
; 4-7 LCD Display D4 .. D7

#include <P16f84.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC



w_copy Equ 0x20
s_copy Equ 0x21
LcdDaten Equ 0x22
LcdStatus Equ 0x23
loops EQU 0x24
loops2 EQU 0x25

; Constanten festlegen

PORTControl equ PORTB
PORTData equ PORTB
LcdEnable equ 0
LcdRw equ 3
LcdRs equ 2
Ini_con Equ B'00000000'
Ini_opt Equ B'00000010'



Init bsf STATUS, RP0
movlw Ini_opt
movwf OPTION_REG
movlw B'11111000'
movwf TRISA
movlw B'00000000'
movwf TRISB
bcf STATUS, RP0
clrf PORTA
clrf PORTB

movlw Ini_con
movwf INTCON

call InitLCD
goto Main

InitLCD
movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

Control8Bit
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable
movlw D'10'
movwf loops
call WAIT
return

OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
return

WAIT
top movlw .110
movwf loops2
top2 nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto top2

decfsz loops, F
goto top
retlw 0

LcdBusy
bsf PORTA, 1
bsf STATUS, RP0
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf PORTControl, LcdRs
bsf PORTControl, LcdRw
bsf PORTControl, LcdEnable
nop
movf PORTData, w
movwf LcdStatus
bcf PORTControl, LcdEnable
nop
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
btfsc LcdStatus, 7
goto BusyLoop
bcf PORTControl, LcdRw
bsf STATUS, RP0
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
bcf PORTA, 1
return

OutLcdDaten
bsf PORTA, 2
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
bcf PORTControl, LcdRs
bcf PORTA, 2
return



Bereit

movlw 'B'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'i'
movwf LcdDaten
call OutLcdDaten
movlw 't'
movwf LcdDaten
call OutLcdDaten
goto Maintop

Main
goto clrdisplay
goto Bereit

Maintop
BTFSC PORTA,0
goto Alarm1
btfsc PORTA,1
goto Alarm2
btfsc PORTA,2
goto Alarm3
btfsc PORTA,3
goto Alarm4
btfsc PORTA,4
goto Alarm5
goto Main

Alarm1
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '1'
movwf LcdDaten
call OutLcdDaten
Goto check1

Alarm2
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '2'
movwf LcdDaten
call OutLcdDaten
Goto check2

Alarm3
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '3'
movwf LcdDaten
call OutLcdDaten
Goto check3

Alarm4
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '4'
movwf LcdDaten
call OutLcdDaten
Goto check4

Alarm5
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '5'
movwf LcdDaten
call OutLcdDaten
Goto check5

check1
btfsc PORTA,0
goto check1
goto clrdisplay
goto Main

check2
btfsc PORTA,1
goto check2
goto clrdisplay
goto Main

check3
btfsc PORTA,2
goto check3
goto clrdisplay
goto Main

check4
btfsc PORTA,3
goto check4
goto clrdisplay
Goto Main

check5
btfsc PORTA, 4
goto check5
goto clrdisplay
Goto Main

clrdisplay

movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

end


MPLAB gibt ein paar hinweise aus, aber assembliert den code vollständig.
Auf den Pic geladen bringt er trotzdem keine ausgabe auf dem LCD. Ich sehe nur schwarze Kästchen ;)

Ich nutze ein Phillips Dislplay mit negativer Kontrastspannungsansteuerung.

Ich habe probeweise auch das Beispiel von sprut.de auf den PIC gebrannt und getestet, auch da bekomm ich leider nur schwarze Kästchen...

Vieleicht wisst ihr ja Rat.

Vielen Dank im Vorraus!

djdune
20.04.2006, 10:25
Hallo erstmal!

Wenn du schon mal C++ programmiert hast, würdest du dir vielleicht leichter tun, den PIC mit C zu programmieren. Dabei ist die LCD Ansteuerung auch etwas übersichtlicher. Kostenlose Version des HiTech Lite Compilers bekommst du von www.hitech.com

Wenn du nur in einer Zeile einen schwarzen Balken hast, dann ist das Display noch nicht initialisiert. Da du aber das Sprut Programm drauf hast, schätz ich dass da ein Hardware Fehler vorliegt.

Funktioniert deine J Taste wieder?

Andre_S
20.04.2006, 10:28
Hallo,

habe leider nicht die Zeit Dein ganzes Programm anzuschauen, aber hast Du mal den Debugger benutzt um zu sehen was bei Dir passiert, nur mal so vom Ablauf.

Was mir sofort auffällt:
Du musst mal mehr auf Goto aufpassen, (Kennst Du den Unterschied zwischen Call und Goto?) da haut schon vieles nicht hin...

Und ordne Deine Unterprogramme mal sinnvoll an, so siehst Du bei größeren Programmen kaum noch durch.


Gruß André

Elo-Azubi
20.04.2006, 12:55
Also für mich bestand der unterschied zwischen Call und goto einfach nur darin, dass ich bei CALL "return" am ende der Unterprogramme schreiben muss, damit der Pic von der gesprungenen Zeile aus wieder weiter geht. Ist das so korrekt?

Das mit der Sprut LCD Ansteuerung ist etwas komisch. Ich hab es geschafft, dass das Display "Hallo" ausgibt, aber leider nur. wenn ich mit dem Finger PIN 3 (RA4/T0CLK) berühre... was könnte hier das Problem sein?

Andre_S
20.04.2006, 13:24
Yep,...

Call ist Unterprogrammaufruf, nach call wird weiter abgearbeitet, aber doch nicht nach Goto.

Nun schau Dir mal als Beispiel zwei Deiner Aufrufe an


Main
goto clrdisplay
goto Bereit
...


wie soll er von goto clrdisplay jemals zu goto Bereit kommen?




Alarm1
goto clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'



Oder wie soll er bei Aufruf Alarm1 wenn er zu crldisplay verzweigt mit dem Rest ab movlw 'A' weitermachen können.

Da kommt er doch niemals hin...


Gruß André

Elo-Azubi
21.04.2006, 06:47
Ahsooo. jetz wirds mir klar. Logisch dass das was ich da gemacht hab recht sinnlos ist.

Ich hab das mit dem Display gestern übrigens noch hinbekommen. Ich hab übersehen, dass MCLR lowaktiv ist und damit natürlichweise auch kein "Hallo" angezeigt werden kann.

Danke Andre für deine Hilfe, ich werd mich ransetzen und mich wieder melden ;)

(Zu meinem J: ich sitze am Arbeitsrechner, da funktioniert das J einwandfrei, mein Laptop ist zur Reparatur, ohne J gehts halt doch nicht, da darf man sich nichts vormachen ;) )

EinsamerUser
21.04.2006, 21:30
Das errinnert mich an mein 2. Aubildungsjahr, wobei der Beruf da noch Kommunikationselektroniker hieß. *g*

Leider durften wir damals auch schon nicht in C programmieren.
Und ich hab auch mit den selben Problemen gekämpft wie du!! *g*

Aber immerwieder schön zusehen, dass man nicht als einziger mit den Problemen zu kämpfen hatte!! :-)

Kleiner Tipp:

Sobald du nicht mehr in Assembler programmieren musst. Steig um auf C! Das macht dann erst richtig Spaß!!! *lol*

Also viel Spaß noch beim Basteln.

Gruß
Stefan

Elo-Azubi
24.04.2006, 07:10
Guten morgen!!!

Ich hab das Programm jetzt zum laufen bekommen. Es scheint hier und da noch etwas verbuggt, aber im großen und ganzen sollte es so funktionieren, bis auf eine Kleinigkeit...

hier der code:




list P=16F84a.inc

; PORTA: 0 -
; 1 -
; 2 -
; 3 -
; 4 -
; PORTB: 0 LCD Display E
; 1
; 2 LCD Display RS
; 3 LCD Display R/W
; 4-7 LCD Display D4 .. D7

#include <P16f84.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC



w_copy Equ 0x20
s_copy Equ 0x21
LcdDaten Equ 0x22
LcdStatus Equ 0x23
loops EQU 0x24
loops2 EQU 0x25

; Constanten festlegen

PORTControl equ PORTB
PORTData equ PORTB
LcdEnable equ 0
LcdRw equ 3
LcdRs equ 2
Ini_con Equ B'00000000'
Ini_opt Equ B'00000010'



Init bsf STATUS, RP0
movlw Ini_opt
movwf OPTION_REG
movlw B'11111000'
movwf TRISA
movlw B'00000000'
movwf TRISB
bcf STATUS, RP0
clrf PORTA
clrf PORTB

movlw Ini_con
movwf INTCON
BSF TRISA, 0
bsf TRISA, 1
bsf TRISA, 2
bsf TRISA, 3
bsf TRISA, 4

call InitLCD
goto Main

InitLCD
movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

Control8Bit
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable
movlw D'10'
movwf loops
call WAIT
return

OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
return

WAIT
top movlw .110
movwf loops2
top2 nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto top2

decfsz loops, F
goto top
retlw 0

LcdBusy
bsf PORTA, 1
bsf STATUS, RP0
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf PORTControl, LcdRs
bsf PORTControl, LcdRw
bsf PORTControl, LcdEnable
nop
movf PORTData, w
movwf LcdStatus
bcf PORTControl, LcdEnable
nop
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
btfsc LcdStatus, 7
goto BusyLoop
bcf PORTControl, LcdRw
bsf STATUS, RP0
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
bcf PORTA, 1
return

OutLcdDaten
bsf PORTA, 2
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
swapf LcdDaten, w
andlw H'F0'
movwf PORTData
bsf PORTControl, LcdRs
bsf PORTControl, LcdEnable
nop
bcf PORTControl, LcdEnable
bcf PORTControl, LcdRs
bcf PORTA, 2
return



Bereit

movlw 'B'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'e'
movwf LcdDaten
call OutLcdDaten
movlw 'i'
movwf LcdDaten
call OutLcdDaten
movlw 't'
movwf LcdDaten
call OutLcdDaten
goto Maintop

Main
CALL clrdisplay
goto Bereit

Maintop
BTFSC PORTA,0
goto Alarm1
btfsc PORTA,1
goto Alarm2
btfsc PORTA,2
goto Alarm3
btfsc PORTA,3
goto Alarm4
btfsc PORTA,4
goto Alarm5
goto Maintop

Alarm1
CALL clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '1'
movwf LcdDaten
call OutLcdDaten
goto check1

Alarm2
call clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '2'
movwf LcdDaten
call OutLcdDaten
Goto check2

Alarm3
call clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '3'
movwf LcdDaten
call OutLcdDaten
Goto check3

Alarm4
call clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '4'
movwf LcdDaten
call OutLcdDaten
Goto check4

Alarm5
call clrdisplay
movlw 'A'
movwf LcdDaten
call OutLcdDaten
movlw 'l'
movwf LcdDaten
call OutLcdDaten
movlw 'a'
movwf LcdDaten
call OutLcdDaten
movlw 'r'
movwf LcdDaten
call OutLcdDaten
movlw 'm'
movwf LcdDaten
call OutLcdDaten
movlw '5'
movwf LcdDaten
call OutLcdDaten
Goto check5

check1
btfsc PORTA,0
goto check1
CALL clrdisplay
goto Main

check2
btfsc PORTA,1
goto check2
CALL clrdisplay
goto Main

check3
btfsc PORTA,2
goto check3
CALL clrdisplay
goto Main

check4
btfsc PORTA,3
goto check4
CALL clrdisplay
Goto Main

check5
btfsc PORTA,4
goto check5
CALL clrdisplay
Goto Main

clrdisplay

movlw D'255'
movwf loops
call WAIT

movlw B'00110000'
movwf PORTB
bsf PORTB, LcdEnable
nop
bcf PORTB, LcdEnable

movlw D'50'
movwf loops
call WAIT

movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit

movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
return

end



Port RA4 macht mir Probleme, er nimmt mein High nicht an... es passiert gar nichts. Muss ich noch eine andere Einstllung vornehmen, damit er als Eingang klassifiziert wird, oder hab ich sonst etwas vergessen?


Hier hab ich auf Eingang geschalten:



Init bsf STATUS, RP0
movlw Ini_opt
movwf OPTION_REG
movlw B'11111000'
movwf TRISA
movlw B'00000000'
movwf TRISB
bcf STATUS, RP0
clrf PORTA
clrf PORTB

movlw Ini_con
movwf INTCON
BSF TRISA, 0
bsf TRISA, 1
bsf TRISA, 2
bsf TRISA, 3
bsf TRISA, 4





Was hab ich falsch gemacht?

Ich wünsch euch allen ne erfolgreiche Woche !

Elo-Azubi
24.04.2006, 08:22
Korrektur 8-[


Ich habe den RA4 probeweise nicht als Eingang deklariert, erfolgreich. es gibt aber leider noch ein Problem, dessen Lösung ich einfach nicht finde.

Wenn ich einen High Pegel an Pin1 lege, passiert nur eins: Das Display geht aus (?)... nehme ich den High Pegel weg, so erscheint ganz kurz "Alarm3" auf dem Display und dann wieder "Bereit".

Wo kann da das Problem liegen? Es ist ja eigentlich alles gleich programmiert... Gibt es eine Besonderhit an Pin 1? Oder sieht jemand einen Programmierfehler, der mir nicht auffällt?

EinsamerUser
24.04.2006, 12:55
könnte vielleicht daran hängen, dass du in den LCD-Routinen immernoch RA1,


LcdBusy
bsf PORTA, 1
.
.
.
.
bcf PORTA,1

und


OutLcdDaten
bsf PORTA, 2
.
.
.
bcf PORTA,2

drin stehen hast!!

Ich würde zwar generell sagen, das es nichts ausmacht, da er den Befehl nicht übernimmt, wenn der PORT-Pin als Eingang geschaltet ist.

Aber ich hab schon ganz andere Mysterien aufm PIC erlebt.

Check das mal nach! :-)

Gruß
Stefan

Elo-Azubi
24.04.2006, 22:21
...und es macht doch was aus...

genau dasselbe ist mir dann auch aufgefallen. Probeweise ein ; davor gesetzt. Klappt... nur das der Fehler nun nicht mehr an pin1 sondern an pin 18 tranferriert wurde ;)

Dasselbe ; nochmal vor die andere... und schon liegt der Fehler nicht mehr an Pin 1... und auch nicht mehr an pin 18...sondern an pin17...

ich wusste nicht weiter, also muss ich den Fehler wohl so hinnehmen. Alles rückgängig gemacht und hin nd her überlegt. Dann hab ich einfach beschlossen, auf pin1 meine Lichtschranke zu setzen. Gibt die ein Signal, dann nur Kurz. Den Rücksprung in "Bereit" entfernt, und ein Sleep hinten ran gesetzt. Nun erscheint bei einem Kurzen Impuls auf pin1 LICHTSCHRANKE auf dem Display...und bleibt. In meiner endschaltung werde ich dann wohl oder übel einen "Pseudo-Lichtschrankenreset"-Taster einbauen, der eben den ganzen Pic zurücksetzt.
Nunja, eigentlich wollte ich noch ein paar andere Sachen mit einbauen, aber mitlerweile bin ich mit dem jetzigen Resultat zufrieden und hab erstmal die faxen mit dem Pic dick.

Obwohl... ich bekomme doch Lust auf einen Quick Power On Self Test für meine Alarmanalge... gesteuert von meiner neuen Leidenschaft ^^

Mal sehn was sich da berichten lässt ^^

EinsamerUser
25.04.2006, 20:13
hast du auch alles Kontrolliert? Nicht das irgendwo an einer anderen Stelle PORTA in irgendeiner Weise verwendet wird??

Gruß
Stefan

Elo-Azubi
25.04.2006, 22:17
ausser die beiden beispiele die du genannt hast ist mir auch nix aufgefallen... ich schau morgen nochmal und stell den code nochmal rein... aber eigentlich sollte es an keiner anderen stelle sein... nochmal prüfen.

kennst du ein gutes tutorial zur C programmierung?

Andy62
26.04.2006, 00:10
> Port RA4 macht mir Probleme, er nimmt mein High nicht an... es passiert gar

RA4 ist bei vielen PICs, wenn als Ausgang programmiert, vom Typ Open-Collector.

Du benötigst also einen Pull-Up Widerstand, damit er auf High gehen kann.

Gruss

Andy

EinsamerUser
26.04.2006, 12:59
nö fällt mir jetzt konkret nix ein.

Und selbst wenn, willst ein Tutorial für C-Programmierung aufm PIC oder fürn PC haben?

Aber ich weis wer dir auf jedenfall weiterhelfen kann.

Frag einfach mal Google *grins* ;-)

Gruß
Stefan