Externer Interrupt INT0 und INT1 mit internen PullUps

Gast #2578411
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;
}
Gast #2578667
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.
#2578741
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.
.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren