Warum denn PINC ?Code:else //rising edge { if bit_is_clear(PINC,4) //rechtsrum
sorry, bin mit dem compiler nicht vertraut, aber ich nehme an, dass der Buchstaben den Port bezeichnet ?
gruss
Hi,
ich habe hier einen drehencoder den ich mit einem mega16 auswerte, Ausgang A ist an INT1 und Ausgang B an PIND.4 wen ich ihn mit diesem code auswerte funktioniert das ganze nur wen ich schnell am encoder drehe. Bei langsamem drehen egal in welche richtung geht der wert immer in den minus bereich.
Hier mein code:
Der interrupt ist auf steigende und fallende flanken eingestellt.Code:ISR(INT1_vect) { char cSREG; cSREG = SREG; // Statusregister puffern in Variable cSREG // if bit_is_clear(PIND,PIND3) //falling edge! { if bit_is_clear(PIND,4) //linksrum { enc--; } else { enc++; } } else //rising edge { if bit_is_clear(PINC,4) //rechtsrum { enc++; } else { enc--; } } SREG = cSREG; // Statusregister aus Variable cSREG retten // }
Danke schonmal im vorraus.Code:GICR |= (1<<INT1); MCUCR |= (1<<ISC10);
MfG Martin
Warum denn PINC ?Code:else //rising edge { if bit_is_clear(PINC,4) //rechtsrum
sorry, bin mit dem compiler nicht vertraut, aber ich nehme an, dass der Buchstaben den Port bezeichnet ?
gruss
upps da ist wohl ein fehler bei copieren pasiert es muss heisen PIND.
Funktioniert trotzdem nicht!
Ja, der buchstabe bezeichnet den port.
Hat noch jemand ne idee?
MfG Martin
und oben ?
bit_is_clear(PIND,PIND3)
muss dass dann nicht heissen
bit_is_clear(PIND,3) ?
Kannst du den Interrupt auch on change machen, oder nur auf steigende oder fallende flanke ?
Da reichts nämlich dann, die Zustände zu vergleichen.
Beide Pins gleich: Rechtsrum, else Linksrum... Oder andersrum, je nachdem, wie dus angeschlossen hast.
das ist egal PIND3 ist als 3 definiert macht keinen unterschied was man da schreibt.
kann mit keiner helfen?
hast du das was ich noch geschrieben habe mal Probiert ? Also einfach nur vergleichen ?
hast du das was ich noch geschrieben habe mal Probiert ? Also einfach nur vergleichen ?
So ungetestet auf den ersten Blick sollte dein Programm das schon richtig auswerten... vor allem wenns geschwindigkeitsabhängig ist. Stimmt das Signal des Encoders, oder ist vielleicht eine Lichtschranke verschoben (weiss ja nicht, was für einen du hast)
Hallo
ich hab mir jetzt das Datenblatt vom Mega16 nicht angeschaut, aber ich nehme mal an Int0 ist PD3?
Dann zuerst mal was soll dieser Teil:
du änderst das Statusregister doch gar nicht? warum also diese Zwischenspeicherung. Außerdem kann (normalerweise?) eine ISR doch eh nicht von einem anderen Interrupt unterbrochen werden (oder hab ich da was falsch verstanden?).Code:char cSREG; cSREG = SREG; // Statusregister puffern in Variable cSREG // SREG = cSREG; // Statusregister aus Variable cSREG retten //
Dann zu deinem eigentlichen Problem. Du benutzt ja eine Variable, die du hoch bzw. runter zählst.
Ich würde es so machen (bzw. habe es so gemacht). Eine Variable, die die Impulse zählt und eine zweite, die die Richtung dazu angibt. (ich habe das ganze für eine Motorenregelung benutzt, wobei der Regler mit 100Hz aufgerufen wurde, sodass die kleine Ungenauigkeit (wenn der Motor von einer Laufrichtung zur nächsten Wechselt) nicht so schlimm ist).
Machs doch einfach so: Setzt den Interrupt Port auf steigene Flanke. Dann zählst du bei jedem Interrupt die Zählvariable hoch und überprüfst ob der zweite Port high oder low ist. Jenachdem setzt du dann deine Richtungsvariable auf 1 oder 0 (oder wie auch immer). Alternativ um die Genauigkeit zu steigern (von der Impulsanzahl) kannst du natürlich auch den Interrupt bei steigender und fallender Flanke auslösen, beide Impulse zählen. (du könntest sogar noch den 2. Port als Interruptport nehmen und von diesem auch noch die Impulse zählen. dadurch hast du dann insgesamt viermal so viele Impulse pro Motordrehung.)
Hi,
es funtioniert jetzt, hab den interrupt auf steigende flanke gesetzt und ein kleines delay eingefügt.
Lesezeichen