#include /************************************************************************/ /* */ /* Reading rotary encoder */ /* one, two and four step encoders supported */ /* */ /* Author: Peter Dannegger */ /* target: ATmega16 */ /************************************************************************/ #include #include //#define XTAL 8e6 // 8MHz #define F_TIMER1 100 // Timer 1 frequency /Hz #define ENCODER_PIN PINC #define PHASE_A (1< 65535 ) val = 65535; if( val < 0 ) val = 0; Serial.print ( "val = " ); Serial.println( val, DEC ); Serial.print ( "OCR3A = " ); Serial.println( OCR3A, DEC ); //Serial.println( ); } LEDS = val; } // Ende void loop() //////////////////////////////////////////////////////////////////////////////// // Interrupt Service Routine Timer1 Output Compare Match A // Hand-encoder auswerten ISR( TIMER1_COMPA_vect ) { // 1ms for manual movement int8_t neu, diff, tmp; tmp = ENCODER_PIN; neu = 0; if ( tmp & PHASE_A ) neu = 3; if ( tmp & PHASE_B ) neu ^= 1; // convert gray to binary diff = last - neu; // difference last - new if( diff & 1 ) { // bit 0 = value (1) last = neu; // store new as next last enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-) } } //////////////////////////////////////////////////////////////////////////////// // Timer3 Mode 4 CTC mit OCR3A als TOP ohne Vorteilung initialisieren // void rechteckgenerator_init ( void ) { OCR3A = val; // OCR3A bestimmt die Frequenz TCCR3A = 0b01<< COM3A0; // OC3A Toggeln TCCR3B = 0b01<< WGM12 | 0b001<< CS10; // Mode 4 & Vorteiler = 1j DDRE |= 1<<3; // OC3A-Pin als Ausgang konfigurieren } //////////////////////////////////////////////////////////////////////////////// // Zaehler an Hand-Encoder-Typ anpassen // read 1, 2, or 4 step encoders int8_t encode_read( uint8_t klicks ) { int8_t val; // atomic access to enc_delta cli(); val = enc_delta; switch (klicks) { case 2: enc_delta = val & 1; val >>= 1; break; case 4: enc_delta = val & 3; val >>= 2; break; default: enc_delta = 0; break; } sei(); return val; // counts since last call } //////////////////////////////////////////////////////////////////////////////// // Hand-Encoder und Timer1 Output Compare A initialisieren // void encode_init( void ) { int8_t neu, tmp; // init encoder tmp = ENCODER_PIN; neu = 0; if( tmp & PHASE_A ) neu = 3; if( tmp & PHASE_B ) neu ^= 1; // convert gray to binary last = neu; // power on state enc_delta = 0; tmp |= PHASE_A | PHASE_B; // activate internal pull up resistors // put your setup code here, to run once: // Timer 1, CTC mode 4, prescaler 64 TCCR1A = 0; TCCR1B = (1<