Forum: Mikrocontroller und Digitale Elektronik Externer Interrupt INT0 und INT1 mit internen PullUps


von aspire (Gast)


Lesenswert?

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;
}

von Avr (Gast)


Lesenswert?

Wie werden die Ports ueberwacht?
Per LED oder per Scope?
Wenn die Schalter prellen, dann flackert das eventuell sehr schnell!

von Avr (Gast)


Lesenswert?

Nachtrag: Main macht aber schon eine while(1)-Schleife, oder?

von aspire (Gast)


Lesenswert?

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

von Dietrich L. (dietrichl)


Lesenswert?

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

von Avr (Gast)


Lesenswert?

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

von aspire (Gast)


Lesenswert?

//Interrupts
//----------
ISR( INT0_vect ){
  PORTC |= 0x01;
}

ISR( INT1_vect ){
  PORTC |= 0x02;
}

beide interrupt lösen sofort aus.

von aspire (Gast)


Lesenswert?

und die leds leuchten

von aspire (Gast)


Lesenswert?

Gibt es vielleicht probleme, wenn ich mein LCD Display auch über den 
PORTD ansteuere?

von Uwe (de0508)


Lesenswert?

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 !

.

von aspire (Gast)


Lesenswert?

Ich weis das Taster Prellen, aber selbst wenn ich da ne prellzeit 
einfüge oder ähnliches besteht das problem immernoch!

von aspire (Gast)


Lesenswert?

Es hatte mit nem externen PULLUP auch schon alles funktioniert, jetzt 
wollte ich aus platzgründen auf den internen zurückgreifen

von Achim S. (Gast)


Lesenswert?

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.

von Uwe (de0508)


Lesenswert?

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.
.

von aspire (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.