Hallo zusammen, Bin neu hier und hab auch schon gleich ma ne Frage. Ich hatte vor mir den oben genannten PIC für die Steuerung eines Schritmotors zu programmieren und zwar ist auf der rotierenden Achse des Motors ein runds Blatt befestigt mit einem loch andem die Lichtschranke beim vorbeikommen ein High Pegel zeigt. Unter den rotierenden Blatt ist ein befestigtes Blatt mit Zaheln von 0-9 in gleichmäsigem abstand 360° verteilt. wenn der pic startet soll er sich unabhängig von seiner Position erst einmal orientieren (mit Interrupt gelöst) was auch funktioniert (er orientiert sich an Position 0 also die Lichtschranke). Nun soll der Motor wenn man Hexadezimal eine Zahl an den Ports eingibt und diese durch drücken des übername Taster dann auch eingelesen wird (High beim betätigen) (vorher Binär gewandelt funktioniert auch einbandfrei) auch auf diese Zahl zeigen (Es Wird Hex nur 0-9 benutz(Logisch)). Dort liegt der Haken wenn ich die zweite Programm hälfte also das nachdem Interrupt in dem Pic auch noch einfüge Kallibriert er sich zwar mit Linksdrehung aber schwenkt dann nach rechts um und dreht sich nurnoch wie verrückt. Ich wies das es sich nach viel anhört hoffe allerdings dennoch das ihr mir helfen könnt da ich das fertige Programm dringent morgen brauche! hier noch die benutzten Ports: B Für das Bitmuster des Motors: RA0= 2^0 RA1= 2^1 RA2= 2^2 RA3= 2^3 Übernahme Taster der beim drücken High Pegel gibt: RA4 Lischtschrancke (Position0) RB0 Standorteingabe also die hexadezimale eingabe: RB1=2^0 RB2=2^1 RB3=2^2 RB4=2^3 Und hier noch mein Programm was nicht funktioniert: list p=16f84 include <P16F84.inc> ZAHL05 equ 0x0C ZAHL5 equ 0x0D KONST equ 0x0E KONSTISR equ 0x0F W_TEMP equ 0x10 STATUS_TEMP equ 0x11 TEMP_EIN equ 0x12 TEMP_AUS equ 0x13 TEMP equ 0x14 ZAHL equ 0x15 org 0x0000 goto INIT org 0x0004 PUSH movwf W_TEMP swapf STATUS,0 movwf STATUS_TEMP ISR movlw 0x01 movwf KONSTISR POP swapf STATUS_TEMP,0 movwf STATUS swapf W_TEMP,1 swapf W_TEMP,0 bcf INTCON,INTF retfie INIT bsf STATUS,RP0 movlw 0x10 movwf TRISA movlw 0xFF movwf TRISB bsf OPTION_REG,INTEDG bcf STATUS,RP0 bsf INTCON,INTE bsf INTCON,GIE HP movlw 0x02 movwf KONSTISR movlw 0x04 movwf KONST WIEDL movf KONST,0 call TABLI movwf PORTA call ZEIT5 decfsz KONST,1 goto WIEDL decfsz KONSTISR,1 goto HP bcf INTCON,GIE clrf TEMP_AUS WIED0 btfss PORTB,0 goto WIED0 movf PORTB,0 andlw 0x1E movwf TEMP_EIN rrf TEMP_EIN,1 movlw 0x05 subwf TEMP_EIN,0 movwf TEMP movf TEMP_EIN,0 movwf TEMP_AUS btfss STATUS,C goto POS1 goto POS2 POS1 call LINKS goto WIED POS2 call RECHTS WIED btfss PORTA,4 goto WIED movf PORTB,0 andlw 0x1E movwf TEMP_EIN rrf TEMP_EIN,1 movf TEMP_AUS,0 subwf TEMP_EIN,0 movwf TEMP movf TEMP_EIN,0 movwf TEMP_AUS btfss STATUS,C goto POS9 goto POS10 POS9 call LINKS goto WIED POS10 call RECHTS goto WIED ZEIT05 movlw 0x7D movwf ZAHL05 WIED1 nop decfsz ZAHL05,1 goto WIED1 return ZEIT5 movlw 0x0A movwf ZAHL5 nop WIED2 call ZEIT05 decfsz ZAHL5,1 goto WIED2 return TABRE addwf PCL,1 nop retlw 0x06 retlw 0x05 retlw 0x09 retlw 0x0A TABLI addwf PCL,1 nop retlw 0x09 retlw 0x05 retlw 0x06 retlw 0x0A LINKS POS5 movlw 0x14 movwf ZAHL POS3 movlw 0x04 movwf KONST POS4 movf KONST,0 call TABLI movwf PORTA call ZEIT5 decfsz KONST,1 goto POS4 decfsz ZAHL,1 goto POS3 decfsz TEMP,1 goto POS5 return RECHTS POS6 movlw 0x14 movwf ZAHL POS7 movlw 0x04 movwf KONST POS8 movf KONST,0 call TABRE movwf PORTA call ZEIT5 decfsz KONST,1 goto POS8 decfsz ZAHL,1 goto POS7 decfsz TEMP,1 goto POS6 return Ende end Ach und Arbeiten tue ich mit MPLAB. Hoffe ihr könnt mir bald helfen das Program zum laufen zu bekommen! Danke im Vorraus!!!
Ich hab mir nicht alles angeguckt, aber: org 0x0004 PUSH <- die Instruktion kenne ich nicht, der 18f84 auch nicht, und als Label wird das auch nicht verwendet, es sieht so aus als ob du das aus einem anderen Programm übernommen hast ohne es zu verstehen movwf W_TEMP swapf STATUS,0 movwf STATUS_TEMP ISR<- die Instruktion kenne ich nicht, der 18f84 auch nicht, und als Label wird das auch nicht verwendet, es sieht so aus als ob du das aus einem anderen Programm übernommen hast ohne es zu verstehen movlw 0x01 movwf KONSTISR POP<- die Instruktion kenne ich nicht, der 18f84 auch nicht, und als Label wird das auch nicht verwendet, es sieht so aus als ob du das aus einem anderen Programm übernommen hast ohne es zu verstehen swapf STATUS_TEMP,0 movwf STATUS swapf W_TEMP,1 swapf W_TEMP,0 bcf INTCON,INTF retfie Nehmen wir also an, diese Interrupt-Routine setzt erfolgreich KONSTISR auf 1 wenn ein Interrupt ausgelöst wurde INIT bsf STATUS,RP0 movlw 0x10 movwf TRISA movlw 0xFF movwf TRISB bsf OPTION_REG,INTEDG bcf STATUS,RP0 bsf INTCON,INTE <- RB= liefert Interrupt bsf INTCON,GIE <- Interrupts erlaubt HP movlw 0x02 <- 2 mal movwf KONSTISR movlw 0x04 <- je 4 Schritte movwf KONST WIEDL movf KONST,0 call TABLI movwf PORTA call ZEIT5 decfsz KONST,1 goto WIEDL decfsz KONSTISR,1 goto HP bcf INTCON,GIE <- Interrupts verboten Wie kommst du dadrauf, daß in dieser kurzen Zeit von nur 2 Vollschritten dein Zeiger so weit gelaufen ist, daß der Interrupt ausgelöst wurde ? Es gibt keinen Rücksprung nach INIT, HP oder WIEDL. clrf TEMP_AUS WIED0 btfss PORTB,0 <- wann soll sich der ändern, wenn nicht passiert ? goto WIED0 Du kannst nicht PB0 sowohl an die Lichtschranke für den Zeiger als auch an den Taster für das Einlesen der Sollposition gekoppelt haben, also ist der Taster woanders, also wird man ewig auf PB0=1 warten, hier sollte wohl RA4 getestet werden. movf PORTB,0 andlw 0x1E movwf TEMP_EIN rrf TEMP_EIN,1 movlw 0x05 <- keine Ahnung warum du nun 5 abziehst subwf TEMP_EIN,0 movwf TEMP movf TEMP_EIN,0 ; ab hier weiß der Geier was du treibst movwf TEMP_AUS btfss STATUS,C goto POS1 goto POS2 POS1 call LINKS ; warum links goto WIED POS2 call RECHTS ; warum rechts, ich dachte du drehst nun links bis di dort bist WIED btfss PORTA,4 goto WIED movf PORTB,0 andlw 0x1E movwf TEMP_EIN rrf TEMP_EIN,1 movf TEMP_AUS,0 subwf TEMP_EIN,0 movwf TEMP movf TEMP_EIN,0 movwf TEMP_AUS btfss STATUS,C goto POS9 goto POS10 POS9 call LINKS goto WIED POS10 call RECHTS goto WIED ZEIT05 movlw 0x7D movwf ZAHL05 WIED1 nop decfsz ZAHL05,1 goto WIED1 return ZEIT5 movlw 0x0A movwf ZAHL5 nop WIED2 call ZEIT05 decfsz ZAHL5,1 goto WIED2 return TABRE addwf PCL,1 nop retlw 0x06 retlw 0x05 retlw 0x09 retlw 0x0A TABLI addwf PCL,1 nop retlw 0x09 retlw 0x05 retlw 0x06 retlw 0x0A LINKS POS5 movlw 0x14 movwf ZAHL POS3 movlw 0x04 movwf KONST POS4 movf KONST,0 call TABLI movwf PORTA call ZEIT5 decfsz KONST,1 goto POS4 decfsz ZAHL,1 goto POS3 decfsz TEMP,1 goto POS5 return RECHTS POS6 movlw 0x14 movwf ZAHL POS7 movlw 0x04 movwf KONST POS8 movf KONST,0 call TABRE movwf PORTA call ZEIT5 decfsz KONST,1 goto POS8 decfsz ZAHL,1 goto POS7 decfsz TEMP,1 goto POS6 return Vergiss die Interrupts, vergiss das Linksdrehen, prüfe nur PB0 (Lichtschranke) als Nullposition und drehe rechts: HP: movlw 0x04 <- je 4 Teilschritte pro Vollschritt movwf KONST Label1: ; drehe rechts bis PB0 = 0 call onesteptotheright btfsz PORTB,0 goto Label1 Label2: ; drehe rechts bis PB0 = 1 call onesteptotheright btfss PORTB,0 goto Label1 WIED0 btfss PORTA,4 <- warte auf Tastendruck goto WIED0 movf PORTB,0 andlw 0x1E movwf TEMP_EIN rrf TEMP_EIN,1 ; nun wissen wir auf welche Ziffer positioniert werden soll ; ich weiß aber nicht ob deine Skala mit Ziffer 1 oder ; Ziffer 0 beginnt angenommen die erste Position ist 1 Label3: movlw x <-- x steht für Anzahl Viertelschritte pro Ziffer, z.B. 40 movwf KONSTISR Label4: call onesteptotheright decfsz KONSTISR goto Label4 decfsz TEMP_EIN goto Label3 stop: goto stop onesteptotheright: movf KONST,0 ; aktuellen Viertelschritt an Schrittmotor call TABRE movwf PORTA call ZEIT5 decfsz KONST,1 return movlw 0x04 ; nächster Schritt wieder 4 movwf KONST return das sollte reichen, zusammen mit deinen Subroutinnen TABRE und ZEIT5
Mein Ziffernblatt fängt mit 0 an dort ist auch die Lichtschrancke. Mir fällt auch grad auf das ich dir eine Information verschwiegen habe und zwar soll der Motor von Zahl zur Zahl nicht einfach von z.b. 3 nach 8 in eine richtung drehen sonder er soll von Zahl zu Zahl immer den kürzesten weg nehemen. Deswegen ziehe ich die hälfte also 5 ab und überprüfe die c flag ist sie gesetzt dann eine linksdrehung zur nächsten Zahl wenn nicht dann eine Rechtsdrehung zur nächsten Zahl. Echt doof von mir das ich das vergessen hab reinzuschreiben XD SORRY!
Ansich war das Ziel ja ein Programm zu bauen wobei der Motor sich beim einschalten auf 0 (Lichtschranke) kaliebriert und dann bei eingabe einer position diese anfährt und bei der eingabe einer neuen Position die neue auff dem kürzesten weg von der alten aus anfährt. die Positions eingabe sollte mit drücken des Tasters übernommen werden.
Dann brauchst du bloss stop: goto stop gegen WIED1 btfsc PORTA,4 <- warte auf Taste losgelassen goto WIED1 goto Label1 und natürlich das zweite goto Label1 gegen goto Label2 korrigieren. Nur dreht er eben immer rechtsrum. Klappt das, kannst du ja auf kürzesten Weg umbauen.
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.