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
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
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
MfG Karl-Heinz
HobbyElektronik hier klicken ....
Hallo Alex,Zitat von Elo-Azubi
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é
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!
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:
Der xor Befehl setzt immer dann das ZERO flag, wenn die beiden gexorten Werte gleich waren, ansonsten löscht er es.Code: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
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
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.
Code:btfsc PORTB,1 ; Teste, ob Eingang B1 High call ALARM1 ; wenn ja, gehe zu Unterprogramm ALARM1 NOP ; wenn nein weiter im Programmablauf
Gruß André
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,Zitat von Elo-Azubi
probier einfach und wenn Probleme auftreten, dann wieder melden...
Gruß André
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
Code: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
Nochmal ich
Ich hab den Quelltext nochmal geändert, nachdem ich hier offensichtlich großen Müll reingepostet hatte. Hier kommt er-
Code: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!
Lesezeichen