Hallo ich bin die letzen Tage dabei eine Auswertung für einen Drehgeber
von ALPS zu programmieren.
Er soll:
- über Interrupts funktionieren (int0/int1)
- Entprellen über Timer3
- Variable "count" hochzählen/herunterzählen
Meine Hardware:
-mega162
Problem:
Er zählt an sich gut hoch und runter, allerdings fängt er oft plötzlich
an 3-5 Schritte nacheinander in die gegenrichtung zu Zählen!!Dann wieder
richtig! Habe mir auf einem LCD mal ein paar Hilfsvariablen darstellen
lassen. Sie zeigen mir wenn ich Sie richtig interpretiere an, dass meine
aufkommenden Interrupt während einer Int0/1 Routine gespeichert werden
und trotz Gesetzen INTF0/1 nach dem Entprellvorgang durchkommen!
und somit eine weiter Routine von int0/1 aufgerufen wird. Bin mir nicht
sicher ob das verzählen in die andere Richtung und das deaktivieren der
Interrupts ein und das selbe Problem sind?
Frage: Warum kommen nach dem ich INTF0 und INTF1 in GIFR Gesetz habe
noch Interrupts von int0 bzw. int1 durch?
1 | GIFR|= _BV(INTF1) | _BV(INTF0);
|
ist der Befehl vielleicht an falscher stelle?
Wäre dankbar für jede Art von Anregung oder Lösung (-:
Gruß
Markus
1 | volatile uint8_t int0;
|
2 | volatile uint8_t int1;
|
3 | volatile uint8_t count = 0;
|
4 | volatile uint8_t countint0 = 0;
|
5 | volatile uint8_t countint1 = 0;
|
6 | volatile uint8_t test;
|
7 | volatile uint8_t test2;
|
8 | volatile uint8_t test3;
|
9 |
|
10 |
|
11 | void Timer3Init(void)
|
12 | {
|
13 | TCCR3B = _BV(CS31);//Teiler 8
|
14 | ETIMSK = _BV(OCIE3A);//overflow interrupt
|
15 | TCNT3 = 0;
|
16 | OCR3A = 60000; //ca 0.5sekunden
|
17 |
|
18 | }
|
19 |
|
20 |
|
21 | void IntInit(void)
|
22 | {
|
23 | MCUCR = _BV(ISC11) | _BV(ISC01);
|
24 | GICR = _BV(INT1) | _BV(INT0);
|
25 |
|
26 | }
|
27 |
|
28 |
|
29 | ISR(INT0_vect)
|
30 | {
|
31 | countint0++; //Hilfsvariable
|
32 | int0=1;
|
33 | if(int1==0 && test==0)
|
34 | {
|
35 | count++; //wenn es der erste Interreupt ist geht er in die if schleife
|
36 | test=1;
|
37 | }
|
38 | else
|
39 | {
|
40 |
|
41 | int1=0;
|
42 | int0=0;
|
43 | GICR &=~ (1 << INT1); //deaktvieren der Externen Interrupts
|
44 | GICR &=~ (1 << INT0); //deaktvieren der Externen Interrupts
|
45 | Timer3Init();
|
46 |
|
47 | }
|
48 |
|
49 | }
|
50 |
|
51 |
|
52 | ISR(INT1_vect)
|
53 | {
|
54 | countint1++; //Hilfsvariable
|
55 | int1=1;
|
56 | if(int0==0 && test2==0)
|
57 | {
|
58 | count--; //wenn es der erste Interreupt ist geht er in die if schleife
|
59 |
|
60 | test2=1;
|
61 | }
|
62 | else
|
63 | {
|
64 | int1=0;
|
65 | int0=0;
|
66 | GICR &=~ (1 << INT1); //deaktvieren der Externen Interrupts
|
67 | GICR &=~ (1 << INT0); //deaktvieren der Externen Interrupts
|
68 | Timer3Init();
|
69 |
|
70 |
|
71 | }
|
72 | }
|
73 |
|
74 |
|
75 |
|
76 |
|
77 | ISR(TIMER3_COMPA_vect)
|
78 | {
|
79 | ETIMSK = 0x00; //Timer3 auschalten
|
80 | GIFR|= _BV(INTF1) | _BV(INTF0); //****Interrupt-bit zurücksetzen (bis her aufgelaufende Int. rücksetzen)
|
81 | GICR = _BV(INT1) | _BV(INT0); //Interrupt wieder anschalten
|
82 |
|
83 | test=0; //Verriegelung
|
84 | test2=0; //Verriegelung
|
85 | test3++; //Hilfsvariable
|
86 |
|
87 | }
|
88 |
|
89 |
|
90 |
|
91 |
|
92 | int main(void)
|
93 | {
|
94 | char buffer[7];
|
95 |
|
96 |
|
97 | DDRD &=~ (1 << PD1);
|
98 | PORTD |= (1 << PD1);
|
99 |
|
100 | DDRB |= (1<<PB0);
|
101 | PORTB |= (1<<PB0);
|
102 |
|
103 | lcd_init(LCD_DISP_ON);
|
104 |
|
105 | IntInit();
|
106 | sei();
|
107 | while(1)
|
108 | {
|
109 |
|
110 | //////////////////Nur die Anzeige der Hilfvariablen auf dem LCD////////////////////////////
|
111 |
|
112 | OCR1A=count;
|
113 |
|
114 | lcd_clrscr();
|
115 | lcd_puts("c:");
|
116 | itoa( count , buffer, 10);
|
117 | lcd_gotoxy(2,0);
|
118 | lcd_puts(buffer);
|
119 | /*
|
120 | lcd_gotoxy(0,1);
|
121 | lcd_puts("test:");
|
122 | lcd_gotoxy(5,1);
|
123 | itoa( test , buffer, 10);
|
124 | lcd_puts(buffer);
|
125 | */
|
126 | lcd_gotoxy(0,1);
|
127 | lcd_puts("tes3:");
|
128 | lcd_gotoxy(5,1);
|
129 | itoa( test3 , buffer, 10);
|
130 | lcd_puts(buffer);
|
131 | /*
|
132 | lcd_gotoxy(8,1);
|
133 | lcd_puts("tes2:");
|
134 | lcd_gotoxy(13,1);
|
135 | itoa( test2 , buffer, 10);
|
136 | lcd_puts(buffer);
|
137 | */
|
138 | lcd_gotoxy(8,0);
|
139 | lcd_puts("i0:");
|
140 | lcd_gotoxy(11,0);
|
141 | itoa( countint0 , buffer, 10);
|
142 | lcd_puts(buffer);
|
143 |
|
144 |
|
145 | lcd_gotoxy(8,1);
|
146 | lcd_puts("i1:");
|
147 | lcd_gotoxy(11,1);
|
148 | itoa( countint1 , buffer, 10);
|
149 | lcd_puts(buffer);
|
150 |
|
151 | _delay_ms(50);
|
152 |
|
153 | }
|
154 |
|
155 | }
|