Find ich nicht so dolle. Vor allem, wenn es Dir auf Geschwindigkeit ankommt.
Jeder Drehgeberausgang bekommt einen IRQ. Dann fragst Du ab, in welche Richtung sich dieser Porteingang geändert hat. Diesen Gesamtzustand (aus allen 4 Ports) speicherst Du anschließend ab und hast dann den Ausgangszustrand für den nächsten IRQ.
Jetzt kannst Du die Drehrichtung auswerten und die aktuelle Position absspeichern.
Alles andere außerhalb des IRQ.
Guckst Du hier (für Atmega in C). So habe ich es mal gemacht:
Das "TURN" kannst Du weglassen. Das ist für eine Mehrachsensteuerung.)Code:#define TURN_ENC_1 PD7 #define TURN_ENC_2 PD6 volatile uint8_t iTurnOldEncPort; volatile uint8_t iTurnNewEncPort; volatile int16_t lTurnActPosition; volatile int16_t lTurnTargetPosition; ISR(INT0_vect) { VerticalEncoderRead(); } void TurnEncoderRead(void) { iTurnNewEncPort = PIND; if ( iTurnOldEncPort & (1<<TURN_ENC_1) ) { if ( iTurnNewEncPort & (1<<TURN_ENC_1) ) { if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) { if (!( iTurnNewEncPort & (1<<TURN_ENC_2) )) lTurnActPosition++; } else { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition--; } } else { if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition--; else lErrorFlags |= ERR_TURN_ENC; } else { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lErrorFlags |= ERR_TURN_ENC; else lTurnActPosition++; } } } else { if ( iTurnNewEncPort & (1<<TURN_ENC_1) ) { if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition++; else lErrorFlags |= ERR_TURN_ENC; } else { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lErrorFlags |= ERR_TURN_ENC; else lTurnActPosition--; } } else { if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) { if (!( iTurnNewEncPort & (1<<TURN_ENC_2) )) lTurnActPosition--; } else { if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition++; } } } iTurnOldEncPort = iTurnNewEncPort; }
Gruß
pctoaster







Zitieren

Lesezeichen