Guten Tag, Ich habe erst vor 3 Wochen mit PIC-Programmierung angefangen. Ich habe schon ein fertiges programm im internet gefunden und wollte das umschreiben. Hier mein umgeschriebenes Programm: ;***************** ;* Programmstart * ;***************** ORG 00H ; Das Programm wird ab Speicherstelle 0 in den Speicher geschrieben GOTO init ; Springe zur Grundinitialisierung der Ports A und B ;******************* ;* Initialisierung * ;******************* init BSF STATUS,RP0 ; wechsle zu Registerbank 1 (spezielle Register) MOVLW B'00011111' MOVWF TRISA ; RA0 .. RA4 Eingänge MOVLW B'00000000' MOVWF TRISB ; RB0-RB7 Ausgänge BCF STATUS,RP0 ; wechsle zu Registerbank 0 (normaler Speicherbereich) MOVLW b'00000111' ; Komparatoren abschalten, nur Digitalports MOVWF CMCON CLRF PORTA ; Port A löschen CLRF PORTB ; Port B löschen ;***************** ;* Hauptprogramm * ;***************** main MOVF PORTA,W ; Lade Zustand von Port A in Arbeitsregister W CALL table ; Springe zur Tabelle MOVWF PORTB ; Schreibe Arbeitsregister nach Port B GOTO main ; Wiederhole... ; Dekodier-Tabelle ;****************** table ADDWF PCL,F ; Addiere Arbeitsregister zum Programmzähler RETLW B'00111111' ; 7-Segment-Code für die Ziffer '0' RETLW B'00000110' ; 7-Segment-Code für die Ziffer '1' RETLW B'01011011' ; 7-Segment-Code für die Ziffer '2' RETLW B'01001111' ; 7-Segment-Code für die Ziffer '3' RETLW B'01100110' ; 7-Segment-Code für die Ziffer '4' RETLW B'01101101' ; 7-Segment-Code für die Ziffer '5' RETLW B'01111101' ; 7-Segment-Code für die Ziffer '6' RETLW B'00000111' ; 7-Segment-Code für die Ziffer '7' RETLW B'01111111' ; 7-Segment-Code für die Ziffer '8' RETLW B'01101111' ; 7-Segment-Code für die Ziffer '9' RETLW B'01110111' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111100' ; 7-Segment-Code für die Ziffer 'E' RETLW B'00111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01011110' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01110001' ; 7-Segment-Code für die Ziffer 'E' END ______________________________________________________________________ ___________ Meine Fragen: 1. Bei den "RETLW" Befehlen waren die Buchstagen nach den Ziffern von a bis f definiert. Ich möchte da aber nur das E für error haben. geht das so oder muss man das noch wo anders definieren? 2. Ich möchte an Pin 0 von Port A ein "Übernahmetaster" mit einbauen und die 4 ansteuerungstaster für den BCD-Code sollen von Pin 1-4 sein (Port A). wo wird das definiert? 3. Der Übernahmetaster soll folgendermaßen funktionieren: Er ist an Pin 0 von Port A angeschlossen. Man soll die 4 Taster beliebig umstellen können ohne das man es auf der 7 Segmentanzeige sieht. Drückt man den taster soll es eine art aktuallisierung sein und er zeigt den momentanen wert der tasterkombination so lange an, bis der taster erneut gedrückt wird. hoffe ich habe mich verständlich ausgedrückt. würde mich über hilfe freuen gruß
Mir scheint, da fehlen noch reichlich Grundlagen. Für PIC-Anfänger immer wieder gern vorgeschlagen: www.sprut.de Ein erster Tip: > RETLW B'00111111' ; 7-Segment-Code für die Ziffer '0' > RETLW B'00000110' ; 7-Segment-Code für die Ziffer '1' > RETLW B'01011011' ; 7-Segment-Code für die Ziffer '2' > RETLW B'01001111' ; 7-Segment-Code für die Ziffer '3' > RETLW B'01100110' ; 7-Segment-Code für die Ziffer '4' > RETLW B'01101101' ; 7-Segment-Code für die Ziffer '5' > RETLW B'01111101' ; 7-Segment-Code für die Ziffer '6' > RETLW B'00000111' ; 7-Segment-Code für die Ziffer '7' > RETLW B'01111111' ; 7-Segment-Code für die Ziffer '8' > RETLW B'01101111' ; 7-Segment-Code für die Ziffer '9' > RETLW B'01110111' ; 7-Segment-Code für die Ziffer 'E' > RETLW B'01111100' ; 7-Segment-Code für die Ziffer 'E' > RETLW B'00111001' ; 7-Segment-Code für die Ziffer 'E' > RETLW B'01011110' ; 7-Segment-Code für die Ziffer 'E' > RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' > RETLW B'01110001' ; 7-Segment-Code für die Ziffer 'E' Hinter einem ';' steht nur Kommentar, das ignoriert der Assembler. Wenn du da etwas Änderst, hat das keine Auswirkungen. Also: Wenn du die Ausgabe von 'A' nach 'E' ändern willst, dann musst du die Ansteuerung der Segmente anpassen. Im Original-Code war für 'E' folgende Zeile: > RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' Das heisst '01111001' ergibt ein 'E' auf deiner Anzeige (jede 1 ist ein leuchtendes Segment). Und nun überlege mal, was du ändern musst, damit '0'-'9' und dann nur noch 'E' ausgegeben wird.
hmm... ich habe hier mit meinen Unterlagen und Befehlslisten echt ne halbe stunde überlegt aber da ist nichts sinnvolles bei rausgekommen. Meine beste überlegung war mit einem BTFSS befehl die bits abfragen und wenn es a,b,c,d oder f wäre, würde er die ausgabe überspringen und dann ein direkten goto befehl zu dem "E" setzen
Also: Was das Programm jetzt macht ist, dass es in Abhängigkeit von PORTA einen der Werte 0 1 2 3 4 5 6 7 8 9 A B C D E F ausgibt und dass endloos. Am PORTA können ja die Werte 0-15 anliegen. Ausgegeben wird dann an der Anzeige (an PORTB) Eingabe PORTA 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Ausgabe PORTB 0 1 2 3 4 5 6 7 8 9 A B C D E F Willst du stattdessen Eingabe PORTA 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Ausgabe PORTB 0 1 2 3 4 5 6 7 8 9 E E E E E E musst du nur deine Tabelle ändern in RETLW B'00111111' ; 7-Segment-Code für die Ziffer '0' RETLW B'00000110' ; 7-Segment-Code für die Ziffer '1' RETLW B'01011011' ; 7-Segment-Code für die Ziffer '2' RETLW B'01001111' ; 7-Segment-Code für die Ziffer '3' RETLW B'01100110' ; 7-Segment-Code für die Ziffer '4' RETLW B'01101101' ; 7-Segment-Code für die Ziffer '5' RETLW B'01111101' ; 7-Segment-Code für die Ziffer '6' RETLW B'00000111' ; 7-Segment-Code für die Ziffer '7' RETLW B'01111111' ; 7-Segment-Code für die Ziffer '8' RETLW B'01101111' ; 7-Segment-Code für die Ziffer '9' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' Dann wird für alle Eingabewerte grösser 9 ein 'E' ausgegeben
@Myho sowas vielleicht?
1 | ;***************** |
2 | ;* Hauptprogramm * |
3 | ;***************** |
4 | |
5 | main MOVF PORTA,W ; Lade Zustand von Port A in Arbeitsregister W |
6 | BSF STATUS,C ; setze Carry-Bit |
7 | SUBLW 0x09 ; wenn der Wert in W größer ist als 0x09, |
8 | ; wird das Carry-Bit GELÖSCHT (mußte ich auch erst mal drauf kommen) |
9 | MOVLW 0x0E ; W mit 0x0E laden (Carry-Bit wird dadurch nicht beeinflußt) |
10 | BTFSC STATUS,C ; Carry-Bit auswerten |
11 | MOVF PORTA,W ; Carry-Bit war noch gesetzt, Wert an PORTA gültig |
12 | |
13 | CALL table ; Springe zur Tabelle |
14 | MOVWF PORTB ; Schreibe Arbeitsregister nach Port B |
15 | GOTO main ; Wiederhole... |
16 | |
17 | ; Dekodier-Tabelle |
18 | ;****************** |
19 | |
20 | table ADDWF PCL,F ; Addiere Arbeitsregister zum Programmzähler |
21 | RETLW B'00111111' ; 7-Segment-Code für die Ziffer '0' |
22 | RETLW B'00000110' ; 7-Segment-Code für die Ziffer '1' |
23 | RETLW B'01011011' ; 7-Segment-Code für die Ziffer '2' |
24 | RETLW B'01001111' ; 7-Segment-Code für die Ziffer '3' |
25 | RETLW B'01100110' ; 7-Segment-Code für die Ziffer '4' |
26 | RETLW B'01101101' ; 7-Segment-Code für die Ziffer '5' |
27 | RETLW B'01111101' ; 7-Segment-Code für die Ziffer '6' |
28 | RETLW B'00000111' ; 7-Segment-Code für die Ziffer '7' |
29 | RETLW B'01111111' ; 7-Segment-Code für die Ziffer '8' |
30 | RETLW B'01101111' ; 7-Segment-Code für die Ziffer '9' |
31 | RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' |
Und zum "Übernahmetaster" an RA0: Du wartest in einer Endloos-Schleife bis der RA0 0 oder 1 ist (je nach dem, wie der Taster angeschlossen ist) und gibst dann den Wert von RA1..4 aus. Der Anfang deines Programms sollte so aussehen: ;***************** ;* Programmstart * ;***************** TEMP EQU 0x0C ; Speicher für Temp-Variable ORG 00H ; Reset-Vector GOTO init ; Springe zur Grundinitialisierung der Ports A und B ORG 04H ; Interrupt-Vector GOTO init ; auch zu init (weil kein Interrupt aktiv) Dein Hauptprogramm sollte dann so etwa aussehen: ;***************** ;* Hauptprogramm * ;***************** Deine MAIN-Routine sollte dann ungefär so aussehen (nicht getestet): main waret_auf_taste BTFSC PORTA,0 ; Taste gedrückt? GOTO warte_auf_taste ; nein, warten MOVF PORTA,W ; Lade Zustand von Port A in Arbeitsregister MOVWF TEMP ; Speichern RRF TEMP,W ; Nach rechts schieben und nach W ANDLW b'00000111' ; gewünschte Bits maskieren CALL table ; Springe zur Tabelle (Wert ist in W) MOVWF PORTB ; Schreibe Arbeitsregister nach Port B GOTO main ; Wiederhole... Aber vielleicht solltest du noch kleiner anfangen und ersteinmal eine LED in Abhängigkeit von einem Taster zum Leuchten bringen
hey das ist gut das könnte funktionieren coole sache dankeschön hab trotzdem noch eine "definitions frage" und zwar: muss nicht irgendwo definiert werden an welchem Pin z.B. der Übernahmetaster sein muss? Was ist wenn man angenommen ein "a" oder ein "c" mit dem passenden BCD Code ansteuert? das ist ja gar nicht aufgeführt... dann soll ja das "E" kommen. wie wird das denn nun gemacht?
als erstes solltest du dafür sorgen das du nicht über deine tabelle hinweg springst, das kannst du machen indem du nach dem einlesen des port a ein: andlw h'0F' machst damit lässt du nur die unteren 4 bits des port a passieren, ansonsten musst du daráuf achten das die andren 4567 auch auf low sind, jenachdem wie du sie konfiguriert hast, wenn ich recht schätze hast du den 16f628 im einsatz!? in der routine von tastendrücker ist das ganze so aisgeführt das der taster per pull up an 5v gehaten wird, wird er geschlossen zieht er den jeweilige pin auf 0, das merkt der pic und geht aus seiner warteschleife. kannst zb 10k als pull up nehmen. jetzt sind auch in der routine noch fehler enthalten: MOVWF TEMP ; Speichern RRF TEMP,W ; Nach rechts schieben und nach W ANDLW b'00000111' ; gewünschte Bits maskieren CALL table ; Springe zur Tabelle (Wert ist in W) MOVWF PORTB ; Schreibe Arbeitsregister nach Port B GOTO main ; Wiederhole... su solltest einfach den porta,7 nehmen, stelle in der entwicklungsumgebung entsprechend ein, das restet nicht aktiv sein soll, programming bits... hast du einen externen quarz oder nutzt du den internen oszi? ansonsten könntest du auch die anderen port a bits nutzen (5,6)... bei der routine oben sind fehler enthalten, wenn su also den pic ohne sonderliche veränderunegen nutzt, kannst du auch prorta,4 als eingang nutzen für den taster, der code oben geht davon aus das du die anschlüsse port a 1-4 als bcd nutzt schließt aber nicht aus das du die pins ra5-7 auch aktiviert hast... was bei deinem modell pic möglich wäre denn er hat comperatoren und ist damit kein f84 ... also, mein vorschlag: nutze porta,4 als eíngang für den taster, und die bits ra0-3 für den bsd code. und vergiss nicht die bits auszumaskieren mit: movf porta,w andlw h'0f' call table viel spass. whitenoise ps.: btfsc steht für Bit Test F(register) Scip if Clear, der nächste befehl wird übersprungen wenn das spezielle bit in diesem fall clear ist, wenn du deinen taster nach plus angeschlossen hast, brauchst du nur den befehl ändern in btfss (if Set) ändern. übrigens, das was du suchst kann zb auch die til311 ganz ohne controller, einfach taster an der freigabeeingan anlegen und das bcd zeichen für e anlegen...
@whitenose Beim 16f84a hat der PORTA nur 5 Pins (RA0..RA4) und meine Maskierung MOVWF TEMP ; Speichern RRF TEMP,W ; Nach rechts schieben und nach W ANDLW b'00000111' ; gewünschte Bits maskieren CALL table ; Springe zur Tabelle (Wert ist in W) MOVWF PORTB ; Schreibe Arbeitsregister nach Port B GOTO main ; Wiederhole... setzt voraus, dass der Taster an RA4 sitzt (wie vom TO gepostet) und verhindert auch, dass die Tabelle "übersprungen" wird.
Ich habe jetzt soweit das Programm fertig wo ich denke das funktioniert so (dank eurer Hilfe) Hier das Programm: ; ********************************************* ; * 7segment2.asm - BCD zu 7-Segment Decoder * ; ********************************************* ; ; Zeichen Segmente ; 0 a,b,c,d,e,f ; 1 b,c ; 2 a,b,d,e,g ; 3 a,b,c,d,g ; 4 b,c,f,g ; 5 a,c,d,f,g ; 6 a,c,d,e,f,g ; 7 a,b,c ; 8 a,b,c,d,e,f,g ; 9 a,b,c,d,f,g ; E a,d,e,f,g ; ; ; ; EINGÄNGE: ; ; PortA,0 -> Übernahmetaster ; PortA,1 -> BCD-1 - Schließer ; PortA,2 -> BCD-2 - Schließer ; PortA,3 -> BCD-4 - Schließer ; PortA,4 -> BCD-8 - Schließer ; ; ; AUSGÄNGE: ; ; PortB,0 -> Segment a ; PortB,1 -> Segment b ; PortB,2 -> Segment c ; PortB,3 -> Segment d ; PortB,4 -> Segment e ; PortB,5 -> Segment f ; PortB,6 -> Segment g ;*********************************************************************** **** ;* Bestimmung des Prozessortyps für den Assembler und das Programmiergerät * ;*********************************************************************** **** LIST P=16F84A ;****************************************** ;* Includedatei für den 16F84A einbinden * ;****************************************** #include <P16f84a.INC> ;***************** ;* Programmstart * ;***************** TEMP EQU 0x0C ; Speicher für Temp-Variable ORG 00H ; Reset-Vector GOTO init ; Springe zur Grundinitialisierung der Ports A und B ORG 04H ; Interrupt-Vector GOTO init ; auch zu init (weil kein Interrupt aktiv) ;******************* ;* Initialisierung * ;******************* init BSF STATUS,RP0 ; wechsle zu Registerbank 1 (spezielle Register) MOVLW B'00011111' MOVWF TRISA ; RA0 .. RA4 Eingänge MOVLW B'00000000' MOVWF TRISB ; RB0-RB7 Ausgänge BCF STATUS,RP0 ; wechsle zu Registerbank 0 (normaler Speicherbereich) MOVLW b'00000111' ; Komparatoren abschalten, nur Digitalports MOVWF CMCON CLRF PORTA ; Port A löschen CLRF PORTB ; Port B löschen ;***************** ;* Hauptprogramm * ;***************** main waret_auf_taste BTFSC PORTA,0 ; Taste gedrückt? GOTO warte_auf_taste ; nein, warten MOVF PORTA,W ; Lade Zustand von Port A in Arbeitsregister MOVWF TEMP ; Speichern RRF TEMP,W ; Nach rechts schieben und nach W ANDLW b'00000111' ; gewünschte Bits maskieren CALL table ; Springe zur Tabelle (Wert ist in W) MOVWF PORTB ; Schreibe Arbeitsre ;******************** ;* Dekodier-Tabelle * ;******************** table ADDWF PCL,F ; Addiere Arbeitsregister zum Programmzähler RETLW B'00111111' ; 7-Segment-Code für die Ziffer '0' RETLW B'00000110' ; 7-Segment-Code für die Ziffer '1' RETLW B'01011011' ; 7-Segment-Code für die Ziffer '2' RETLW B'01001111' ; 7-Segment-Code für die Ziffer '3' RETLW B'01100110' ; 7-Segment-Code für die Ziffer '4' RETLW B'01101101' ; 7-Segment-Code für die Ziffer '5' RETLW B'01111101' ; 7-Segment-Code für die Ziffer '6' RETLW B'00000111' ; 7-Segment-Code für die Ziffer '7' RETLW B'01111111' ; 7-Segment-Code für die Ziffer '8' RETLW B'01101111' ; 7-Segment-Code für die Ziffer '9' RETLW B'01111001' ; 7-Segment-Code für die Ziffer 'E' END __________________________________________________________________ wenn ich nun "build all" mache, kommt folgende Fehlermeldung mit der ich nicht klar komme: *Error[113] C:\PIC\7SEGMENT2.ASM 77 : Symbol not previously defined (CMCON) Error[113] C:\PIC\7SEGMENT2.ASM 90 : Symbol not previously defined (warte_auf_taste)* (hab mal das wichtige rauskopiert)
wer lesen kann ist klar im vorteil (waret... und warte.. ist wohl kaum das gleiche) und ich kanns nur nochmal sagen - dein controller ist ein f84a und kein f628a - der hat keine komparatoren - weniger code copieren - mehr nachdenken und vor allem gründlich lesen! whitnenoise
Ja du hast recht. Und wie schaff ich es nun diesen "CMCON" Befehl um zu schreiben das es für den f84a funktioniert? Den kenn ich gar nicht und bei google hab ich auch nicht viel gefunden.
1) > MOVLW b'00000111' ; Komparatoren abschalten, nur Digitalports > MOVWF CMCON der 16f84 hat keine Komparatoren, also kann ma die auch nicht abschalten...weg mit den Zeilen 2) >warte_auf_taste (NICHT waret_auf_taste) > BTFSC PORTA,0 ; Taste gedrückt? > GOTO warte_auf_taste ; nein, warten 3) (mein Fehler) MOVWF TEMP ; Speichern RRF TEMP,W ; Nach rechts schieben und nach W ANDLW b'00001111' ; gewünschte Bits maskieren Und dann wird dein Prog immer noch nicht funktionieren. Z.B. kannst du über die Eingänge 16 Werte eingeben (0..15) deine Tabelle hat jetzt aber nur noch 11 Einträge. Was passiert wenn du 13 eingibst? Versuche erst einmal den Controller, den du verwendest kennenzulernen und dan n das Programm zu verstehen. Bitte die Tipps, die dir hier gegeben werden, nicht als abschreibfertige Lösungen ansehen.
danke dir ich werde erstmal ein tag darüber nachdenken. vielleicht fällt mir ja eine lösung ein
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.