Hallo, ich würde gern mit einem PIC 16F877A einen Motor ein bzw ausfahren. Dazu lese ich eine beim Motor angebrachte Lichtschranke über den AD Wandler ein. Einen zweiten Wert gebe ich über einen Poti vor, dieser ist der Soll Wert für den Motor. Das heißt also ich gebe eine Spannung am Poti vor und wandle diese ebenfalls am ADC. Dann Vergleiche ich den Wert mit dem eingelesenen Wert von der Lichtschranke und vergleiche auf > oder < in dem ich beide Werte voneinander abziehe, und das Carry Flag auswerte. So weiß ich ob der Motor rechts oder links loslaufen soll. Weiter vergleiche ich dann ständig den Wert der Lichtschranke mit dem nur einmal eingelesene Wert des Poti-sobald ein Vorzeichenwechsel stattfindet, stoppe ich den Motor. dann geht alles wieder von vorne los- neuer Sollwert wird eingelesen und wieder geschaut wo der Motor hinlaufen soll. Jetzt habe ich das Problem das mein Motor natürlich ständig um den Sollwert herum vor und zurück läuft- ich würde also gerne sagen das der Motor stehen bleiben soll sobald er sich in einem bestimmten Bereich befindet. Wie könnte ich das machen??? Dachte irgendwie an eingegebene Tabellenwerte die ich dann irgendwie auswerte?? Kenn mich aber dafür zu wenig aus-bin für jede Anregung dankbar!!!
Du brauchst eine =>Hysterese. Erst wenn die Differenz Soll-Ist vom Betrage her größer als X ist, wird entsprechend verfahren.
Danke für die schnellen Antworten. Genau so etwas brauche ich, dass ist mir vom Prinzip her klar, nur wie kann ich sowas in Assembler umsetzen??
Du musst dir einen Bereich schaffen, indem dein Motor stehen bleibt. Also angenommen dein Poti hat den Wert 500. Dann subtrahierst du einmal 10 von diesem Wert, das ist dein unterer Vergleichswert. Nun addierst du in einem zweiten Schritt 10 hinzu, dass ist dein oberer Vergleichswert. Damit würde der Motor zwischen 490 und 510 stehen bleiben. Ist ein wenig mehr Schreiberei in Assembler aber grundsätzlich nicht allzu schwierig. Falls 8 Bit genau genug sind, dann benutze nur die höheren 8 Bit von dem ADC. Das spart dir die Rechnerei mit den 16-Bit Zahlen. Sven
1 | .equ max=123 |
2 | .equ min=89 |
3 | |
4 | .dseg |
5 | st_ausgang: .byte 1 |
6 | |
7 | .cseg |
8 | ; messwert in r16 |
9 | asm_st: |
10 | cpi r16, max |
11 | brlo asm_st_no_max |
12 | ldi r17,1 ; obere Schwelle überschritten -> 1 |
13 | sts st_ausgang,r17 |
14 | ret |
15 | asm_st_no_max: |
16 | cpi r16, min |
17 | brsh asm_st_no_min |
18 | ldi r17,0 ; untere Schwelle unterschritten -> 0 |
19 | sts st_ausgang,r17 |
20 | ret |
21 | asm_st_no_min: |
22 | ret ; zwischen den Schwellen, keine Änderung |
In PIC-ASM sehr ähnlich, kann ich aber nicht. MFG Falk
@falk Danke für den Code, leider kenn ich mich damit nicht aus!! @stepp64 8 bit würden locker reichen-obwohl ich zur zeit noch mit 16 bit rechne. Das Problem was ich habe liegt immer noch in den Vergleichsprozessen. Ich addiere bzw subtrahiere von meinem Poti_Wert jeweils z.B 10 und lege diese Werte in zwei Speicherzellen ab. Aber wie kann ich dann am schnellsten meinen Lichtschrankenwert damit vergleichen-ob erim Bereich liegt oder drunter bzw darüber. Ich steh da wohl irgendwie auf der Leitung.
Also angenommen du hast den minimalen Wert in min gespeichert und den maximalen Wert in max. Dein Vergleichswert steht in pot. Nun sagen wir mal: min ist 120, max ist 140 und pot ist 130. Nun musst du zwei Vergleiche machen. Vergleichen ob etwas größer oder kleiner ist kannst du nur über den Subtraktionsbefehl. Du lädst also pot nach w und subtrahierst min von w ab. Carry ist dann 0 wenn w größer war und 1 wenn es gleich oder kleiner war. Schau dir mal das Instruction set des 16F887 (nicht 877) an. Dort ist es besser beschrieben. Bsp.
1 | movfw pot |
2 | subwf min,w ;das w hinter dem Komma ist wichtig, damit der Wert in |
3 | ;min nicht überschrieben wird |
4 | btfss STATUS,C |
5 | goto größer |
6 | |
7 | kleiner |
8 | ..... |
9 | |
10 | größer |
11 | ..... |
Probier es im Simulator aus, da kannst du schön erkennen ob es funktioniert
Danke für den Tipp. Ich werds morgen mal ausprobieren-hab mir schon gedacht das ich es so machen muss, ist halt so bei RISC!!! Sehe nur noch das Problem wenn mein Poti z.B. auf 9 ist und ich 10 abziehe für meinen unteren Grenzwert dann hab ich ja FF und Carry gesetzt-aber irgendwie muss das ja auch noch zu lösen sein!!
Na sicher ist das zu lösen. Nach Subtraktionen und Additionen sollte man immer das Carryflag überprüfen und entsprechend reagieren. Kommt in deinem Fall ein Überlauf zustande, dann setzt du den Wert pot halt einfach auf 0. Gilt ja in diesem Beispiel für alle Werte zwischen 0 und 9.
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.