Klaus schrieb:
> Bietet das eventuell die Möglichkeit beide Routinen in einem Progamm zu
> nutzen? Ich denke nicht, da ja beide Routinen unabhängig am TCNT0
> manipulieren.
Doch, das geht natürlich. Hier ist was für den Tiny26, wo beide Routinen
in der gemeinsamen (CTC) ISR kombiniert sind:
1 | // Definitions
|
2 | // Rotary Encoder properties
|
3 | #define ROTARY_PORT PORTB
|
4 | #define ROTARY_DIR DDRB
|
5 | #define ROTARY_PIN PINB
|
6 | #define WHEEL1 6
|
7 | #define WHEEL2 5
|
8 | #define BUTTON 0
|
9 |
|
10 | #define PHASE_A (ROTARY_PIN & 1<<WHEEL1)
|
11 | #define PHASE_B (ROTARY_PIN & 1<<WHEEL2)
|
12 | #define REPEAT_MASK (1 << BUTTON) // repeat: button
|
13 | #define KEY_MASK REPEAT_MASK
|
14 | #define REPEAT_START 150 // after 1500ms
|
15 | #define REPEAT_NEXT 100 // every 1000ms
|
16 |
|
17 | // for 1 ms
|
18 | #define OCR_SET (uint8_t)(F_CPU/256*1e-3)
|
19 |
|
20 |
|
21 | // encoder routines a la PeDa
|
22 | void encoder_init( void )
|
23 | {
|
24 | int8_t enc_new;
|
25 |
|
26 | enc_new = 0;
|
27 | if( PHASE_A )
|
28 | enc_new = 3;
|
29 | if( PHASE_B )
|
30 | enc_new ^= 1; // convert gray to binary
|
31 | enc_last = enc_new; // power on state
|
32 | enc_delta = 0;
|
33 | TCCR1A = 0;
|
34 | OCR1C = OCR_SET;
|
35 | TCCR1B = (1<<CTC1)|(1<<CS13)|(0<<CS12)|(0<<CS11)|(1<<CS10); // CTC, XTAL / 256
|
36 | TIMSK |= (1<<TOIE1);
|
37 | }
|
38 | ISR(TIMER1_OVF1_vect) {
|
39 | int8_t enc_new, diff;
|
40 | static uint8_t ct0, ct1, rpt,btimer;
|
41 | uint8_t i;
|
42 |
|
43 | // rotary handling
|
44 | enc_new = 0;
|
45 | if( PHASE_A )
|
46 | enc_new = 3;
|
47 | if( PHASE_B )
|
48 | enc_new ^= 1; // convert gray to binary
|
49 | diff = enc_last - enc_new; // difference last - new
|
50 | if( diff & 1 ){ // bit 0 = value (1)
|
51 | enc_last = enc_new; // store new as next last
|
52 | enc_delta += ((diff & 2) - 1); // bit 1 = direction (+/-)
|
53 | }
|
54 | btimer++;
|
55 | if (btimer > 9) {
|
56 | // button handling
|
57 | i = key_state ^ ~ROTARY_PIN;
|
58 | ct0 = ~(ct0 & i);
|
59 | ct1 = ct0 ^ (ct1 & i);
|
60 | i &= ct0 & ct1;
|
61 | key_state ^= i;
|
62 | key_press |= key_state & i;
|
63 | if( (key_state & REPEAT_MASK) == 0 ) // check repeat function
|
64 | rpt = REPEAT_START; // start delay
|
65 | if( --rpt == 0 ){
|
66 | rpt = REPEAT_NEXT; // repeat delay
|
67 | key_rpt |= key_state & REPEAT_MASK;
|
68 | }
|
69 | btimer = 0;
|
70 | }
|
71 | }
|
Wunder dich nicht, im Tiny26 bewirkt ein CTC Ereignis, das die Timer1
Overflow ISR angesprungen wird. Port Initialisierung ist hier
weggelassen. Abfrage von Encoder und Knöpfen wie gehabt.