ist doch schon mal was...
Du hast ja nur 3 zu unterscheidende Zustände:
Knüppel mitte -> alles aus
Knüppel unten -> ein Paar an
Knüppel oben -> beide Paare an
Sinnig erscheint also, wenn man die Signale erstmal irgendwie unterschieden hat, folgender Weg:
- beschreibe ein Rechenregister mit dem Zustand "alle aus"
- bei "Knüppel unten" entsprechendes Bitmuster laden
- sonst bei "Knüppel oben" entsprechendes Bitmuster laden
- Rechenregister ins Portregister ausgeben
Wie unterscheiden sich nun die 3 Signale?
Scheinbar so:
Code:
..._/--------\____... Mitte
| |
..._/-----\_______... unten
| |
..._/-----------\_... oben
| |
Dieses Signal wiederholt ständig, die steigenden Flanken liegen ca 20ms auseinander.
Du willst also die Zeit zwischen einer steigenden Flanke, und der dazugehörenden fallenden Flanke messen. Oder genauer:
Du willst wissen, wieviele Takte der Timer zwischen den Flanken gezählt hat.
Genau genommen interessiert Dich das aber auch nicht - Du willst ja nur zwischen den 3 diskreten Werten (mitte, Vollausschlag) unterscheiden. Das habe ich mit den senkrechten Strichen angedeutet.
Wo legen die?
Na in der Mitte zwischen Mittelstellung und dem jeweiligen Vollausschlag, also bei 1,25 und 1,75ms.
Liefert der Timer "weniger als 1,25ms", heißt das für Dich "voll unten",
liefert er "mehr als 1,75ms", heißt das "voll oben",
der Rest ist "Mitte"
klar?
Da Du Dich nicht mit der Berechnung der Differenz zwischen den Flanken rumschlagen willst, setzt Du den Timer bei einer steigenden Flanke einfach auf 0 zurück. Und beim Vergleich rechnest Du natürlich nicht mit ms, sondern vergleichst die entsprechenden Timer-Takt-Zahlen, klar?
Du willst jetzt also schnell auf Flanken des Signales (welches an einem sinnigen Pin anliegt) reagieren können, um den Timer zurückzusetzen/auszuwerten - was bietet sich da für Dich an?
Noch was generelles:
...
Timer würde ich an PORBT.2 als Input machen.
PORTB,1 -0-3-4 würde ich als Ausgang nutzen.
Code:
.include “ tn13Adef.inc“
ldi r16,0b11011
out DDRB,r16
...
Also mal abgesehen von der Wahl der Pins - da würde ich erst wenn der Algorithmus steht rangehen...
Mit der include-Direktive bindest Du die Prozessordefinitionsdatei des Tiny13A ein. Schau Dir die mal an. Dort werden diverse Konstanten des Prozessors für Dein Programm definiert, insbesondere Registeradressen (die Du danach zB mit DDRB statt 0x17 ansprechen kannst), aber eben auch die Bitnamen in den Registern.
Logischerweise verbirgt sich zB hinter dem niederwertigsten Bit des DDRB - also DDB0 (siehe Datenblatt) - dort die Konstante "0", definiert durch ".equ DDB0=0".
DDB1 ist 1, DDB3 ist 3, DDB4 ist 4...
damit kannst Du den imediate für Dein LDI (LoaD Imediate) auch festlegen, indem Du die einzelnen Bitwerte ver-OR-st. In Deinem Beispiel sähe das so aus:
Code:
...
LDI r16, (1<<DDB4)|(1<<DDB3)|(1<<DDB1)|(1<<DDB0)
OUT DDRB, r16
...
Die Klammern sind eigentlich unnötig, da das "schieben" ("<<") Vorrang vor den logischen Verknüpfungen ("|"=OR) hat, ich finde es so aber übersichtlicher...
Bei der Assemblierung macht der Assembler da die entsprechende Zahl draus, durch das Eins-Schieben steht quasi in den Klammern der jeweilige Bitwert (1<<DDB4 ist 'ne 1 die DDB4-oft, also viermal nach links geschoben wurde. Aus 0b00000001 wird also 0b00010000
1<<DDB3 entsprechend 0b00001000) - die bitweise ver-OR-ung erzeugt dann 0b00011011, stimmt also.
Der erzeugte Maschinencode ist absolut identisch, aber die Verwendung der Bitnamen ist besser lesbar.
Noch besser wäre es, wenn Du zusätzlich Deine eigenen Konstanten definierst. Da die einzelnen Bits eines jeden Beinchens in den betreffenden 3 Registern (PORT, DDR, PIN) meiner Meinung nach immer einen identischen Wert besitzen/zugewiesen bekommen (also DDxn=PORTxn=PINxn=Pxn), kannst Du einfach zB folgendes definieren:
Code:
.include...
;Ausgänge
.equ Ausg0=PB0
.equ Ausg1=PB1
.equ Ausg2=PB3
.equ Ausg3=PB4
, und das beim LDI dann verwenden:
Code:
LDI r16, (1<<Ausg3)|(1<<Ausg2)|(1<<Ausg1)|(1<<Ausg0)
Das erleichtert nochmal die Lesbarkeit des Codes, außerdem steht jetzt nur noch an einer einzigen Stelle (nämlich der Equation - ".equ"), welches Beinchen dem konkreten "Ausgang" entspricht. Wenn Du also konsequent Deine selbstdefinierten Konstanten im Code benutzt hast, und - sagen wir mal B2 als Ausgang3 verwenden willst, mußt Du nur diese eine Zeile auf ".equ Ausg3=PB2" ändern. (klar, PB2 darf dann natürlich nicht mehr Dein Eingang sein)