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
volatileuint8_tint0;
2
volatileuint8_tint1;
3
volatileuint8_tcount=0;
4
volatileuint8_tcountint0=0;
5
volatileuint8_tcountint1=0;
6
volatileuint8_ttest;
7
volatileuint8_ttest2;
8
volatileuint8_ttest3;
9
10
11
voidTimer3Init(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
voidIntInit(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
intmain(void)
93
{
94
charbuffer[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////////////////////////////
muss ich den beim Rücksetzen des Interruptflags irgendwas beachten außer
das man es setzen muss?
GIFR|= _BV(INTF1) | _BV(INTF0); -> löscht doch quasi alle vorher
anstehenden externen Interrupts das diese nicht mehr ausgeführt werden
oder verstehe ich da was falsch?
Gruß
Markus
Hi spess,
danke für die Antwort. ja klar prellt er,das möchte ich ja mit dem
Timer3 abfangen. Es handelt sich hierbei um eine Aufgabe von der Uni, es
soll leider mit Interrupts gelöst werden. (-:
Gruß
Markus
@ Markus (Gast)
>danke für die Antwort. ja klar prellt er,das möchte ich ja mit dem>Timer3 abfangen.Timer ist richtig, Interrupt auch, aber NICHT Pin Change bzw.
Flankenwechsel an INT0/1!
MFG
Falk
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.