Hallo, ich möchte gerne durch drücken eines Tasters einen Interrupt auslösen. Ich habe die Internen Pullups aktiviert und und schalte den Port durch Drücken auf GND. Es funktioniert aber nicht. Ich nutze eine ATMega8 mit 1MHz internen Osszillator und die Taster sind an den Pins PD2 (INT0) und PD3 (INT1) angeschlossen. Durch drücken des Taster sollen die Pins PC0 und PC1 getoggelt werden. mein code: ... DDRC = 0x03; DDRD = 0xF3; ... int main() { ... //INTERRUPT (MCUCR S.33, GICR S.49) DDRD &= ~((1<<PD2)|(1<<PD3)); //Interne PullUps Setzen PORTD |= ((1<<PD2)|(1<<PD3)); MCUCR &= ~0x0F; // löschen MCUCR |= 0x0A; // INT0, INT1 auf fallende Flanke GICR |= (1<<INT1) | (1<<INT0); // Interrupts aktivieren sei(); // Interrupts einschalten ... } ... ISR( INT0_vect ){ PORTC ^= 0x01; } ISR( INT1_vect ){ PORTC ^= 0x02; }
Wie werden die Ports ueberwacht? Per LED oder per Scope? Wenn die Schalter prellen, dann flackert das eventuell sehr schnell!
Nachtrag: Main macht aber schon eine while(1)-Schleife, oder?
Es gibt natürlich ne while(1) ;-) an den ports hängt ne led, und es tut sich garnicht leider. die flackert nicht mal ein bisschen
aspire schrieb: > an den ports hängt ne led, und es tut sich garnicht leider. die flackert > nicht mal ein bisschen Vielleicht prellt die Taste genau 1x und Du schaltest 2x um und siehst nichts? (Wie wahrscheinlich das ist, sei mal dahingestellt.) Schalte die LED mal nur ein! Ansonsten: LED richtig herum? Defekt? Am richtigen Pin? Gruß Dietrich
1.: LED nur einschalten (in Main), dann ist sicher, dass sie auch tun! 2.: | statt ^ in den ISR's, um sicherzustellen, dass diese durchlaufen werden
//Interrupts //---------- ISR( INT0_vect ){ PORTC |= 0x01; } ISR( INT1_vect ){ PORTC |= 0x02; } beide interrupt lösen sofort aus.
Gibt es vielleicht probleme, wenn ich mein LCD Display auch über den PORTD ansteuere?
Hallo aspire, das ist doch kein Problem, sondern dein Unwissen, wie man Taster - die immer PRELLEN - abfragt. Taster direkt über Interrupts gehören nicht zusammen ! .
Ich weis das Taster Prellen, aber selbst wenn ich da ne prellzeit einfüge oder ähnliches besteht das problem immernoch!
Es hatte mit nem externen PULLUP auch schon alles funktioniert, jetzt wollte ich aus platzgründen auf den internen zurückgreifen
du gibst deinem internen (hochohmige) Pullup nur ca 1 µs Zeit, um den zuvor wahrscheinlich undefinierten Pin auf high zu ziehen. Vielleicht ist das zu kurz (der externe Pullup hat dafür ms lang Zeit, weil er ab dem Powerup wirkt). Bau mal eine Wartezeit zwischen dem Aktivieren der Pullups und dem enablen des Interrupts ein oder treibe die beiden Pins zunächst mal als Ausgang definiert auf high, und schalte sie dann erst als Eingang mit Pullup.
Hallo, hier ist mal ein anderer Ansatz der "C" Programmierung, man sieht viel besser was da passiert:
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | |
4 | // Access bits like variables:
|
5 | struct bits { |
6 | uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; |
7 | } __attribute__((__packed__)); |
8 | #define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
|
9 | #define SBIT(x,y) SBIT_(x,y)
|
10 | |
11 | #define TASTER0 SBIT(PORTD,PD2)
|
12 | #define TASTER0_DDR SBIT(DDRD,PD2)
|
13 | #define TASTER1 SBIT(PORTD,PD3)
|
14 | #define TASTER1_DDR SBIT(DDRD,PD3)
|
15 | |
16 | #define LED0 SBIT(PORTC,PC0)
|
17 | #define LED0_DDR SBIT(DDRC,PC0)
|
18 | #define LED1 SBIT(PORTC,PC1)
|
19 | #define LED1_DDR SBIT(DDRC,PC1)
|
20 | |
21 | int main( void ) |
22 | {
|
23 | ...
|
24 | |
25 | // config LED
|
26 | LED0_DDR = 1; |
27 | LED1_DDR = 1; |
28 | LED0 = 0; |
29 | LED1 = 0; |
30 | |
31 | //INTERRUPT (MCUCR S.33, GICR S.49)
|
32 | TASTER0 = 1; // Interne PullUps setzen |
33 | TASTER1 = 1; // Interne PullUps setzen |
34 | TASTER0_DDR = 0; // Pin auf Eingang |
35 | TASTER1_DDR = 0; // Pin auf Eingang |
36 | |
37 | // von Dir übernommen
|
38 | MCUCR &= ~(_BV(ISC11) ^ _BV(ISC10) ^ _BV(ISC01) ^ _BV(ISC00)); |
39 | MCUCR |= (_BV(ISC11) ^ _BV(ISC01); |
40 | |
41 | GICR |= (_BV(INT1) ^ _BV(INT0); |
42 | sei(); // Interrupts einschalten |
43 | |
44 | while (1) { /* any time */ } |
45 | |
46 | return 0; |
47 | }
|
48 | |
49 | ISR( INT0_vect ){ |
50 | LED0 = 1; |
51 | }
|
52 | |
53 | ISR( INT1_vect ){ |
54 | LED1 = 1; |
55 | }
|
Entprellen muss man immer noch, hier ein Inline Macros von Peda: Beitrag "Entprellen für Anfänger" Das Konzept heißt dann Pollen der Pins, die ISR werden gelöscht. .
Es lag an der display libary und nicht am entprellen oder irgentwas anderem!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.