Hi, erneut habe ich ein paar Frage. Denkt nicht das ich zu faul bin und alles machen lassen möchte ;), aber nach mehreren Stunden bin ich leider immer noch zu keinem vernüftigen Lösungsansatz gekommen. Ich habe hier das solide Programm von dieser Seite um einen Drehgeber auszuwerten. Ich nutze zwar einen Atmega 32 aber sobald ich die Eingänge änder sollte dies ja kein Problem darstellen. Allerdings verstehe ich nicht was hier genau mit single step encoders und two step encoders usw. gemeint ist. Zudem steht unten im Hauptprogramm: " LEDS = val " - was passiert hier, kann man den Ports einen Wert außer 1 und 0 übergeben? Ich würde zum Test simpel eine LED zum leuchten bringen, ab 5000 Impulsen quasi, habe aber leider keine Idee wie ich das lösen könnte. Mein erster Ansatz war eine IF Anweisung in den main Teil zu bringen. IF(val>=5000) schalte PORTA eine LED. Funkzt aber nicht. Kann mir da wer Weiter helfen? Hier das Programm von dem ich ausgehen möchte
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | // target: ATmega16
|
5 | //------------------------------------------------------------------------
|
6 | |
7 | #define XTAL 8e6 // 8MHz
|
8 | |
9 | #define PHASE_A (PINA & 1<<PA1)
|
10 | #define PHASE_B (PINA & 1<<PA3)
|
11 | |
12 | #define LEDS_DDR DDRC
|
13 | #define LEDS PORTC // LEDs against VCC
|
14 | |
15 | |
16 | volatile int8_t enc_delta; // -128 ... 127 |
17 | static int8_t last; |
18 | |
19 | |
20 | void encode_init( void ) |
21 | {
|
22 | int8_t new; |
23 | |
24 | new = 0; |
25 | if( PHASE_A ) |
26 | new = 3; |
27 | if( PHASE_B ) |
28 | new ^= 1; // convert gray to binary |
29 | last = new; // power on state |
30 | enc_delta = 0; |
31 | TCCR0 = 1<<WGM01^1<<CS01^1<<CS00; // CTC, XTAL / 64 |
32 | OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms |
33 | TIMSK |= 1<<OCIE0; |
34 | }
|
35 | |
36 | |
37 | ISR( TIMER0_COMP_vect ) // 1ms for manual movement |
38 | {
|
39 | int8_t new, diff; |
40 | |
41 | new = 0; |
42 | if( PHASE_A ) |
43 | new = 3; |
44 | if( PHASE_B ) |
45 | new ^= 1; // convert gray to binary |
46 | diff = last - new; // difference last - new |
47 | if( diff & 1 ){ // bit 0 = value (1) |
48 | last = new; // store new as next last |
49 | enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-) |
50 | }
|
51 | }
|
52 | |
53 | |
54 | int8_t encode_read1( void ) // read single step encoders |
55 | {
|
56 | int8_t val; |
57 | |
58 | cli(); |
59 | val = enc_delta; |
60 | enc_delta = 0; |
61 | sei(); |
62 | return val; // counts since last call |
63 | }
|
64 | |
65 | |
66 | int8_t encode_read2( void ) // read two step encoders |
67 | {
|
68 | int8_t val; |
69 | |
70 | cli(); |
71 | val = enc_delta; |
72 | enc_delta = val & 1; |
73 | sei(); |
74 | return val >> 1; |
75 | }
|
76 | |
77 | |
78 | int8_t encode_read4( void ) // read four step encoders |
79 | {
|
80 | int8_t val; |
81 | |
82 | cli(); |
83 | val = enc_delta; |
84 | enc_delta = val & 3; |
85 | sei(); |
86 | return val >> 2; |
87 | }
|
88 | |
89 | |
90 | int main( void ) |
91 | {
|
92 | int32_t val = 0; |
93 | |
94 | LEDS_DDR = 0xFF; |
95 | encode_init(); |
96 | sei(); |
97 | |
98 | for(;;){ |
99 | val += encode_read1(); // read a single step encoder |
100 | LEDS = val; |
101 | }
|
102 | }
|