#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 H_ENCODER_PIN PINC #define H_ENCODER_PORT PORTC #define H_ENCODER_DDR DDRC #define H_ENCODER_A ( 1< 65535 ) rechteckgenerator_wert = 65535; if( rechteckgenerator_wert < 0 ) rechteckgenerator_wert = 0; OCR3A = 10000; //rechteckgenerator_wert; // An Rechteckgenerator Wert Uebergeben //Serial.println( ); //Serial.print ( "betrag = " ); //Serial.println( betrag ); Serial.print ( "OCR3A = " ); Serial.println( OCR3A ); Serial.println( ); } LEDS = rechteckgenerator_wert; } // 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 = H_ENCODER_PIN; neu = 0; if ( tmp & H_ENCODER_A ) neu = 3; if ( tmp & H_ENCODER_B ) neu ^= 1; // convert gray to binary diff = h_encoder_alt - neu; // difference last - new if( diff & 1 ) { // bit 0 = value (1) h_encoder_alt = neu; // store new as next last h_encoder_delta += (diff & 2) - 1; // bit 1 = direction (+/-) } } // Ende ISR( TIMER1_COMPA_vect ) //////////////////////////////////////////////////////////////////////////////// // Timer3 Mode 4 CTC mit OCR3A als TOP ohne Vorteilung initialisieren // void rechteckgenerator_init ( void ) { OCR3A = 10000; // OCR3A bestimmt die Frequenz Serial.print ( "OCR3A init = " ); Serial.println( OCR3A ); TCCR3A = 0b01<< COM3A0; // OC3A Toggeln TCCR3B = 0b01<< WGM12 | 0b001<< CS10; // Mode 4 & Vorteiler = 1 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 ) { // atomic access to enc_delta cli(); h_encoder_wert = h_encoder_delta; switch (klicks) { case 2: h_encoder_delta = h_encoder_wert & 1; h_encoder_wert >>= 1; break; case 4: h_encoder_delta = h_encoder_wert & 3; h_encoder_wert >>= 2; break; default: h_encoder_delta = 0; break; } sei(); return h_encoder_wert; // counts since last call } //////////////////////////////////////////////////////////////////////////////// // Hand-Encoder und Timer1 Output Compare A initialisieren // void h_encoder_init( void ) { int8_t neu, tmp; // init encoder tmp = H_ENCODER_PIN; neu = 0; if( tmp & H_ENCODER_A ) neu = 3; if( tmp & H_ENCODER_B ) neu ^= 1; // convert gray to binary h_encoder_alt = neu; // power on state h_encoder_delta = 0; // interne Pull Ups einschalten H_ENCODER_DDR &= ~(H_ENCODER_A | H_ENCODER_B); H_ENCODER_PORT |= (H_ENCODER_A | H_ENCODER_B); // Timer 1, CTC mode 4, prescaler 64 TCCR1A = 0; TCCR1B = (1<