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