Ich möchte gerne diese beiden beispiele:http://www.rn-wissen.de/index.php/Taster-Abfrage_in_C und http://www.mikrocontroller.net/articles/Drehgeber miteinander verbinden.
Die einzelnen Programmbeispiele funktionieren soweit problemlos.
Nur in der kombination funktioniert die Tastenabfrage nicht. Weder kurznoch lang.
Jetzt denke ich das sich ISR und SIGNAL miteinander nicht gut verträgt.
Zumindest dürfte es ein Problem mit der Interruptabfrage geben.
Kann mir dazu jemand einen Tip geben wie ich das am besten kombiniere?
Abgesehen davon habe ich gelesen das SIGNAL eine veraltete methode ist.
Code:/************************************************************************/ /* */ /* Commodore 1541-II */ /* Toolbox */ /* */ /************************************************************************/ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/eeprom.h> #include "taster.h"// CPU: ATmega8 //------------------------------------------------------------------------#define XTAL 8e6 // 8MHz #define ENCODER PORTC // Encoder PORT #define PHASE_A (PINC & 1<<PC0) #define PHASE_B (PINC & 1<<PC1) #define ENC_TASTER (PINC & 1<<PC2)#define LEDS_DDR DDRB #define LEDS PORTB // 7-Segment gegen GNDvolatile int8_t enc_delta; // Encoder WERT static int8_t last;void encode_init(void) { int8_t new; new = 0; if(PHASE_A) new = 3; if(PHASE_B) new ^= 1; // Konvertiert gray nach binär last = new; // Einschaltstatus enc_delta = 0; TCCR2 = 1<<WGM21^1<<CS22; // CTC2, Prescaler 64 OCR2 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms TIMSK |= 1<<OCIE2; }SIGNAL(TIMER0_OVF_vect) { static unsigned char count_ovl0; unsigned char ovl0 = count_ovl0+1; if (ovl0 >= 39) { get_taster (0, PINC & (1<<PC2)); ovl0 = 0; } count_ovl0 = ovl0; }ISR(TIMER2_COMP_vect) // 1ms für manuelles drehen { int8_t new, diff; new = 0; if(PHASE_A) new = 3; if(PHASE_B) new ^= 1; // Konvertiert gray nach binär diff = last - new; // Unterschied LAST - NEW if(diff & 1) { // BIT0 = Wert(1) last = new; // Speichere NEW als nächstes LAST enc_delta += (diff & 2) - 1; // BIT1 = Richtung (+/-) } }int8_t encode_read(void) // Encoderwert auslesen { int8_t val; cli(); // Interrupts deaktivieren val = enc_delta; enc_delta = val & 1; sei(); // Interrupts aktivieren return val >> 1; }void ioinit() { LEDS_DDR = 0xFF; // PORT B = Ausgang ENCODER |= (1<<PC0) | (1<<PC1) | (1<<PC2); // PORT C = PullUp TCCR0 = 1 << CS00; TIMSK |= (1 << TOIE0); // Timer-Interrupt aktivieren }int main(void) { int32_t val = 0; ioinit(); encode_init(); /* Taster konfigurieren (#define NUM_TASTER 0 in taster.h) tasten[0].mode = TM_SHORT; -> Kurzer Tastendruck tasten[0].mode = TM_LONG; -> Langer tastendruck tasten[0].mode = TM_REPEAT; -> Tastenwiederholung */ tasten[0].mode = TM_LONG; sei(); // Interrupts aktivieren for(;;) { signed char tast = taster; val += encode_read(); switch(val) { case 1: // 2 (01011011) LEDS = 0x5B; break; case 2: // 3 (01001111) LEDS = 0x4F; break; case 3: // 4 (01100110) LEDS = 0x66; break; case 4: // 5 (01101101) LEDS = 0x6D; break; case 5: // 6 (01111101) LEDS = 0x7D; break; case 6: // 7 (00000111) LEDS = 0x07; break; case 7: // 8 (01111111) LEDS = 0x7F; break; case 8: // 9 (01101111) LEDS = 0x6F; break; default: switch(tast) { default: case NO_TASTER: // 1 (00000110) LEDS = 0x06; break; case 0: PORTB = 0x4F; break; case 0+TASTER_LONG: PORTB = 0x66; break; } break; } if (tast != NO_TASTER) taster = NO_TASTER; } }
Lesezeichen