Kann mir den keiner helfen?
Jo
Hallo,
hatte folgendes bereits bei microcontroller.net schon geschrieben:
"
Hallo,
ich bin grade dabei ein elektronisches Handrad für eine CNC-Fräse zu
bauen.
Für die Anzeige der aktiven Achse breuchte ich eine Logik, die mir aus 2
Leitungen 4 LED ansteuert.
Ich weiß das könnte man auch einfach mit der 74 TTL reihe (4 and und 2
invertern) realisieren. Aber ich wollte jetzt doch etwas mal mit einem
PIC16F84A machen. Also dachte ich mir ich les mal ein bisschen im I-Net
nach, bin aber leider noch nicht auf einen grünen Zweig gekommen.
Ich weiß durch spurt mittlerweile, dass ich erstmal die ein ung augänge
initalisieren muss mit dem TRISx-Register soweit ich das verstanden
habe, nur dann wird es schwierig.
Könnte mir vielleich jemand einen einfachen und übersichtlichen
Lösungsweg zeigen? Das soll jetzt nicht so sein lass einfach mal die
anderen das machen, ich hab jetzt mittlerweile 1,5 Tage investiert aber
sehe leider immer noch keinen richtigen Ansatz´, wäre also für jede Hilf
dankbar.
Ich hab mir das so gedacht, den Port A des PIC16F84A nehme ich als
Eingang und den Port B als Ausgang.
Input #1 = RA2
Input #2 = RA3
LED x = RB4
LED y = RB5
LED z = RB6
LED a = RB7
LEDx= nicht(Input #1) und nicht(Input #2)
LEDy= Input #1 und nicht(Input #2)
LEDz= nicht(Input #1) und Input #2
LEDa= Input #1 und Input #2
ich weiß etwas blöd geschrieben aber wusste nicht wie sonst.
Und wie bereits gesagt ich weiß ein PIC ist dafür etwas Oversized, aber
ich habe mich bewusst dafür entschieden, um mal mit etwas einfachen in
Assembler anzufangen.
Oder ist Assembler nicht so gut für den Anfang? Ich kann leider bis
jetzt keine Programmiersprache, außer Java, das lernen wir gerade an der
UNI.
Ich hoffe mir kann jemand helfen und schon mal vielen vielen Dank für
eure Mühe.
Danke Jo
"
leider habe ich keine für mich gute Antwort bekommen
also habe ich mich daran gemacht mal etwas zu experimentieren,
nach ettlichen verschiedenen Ansätzen bin ich nun zu diesem Ergebnis gelangt :
beim Umsetzen in eine hex gibts folgende Meldungen, welche soweit ich weiß weiter nicht schlimm sind:Code:list p=16f84a ;************************************************************** ;* Pinbelegung ;* ---------------------------------- ;* PORTA: Eingänge ;* 0 - PIN 17 - Tastereingang ;* 1 - PIN 18 - n.c. ;* 2 - PIN 01 - Input #4 ;* 3 - PIN 02 - Input #5 ;* 4 - PIN 03 - n.c. ;* PORTB: ;* 0 - PIN 06 - Tastersignal ;* 1 - PIN 07 - n.c. ;* 2 - PIN 08 - n.c. ;* 3 - PIN 09 - n.c. ;* 4 - PIN 10 - LED x-Achse ;* 5 - PIN 11 - LED y-Achse ;* 6 - PIN 12 - LED z-Achse ;* 7 - PIN 13 - LED a-Achse ;* ;************************************************************** ; ;jorues 30.03.2007 ; ; Handradlogik ; ; Taktquelle: 4 MHz ; ;************************************************************** ; Includedatei für den 16F84A einbinden #include <P16f84a.INC> ; Configuration festlegen ; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator __CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC ;************************************************************** ; Variablen festlegen Input Equ 0x20 Input_kor Equ 0x21 Result Equ 0x22 ; Constanten festlegen Ini_con Equ B'00000000' ; TMR0 -> Intetupt disable Ini_opt Equ B'00000010' ; pull-up digit0 Equ B'00000000' ; Wert0 festlegen digit1 Equ B'00000100' ; Wert1 festlegen digit2 Equ B'00001000' ; Wert2 festlegen digit3 Equ B'00001100' ; Wert3 festlegen LED_X Equ B'00010000' ; LED für X-Achse LED_Y Equ B'00100000' ; LED für Y-Achse LED_Z Equ B'01000000' ; LED für Z-Achse LED_A Equ B'10000000' ; LED für A-Achse ;************************************************************* ; Das Programm beginnt mit der Initialisierung Init bsf STATUS, RP0 ; Bank 1 movlw Ini_opt ; pull-up on movwf OPTION_REG ; movlw B'11111111' ; PortA alle inputs movwf TRISA ; movlw B'00000000' ; PortB alle outputs movwf TRISB ; bcf STATUS, RP0 ; Bank 0 clrf PORTA clrf PORTB movlw Ini_con ; Interupt disable movwf INTCON clrw ;**************************************************************** Main movfw PORTA ; Port A lesen und nach W kopieren movwf Input ; von W in Input (0x20) kopieren clrw ; W löschen bcf Input,0 ; bcf Input,1 ; alle Bits von Input1 bis auf entscheidende Bits 2 und 3 werden bcf Input,4 ; auf 0 gesetzt bcf Input,5 ; bcf Input,6 ; bcf Input,7 ; movfw Input ; Input in Input_kor schreiben movwf Input_kor clrw ; W löschen ;**************************************************************** ; Input vergleichen X_achse movfw Input_kor ; Input_kor wird in W geladen xorwf digit0,0 ; Input_kor und digit0 werden verglichen, Ergenbins in W movwf Result ; Ergebnis wird in Result gespeichert clrw ; W löschen btfss Result,2 ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat btfsc Result,3 ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat goto Y_achse ; sprung zu Y_achse bsf PORTB,7 ; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet goto Main ;**************************************************************** Y_achse clrf PORTB movfw Input_kor ; Input_kor wird in W geladen xorwf digit1,0 ; Input_kor und digit1 werden verglichen, Ergenbins in W movwf Result ; Ergebnis wird in Result gespeichert clrw ; W löschen btfss Result,2 ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat btfsc Result,3 ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat goto Z_achse ; sprung zu Z_achse bsf PORTB,6 ; Bit 6 von PORTB wird auf high gesetzt, die LED für Y-Achse leuchtet goto Main ;**************************************************************** Z_achse clrf PORTB movfw Input_kor ; Input_kor wird in W geladen xorwf digit2,0 ; Input_kor und digit2 werden verglichen, Ergenbins in W movwf Result ; Ergebnis wird in Result gespeichert clrw ; W löschen btfss Result,2 ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat btfsc Result,3 ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat goto A_achse ; sprung zu A_achse bsf PORTB,5 ; Bit 5 von PORTB wird auf high gesetzt, die LED für Z-Achse leuchtet goto Main ;**************************************************************** A_achse clrf PORTB movfw Input_kor ; Input_kor wird in W geladen xorwf digit3,0 ; Input_kor und digit3 werden verglichen, Ergenbins in W movwf Result ; Ergebnis wird in Result gespeichert clrw ; W löschen btfss Result,2 ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat btfsc Result,3 ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat goto X_achse ; sprung zu X_achse bsf PORTB,4 ; Bit 4 von PORTB wird auf high gesetzt, die LED für A-Achse leuchtet goto Main ;**************************************************************** end
Beim Brennen gibts auch keine Fehler.Code:Message[302] C:\ASM\ROUTINE.ASM 63 : Register in operand not in bank 0. Ensure that bank bits are correct. Message[302] C:\ASM\ROUTINE.ASM 65 : Register in operand not in bank 0. Ensure that bank bits are correct. Message[302] C:\ASM\ROUTINE.ASM 67 : Register in operand not in bank 0. Ensure that bank bits are correct.
Aber leider funktioniert das ganze auf dem Testboard garnicht. Es geschieht nichts. Der ResetPin liegt auf VDD daran kanns also nicht liegen.
Kann jemand den Code mal anschauen, sicher gibt es einfachere Lösungen aber das war das einzige was mir in meinem ersten Code so eingefallen ist.
Vielen Vielen Vielen Dank
Jo
Kann mir den keiner helfen?
Jo
Schau dir mal unter Microchip\MPASM Suite\Template\Code das Grundgerüst eines Programms für deinen Controller an. In deinem Code fehlt
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program
MFG
Ralf
Hallo,
ich möchte vorausschicken, dass ich mit dem PIC keine Erfahrung habe, also prozessor- und hardwarespezifische Einstellungen kann ich nicht kommentieren, und mit CNC-Fräsen kenn' ich mich auch nicht aus. Aber ich komme mit Deinem Code nicht so recht klar. Der Assembler-Einstieg ist (von Java kommend) schon etwas heftig (aber zweifellos lohnenswert; einfacher wäre C). Mein Tip: zeichne Dir mal die Register Deines PICs auf, nimm das Handbuch und führe jeden einzelnen Befehl auf dem Papier aus lt. Handbuch. Da lernst Du viel und findest auch so manches Problem.
Ich hab' das jetzt mal anhand von http://www.sprut.de/electronic/pic/a...e/befehle.html (schau da mal hin!) versucht:
Wie gesagt, bin kein PIC-Experte und mache auch viele Fehler (aber am ATmega12... Hoffentlich hilft's trotzdem etwas.Code:Main movfw PORTA ; Port A lesen und nach W kopieren >> W = PORTA movwf Input ; von W in Input (0x20) kopieren >> Input = W, brauchen wir aber nicht mehr >> jetzt soll W "gereinigt" werden, also alle Bits = 0 außer Bits 2 und 3 >> das geht einfach mit W = W & 0x0C, also bitweises AND mit 00001100 andlw 12 ; W = W & 0x0C, Zero-Flag in STATUS ggf. auf 1 wenn Ergebnis 0 >> folgender Code ergo unnötig clrw ; W löschen bcf Input,0 ; bcf Input,1 ; alle Bits von Input1 bis auf entscheidende Bits 2 und 3 werden bcf Input,4 ; auf 0 gesetzt bcf Input,5 ; bcf Input,6 ; bcf Input,7 ; movfw Input ; Input in Input_kor schreiben >> hier geht's weiter movwf Input_kor >> Input_kor = W >> jetzt haben wir also den Originalzustand von PORTA in Input und den sauberen Zustand in Input_kor und W clrw ; W löschen >> nicht nötig, wir brauchen Input_kor ja gleich wieder X_achse >> Du willst PORTB auf 00010000 (LED_X) wenn Input_kor = 00000000 (digit0) movfw Input_kor ; Input_kor wird in W geladen >> hier nicht nötig, aber für die anderen Achsen schon >> jetzt W mit digit0 vergleichen xorwf digit0,0 ; Input_kor und digit0 werden verglichen, Ergenbins in W >> wenn W gleich digit0, dann liefert XOR 0; das setzt das Zero-Flag in STATUS, und das kannst Du testen movwf Result ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht >> ab hier löschen clrw ; W löschen btfss Result,2 ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat btfsc Result,3 ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat goto Y_achse ; sprung zu Y_achse >> hier geht's weiter bnz Y_achse ; >> ungleich 0, war's also nicht (Branch on Non Zero) >> kapier ich nicht: Ergebnis ist 10000000 in PORT B; LED_X ist aber als 00010000 definiert >> sollte das nicht bsf PORTB,4 sein (Bits von rechts nach links numeriert, also 76543210 )? >> ein Fehler, der mir auch schon das Leben schwer gemacht hat, ist, dass mit 1 die Leitung auf +5V geht >> das klappt nur, wenn die LED richtig herum eingebaut ist, also Prozessor, Vorwiderstand, LED, Masse >> wenn LED zwischen Prozessor und +5V, dann muss der Port auf 0 bsf PORTB,7 ; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet >> dann solltest Du da noch eine Pause einbauen, und alle Leitungen z.B. in Main auf 0 setzen >> siehe http://www.sprut.de/electronic/pic/p...t/lauflich.htm goto Main
LG
Wolfgang
Hallo,
danke für die Tipps. In der Tat waren da ein paar Fehler in der PIN-Zuordnung bei den LEDs .
Hab den Code jetzt mal wie folgt umgestalltet. Wußte leider noch nichts mit flags anzufangen. Jetzt weis ich aber um was es etwa geht:
Habs jetzt auch versuch, mit dem Ergebnis, dass nach dem einschalten erst RB7 und kurz darauf RB5 auf high, logisch 1, gehen.Code:list p=16f84a ;************************************************************** ;* Pinbelegung ;* ---------------------------------- ;* PORTA: Eingänge ;* 0 - PIN 17 - Tastereingang ;* 1 - PIN 18 - n.c. ;* 2 - PIN 01 - Input #4 ;* 3 - PIN 02 - Input #5 ;* 4 - PIN 03 - n.c. ;* PORTB: ;* 0 - PIN 06 - Tastersignal ;* 1 - PIN 07 - n.c. ;* 2 - PIN 08 - n.c. ;* 3 - PIN 09 - n.c. ;* 4 - PIN 10 - LED x-Achse ;* 5 - PIN 11 - LED y-Achse ;* 6 - PIN 12 - LED z-Achse ;* 7 - PIN 13 - LED a-Achse ;* ;************************************************************** ; ;jorues 30.03.2007 ; ; Handradlogik ; ; Taktquelle: 4 MHz ; ;************************************************************** ; Includedatei für den 16F84A einbinden #include <P16f84a.INC> ; Configuration festlegen ; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator __CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC ;*************************************************************** ; Variablen festlegen Input Equ 0x20 Input_kor Equ 0x21 Result Equ 0x22 loops Equ 0x24 ; Zähler für Warteschleife loops2 Equ 0x25 ; Zähler für Warteschleife ; Constanten festlegen Ini_con Equ B'00000000' ; TMR0 -> Intetupt disable digit0 Equ B'00000000' ; Wert0 festlegen digit1 Equ B'00000100' ; Wert1 festlegen digit2 Equ B'00001000' ; Wert2 festlegen digit3 Equ B'00001100' ; Wert3 festlegen LED_X Equ B'10000000' ; LED für X-Achse LED_Y Equ B'01000000' ; LED für Y-Achse LED_Z Equ B'00100000' ; LED für Z-Achse LED_A Equ B'00010000' ; LED für A-Achse ;************************************************************* ;Reset vector ; This code will start executing when a reset occurs. ORG 0x0000 ;************************************************************** ; Das Programm beginnt mit der Initialisierung Init bsf STATUS, RP0 ; Bank 1 movlw B'11111111' ; PortA alle inputs movwf TRISA ; movlw B'00000000' ; PortB alle outputs movwf TRISB ; bcf STATUS, RP0 ; Bank 0 clrf PORTA clrf PORTB movlw Ini_con ; Interupt disable movwf INTCON clrw ;**************************************************************** Main movfw PORTA ; Port A lesen und nach W kopieren >> W = PORTA ; movwf Input ; von W in Input (0x20) kopieren >> Input = W ; andlw 12 ; W = W & 0x0C, Zero-Flag in STATUS ggf. auf 1 wenn Ergebnis 0 ; movwf Input_kor ; Input_kor = W ; jetzt haben wir also den Originalzustand von PORTA in Input und den sauberen ; Zustand in Input_kor und W ; clrw ; W löschen >> nicht nötig, wir brauchen Input_kor ja gleich wieder ; clrf PORTA ; Alle Leitungen auf 0 (LOW) clrf PORTB ; ;**************************************************************************************************************** ;PORTB auf 10000000 (LED_X) wenn Input_kor = 00000000 (digit0) X_achse call Wait ; Wartezeit movfw Input_kor ; Input_kor wird in W geladen ; xorwf digit0,0 ; Input_kor und digit0 werden verglichen, Ergenbins in W ; wenn W gleich digit0, dann liefert XOR 0; das setzt ; das Zero-Flag in STATUS, und das kannst Du testen ; movwf Result ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht ; bnz Y_achse ; >> ungleich 0, war's also nicht (Branch on Non Zero) bsf PORTB,7 ; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet ;**************************************************************************************************************** ;PORTB auf 01000000 (LED_Y) wenn Input_kor = 00000100 (digit1) Y_achse call Wait ; Wartezeit movfw Input_kor ; Input_kor wird in W geladen ; xorwf digit1,0 ; Input_kor und digit1 werden verglichen, Ergenbins in W ; wenn W gleich digit1, dann liefert XOR 0; das setzt ; das Zero-Flag in STATUS, und das kannst Du testen ; movwf Result ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht ; bnz Z_achse ; >> ungleich 0, war's also nicht (Branch on Non Zero) bsf PORTB,6 ; Bit 6 von PORTB wird auf high gesetzt, die LED für Y-Achse leuchtet ;**************************************************************************************************************** ;PORTB auf 00100000 (LED_Z) wenn Input_kor = 00001000 (digit2) Z_achse call Wait ; Wartezeit movfw Input_kor ; Input_kor wird in W geladen ; xorwf digit2,0 ; Input_kor und digit2 werden verglichen, Ergenbins in W ; wenn W gleich digit2, dann liefert XOR 0; das setzt ; das Zero-Flag in STATUS, und das kannst Du testen ; movwf Result ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht ; bnz A_achse ; >> ungleich 0, war's also nicht (Branch on Non Zero) bsf PORTB,5 ; Bit 5 von PORTB wird auf high gesetzt, die LED für Z-Achse leuchtet ;**************************************************************************************************************** ;PORTB auf 00010000 (LED_A) wenn Input_kor = 00001100 (digit3) A_achse call Wait ; Wartezeit movfw Input_kor ; Input_kor wird in W geladen ; xorwf digit3,0 ; Input_kor und digit3 werden verglichen, Ergenbins in W ; wenn W gleich digit3, dann liefert XOR 0; das setzt ; das Zero-Flag in STATUS, und das kannst Du testen ; movwf Result ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht ; bnz X_achse ; >> ungleich 0, war's also nicht (Branch on Non Zero) bsf PORTB,4 ; Bit 4 von PORTB wird auf high gesetzt, die LED für A-Achse leuchtet ;**************************************************************************************************************** goto Main ;**************************************************************************************************************** ; Warteschleife 250 ms Wait movlw D'250' ; 250 ms Pause movwf loops Wai movlw .110 ; Zeitkonstante für 1ms movwf loops2 Wai2 nop ; nop nop nop nop nop decfsz loops2, F ; 1 ms vorbei? goto Wai2 ; nein, noch nicht ; decfsz loops, F ; 250 ms vorbei? goto Wai ; nein, noch nicht retlw 0 ; das Warten hat ein Ende end
Ich bin mir immer noch nicht so sicher, ob mein Grundgerüst stimmt.
Vielleicht könnte da ein PIC experte mal schnell einen Blick darauf werfen???
Vielen Dank euch allen
LG Jo
Am Ende der Achsen-Routinen fehlt jetzt das "goto main", und die Warteschleife ist besser unmittelbar nach dem "bsf PORTx".
Ansonsten musst Du mal sehen, was wirklich an den Input-Ports anliegt.
LG
Wolfgang
Lesezeichen