Externer Interrupt am ATTINY 2313

#2394644
Lesenswert?

Hallo ich versuche vergebens durch einen externen Interrupt an INT0 den 
Controller aus dem Sleepmode zu holen. Mein bisheriger Quellcode.
1
#include "main.h"
2
#include "temp_eigen.h"
3
#include "lcd-routines.h"
4
 
5
 
6
char array[16];
7
volatile uint8_t tick;
8

9
uint8_t scratchpad[2];
10
uint8_t error;
11
uint8_t light;
12
uint8_t flash;
13

14
//ISR(TIMER1_COMPA_vect)          //aller 10msek.
15
ISR(INT0_vect)          //aller 10msek.
16
{
17
  //tick++;
18
  PORTD |= (1<<PD5);       // Interruptsignalisierung durch LED
19
}
20

21
int main(void)
22
{
23
//Timer1 aller 10ms bei 1MHz Taktfrequenz
24
//TCCR1B |= ((1<<WGM12) | (1<<CS11));    // Modus 4 CTC, Prescaler 8
25
//TIMSK |= (1<<OCIE1A);
26
//OCR1A = 12500;     
27
       
28

29
//Sleep_Mode Init
30
set_sleep_mode(SLEEP_MODE_IDLE);        //Init Sleep-Modus auf IDLE
31

32

33
//Anzeige init
34
lcd_init();
35
lcd_setcursor( 0, 1 );
36
lcd_string("-Happy Birthday-");
37
lcd_setcursor( 0, 2 );
38
lcd_string("read");
39

40
// Interrupts auf Eingang legen---LÖSCHEN
41
DDRD  &= ~(1<<DDD2) | (1<<DDD3);  
42
DDRD |= (1<<PD5); 
43

44

45
sei();
46

47
  for(;;)
48
  {
49
  lcd_setcursor( 0, 1 );
50
lcd_string("-Happy Birthday-");
51
lcd_setcursor( 0, 2 );
52
lcd_string("read");
53
    uint8_t digit;
54
   //Interrupts deaktivieren
55
  cli();
56

57
  //switch (tick)
58
  //{
59
  //  case 1:
60
  //  {
61
  _delay_ms(10);
62
      if(therm_reset())
63
        error = 1;
64
      else
65
        error = 0;
66
      if (!(error))
67
      {
68
        therm_write_byte(THERM_CMD_SKIPROM);
69
        therm_write_byte(THERM_CMD_CONVERTTEMP);
70
      }
71
  //  break;
72
  //  }
73

74
  _delay_ms(800);
75
  //  case 81:        //nach 800msek.
76
  //  {
77
      if (!(error))
78
      {
79
        therm_reset();
80
        therm_write_byte(THERM_CMD_SKIPROM);
81
        therm_write_byte(THERM_CMD_RSCRATCHPAD);
82
        scratchpad[0]=therm_read_byte();
83
        scratchpad[1]=therm_read_byte();
84
      }
85
lcd_setcursor( 0, 2 );
86
lcd_string("810");
87
  //  break;
88
  //  }
89

90
   _delay_ms(10);
91
  //  case 82:
92
  //  {
93
      if (!(error))
94
      {
95
        if (scratchpad[1] != 0)    //negative Temperatur
96
        {
97
          digit = ((0xff-scratchpad[0]) +1)>>1;
98
          if (digit < 10)
99
          {
100
            array[0] = ' ';
101
            array[1] = '-';              //Minus-Zeichen setzen
102
            array[2] = (digit%10) + '0';
103
            array[3] = 0xDF;
104
            array[4] = 'C';
105
            array[5] = '\0';
106
          }
107
          else
108
          {
109
            array[0] = '-';              //Minus-Zeichen setzen
110
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
111
            array[2] = (digit%10) + '0';      //einer stelle
112
            array[3] = 0xDF;
113
            array[4] = 'C';
114
            array[5] = '\0';
115
          }
116
          
117
        }
118
        else
119
        {
120
          digit=scratchpad[0]>>1;
121
          if (digit < 10)
122
          {
123
            array[0] = ' ';          
124
            array[1] = ' ';            //vorstellen-Null ausblenden
125
            array[2] = (digit%10) + '0';
126
            array[3] = 0xDF;
127
            array[4] = 'C';
128
            array[5] = '\0';
129
          }
130
          else
131
          {
132
            array[0] = ' ';  
133
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
134
            array[2] = (digit%10) + '0';      //einer stelle
135
            array[3] = 0xDF;
136
            array[4] = 'C';
137
            array[5] = '\0';
138
          }
139
        }
140
      }
141
  //  break;
142
  //  }
143
lcd_setcursor( 0, 2 );
144
lcd_string("820");
145
  _delay_ms(10);
146
  //  case 83:
147
  //  {
148
      lcd_setcursor( 0, 1 );
149
      //lcd_string("-Happy Birthday-");
150
      lcd_string("830");
151
      lcd_setcursor( 0, 2 );
152
      if (!(error))
153
      {
154
        lcd_string("Temperatur:");
155
        lcd_setcursor( 11, 2 );
156
        lcd_string(array);
157
      }
158
      else
159
        if (!(flash))            //abwechselnde Anzeige Sensor Error
160
        {
161
          lcd_string("Sensor Error    ");
162
          flash = 1;
163
        }
164
        else
165
        {
166
          lcd_string("                ");  //Löscht die 2. Zeile
167
          flash = 0;
168
        }
169
      tick = 0;
170
  //  break;
171
  //  }
172
    //}
173
  lcd_setcursor( 0, 2 );
174
  lcd_string("830");
175
   //Interrupts aktivieren
176
   sei();
177
   sleep_mode();
178
  }
179
}

Es wird wohl kein Interrupt ausgelöst. Das Programm geht in den 
Sleepmode und lässt sich über den Taster nicht aufwecken.
#2394669
Lesenswert?

Peter das ist sicherlich nett gemeint, aber mir ist leider noch nicht 
ersichtlich welches Register das ist. Es gibt dort ein

MCU Control Register
General Interrupt Mask Register
External Interrupt Flag Register
Pin Chance Mask Register.

Meiner Vermutung nach würd ich dann das External Interrupt Flag Register 
nehmen. Und dort müsst ich wohl den Pin6 setzen, damit der INT0 aktiv 
wird?
Also so vielleicht:
 EIFR = |= (1<<INTF0)
#2394670
Lesenswert?

Peter II schrieb:
> The INT0 and INT1 interrupts can be triggered by a falling or rising
> edge or a low level. This is
> set up as indicated in the specification for the “MCU Control Register –
> MCUCR” on page 30.

Muss ich denn die Entscheidung treffen ob steigende oder fallende 
Flanke? Oder entscheidet er eventuell automatisch wenn ich das 
unverändert lasse? Mit dem Register aktivier ich doch aber noch nicht 
den INT0 !?
Gast #2394685
Lesenswert?

E. O. schrieb:
> Sieht das nur besser aus oder ist es auch richtig?

keine Ahnung - dafür gibt es doch den Simulator

> Für den Taster - den leg ich einmal auf den INT0 und auf der anderen
> Seite auf GND oder V++?
kommt darauf an, hast du auch noch einen Pull-UP oder Pull-Down 
widerstand vorgesehen, wenn nein musst du auch noch den internen Pull-UP 
aktivieren und dann gegen GND schalten.
#2394689
Lesenswert?

Peter II schrieb:
> kommt darauf an, hast du auch noch einen Pull-UP oder Pull-Down
> widerstand vorgesehen, wenn nein musst du auch noch den internen Pull-UP
> aktivieren und dann gegen GND schalten.

Bislang habe ich davon noch nichts gemacht. Also könnt ich 
theorischerweise noch hinten den Taster ein Widerstand auf Masse legen?

Mit Simulator hab ich noch nicht gearbeiter. Aber so wie es jetzt ist 
funktioniert es anscheinend nicht. Bleibt weiterhin im sleepmode
Gast #2394690
Lesenswert?

E. O. schrieb:
> Also könnt ich theorischerweise noch hinten den Taster ein Widerstand auf Masse 
legen?

diesen Satz versteht ich nicht. Du musst dafür sorgen das wenn er Taster 
nicht gedrückt ist, das ein definierter Pegel an dem eingang anliegt. Es 
darf also keine "offnen" eingang geben.

Dafür kann man den Internen Pull-UP aktivieren oder man muss einen 
Externen Pull-UP oder Pull-Down verwenden.
#2394702
Lesenswert?

Naja sagen wir mal so, bis jetzt läuft das immer noch nicht mit dem 
Interrupt. Da ist für mich die schnellere Lösung. Es macht natürlich 
wahrscheinlich mehr Sinn den internen Widerstand zu nutzen. Das würd ich 
machen wenn der Interrupt funktioniert.
Mein Quellcode schaut jetzt so aus. Er arbeitet sich bis zum 
Sleepmodeaufruf durch, da diese Zeile noch verarbeitet wird.
1
lcd_string("830");
Allerdings kommt er dort wohl nicht raus, weil weder die LED an B5 
leuchtet, noch der Text sich auf dem LCD ändert.
1
#include "main.h"
2
#include "temp_eigen.h"
3
#include "lcd-routines.h"
4
 
5
 
6
char array[16];
7
volatile uint8_t tick;
8

9
uint8_t scratchpad[2];
10
uint8_t error;
11
uint8_t light;
12
uint8_t flash;
13

14
//ISR(TIMER1_COMPA_vect)          //aller 10msek.
15
ISR(INT0_vect)          //aller 10msek.
16
{
17
  //tick++;
18
  PORTD |= (1<<PD5); //LED
19
}
20

21
int main(void)
22
{
23
//Timer1 aller 10ms bei 1MHz Taktfrequenz
24
//TCCR1B |= ((1<<WGM12) | (1<<CS11));    // Modus 4 CTC, Prescaler 8
25
//TIMSK |= (1<<OCIE1A);
26
//OCR1A = 12500;     
27
       
28

29
//Sleep_Mode Init
30
set_sleep_mode(SLEEP_MODE_IDLE);        //Init Sleep-Modus auf IDLE
31

32

33
//Anzeige init
34
lcd_init();
35
lcd_setcursor( 0, 1 );
36
lcd_string("-Happy Birthday-");
37
lcd_setcursor( 0, 2 );
38
lcd_string("read");
39

40
// Interrupts auf Eingang legen---LÖSCHEN
41
DDRD  &= ~(1<<DDD2) | (1<<DDD3);  
42
DDRD |= (1<<PD5); 
43

44
//Steigende Flanke für INT0
45
MCUCR |= (1<<ISC01) | (1<<ISC00);
46
//Aktiviere INT0
47
EIFR |= (1<<INTF0);
48

49

50
sei();
51

52
  for(;;)
53
  {
54
  lcd_setcursor( 0, 1 );
55
lcd_string("-Happy Birthday-");
56
lcd_setcursor( 0, 2 );
57
lcd_string("read");
58
    uint8_t digit;
59
   //Interrupts deaktivieren
60
  cli();
61

62
  //switch (tick)
63
  //{
64
  //  case 1:
65
  //  {
66
  _delay_ms(10);
67
      if(therm_reset())
68
        error = 1;
69
      else
70
        error = 0;
71
      if (!(error))
72
      {
73
        therm_write_byte(THERM_CMD_SKIPROM);
74
        therm_write_byte(THERM_CMD_CONVERTTEMP);
75
      }
76
  //  break;
77
  //  }
78

79
  _delay_ms(800);
80
  //  case 81:        //nach 800msek.
81
  //  {
82
      if (!(error))
83
      {
84
        therm_reset();
85
        therm_write_byte(THERM_CMD_SKIPROM);
86
        therm_write_byte(THERM_CMD_RSCRATCHPAD);
87
        scratchpad[0]=therm_read_byte();
88
        scratchpad[1]=therm_read_byte();
89
      }
90
lcd_setcursor( 0, 2 );
91
lcd_string("810");
92
  //  break;
93
  //  }
94

95
   _delay_ms(10);
96
  //  case 82:
97
  //  {
98
      if (!(error))
99
      {
100
        if (scratchpad[1] != 0)    //negative Temperatur
101
        {
102
          digit = ((0xff-scratchpad[0]) +1)>>1;
103
          if (digit < 10)
104
          {
105
            array[0] = ' ';
106
            array[1] = '-';              //Minus-Zeichen setzen
107
            array[2] = (digit%10) + '0';
108
            array[3] = 0xDF;
109
            array[4] = 'C';
110
            array[5] = '\0';
111
          }
112
          else
113
          {
114
            array[0] = '-';              //Minus-Zeichen setzen
115
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
116
            array[2] = (digit%10) + '0';      //einer stelle
117
            array[3] = 0xDF;
118
            array[4] = 'C';
119
            array[5] = '\0';
120
          }
121
          
122
        }
123
        else
124
        {
125
          digit=scratchpad[0]>>1;
126
          if (digit < 10)
127
          {
128
            array[0] = ' ';          
129
            array[1] = ' ';            //vorstellen-Null ausblenden
130
            array[2] = (digit%10) + '0';
131
            array[3] = 0xDF;
132
            array[4] = 'C';
133
            array[5] = '\0';
134
          }
135
          else
136
          {
137
            array[0] = ' ';  
138
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
139
            array[2] = (digit%10) + '0';      //einer stelle
140
            array[3] = 0xDF;
141
            array[4] = 'C';
142
            array[5] = '\0';
143
          }
144
        }
145
      }
146
  //  break;
147
  //  }
148
lcd_setcursor( 0, 2 );
149
lcd_string("820");
150
  _delay_ms(10);
151
  //  case 83:
152
  //  {
153
      lcd_setcursor( 0, 1 );
154
      //lcd_string("-Happy Birthday-");
155
      lcd_string("830");
156
      lcd_setcursor( 0, 2 );
157
      if (!(error))
158
      {
159
        lcd_string("Temperatur:");
160
        lcd_setcursor( 11, 2 );
161
        lcd_string(array);
162
      }
163
      else
164
        if (!(flash))            //abwechselnde Anzeige Sensor Error
165
        {
166
          lcd_string("Sensor Error    ");
167
          flash = 1;
168
        }
169
        else
170
        {
171
          lcd_string("                ");  //Löscht die 2. Zeile
172
          flash = 0;
173
        }
174
      tick = 0;
175
  //  break;
176
  //  }
177
    //}
178
  lcd_setcursor( 0, 2 );
179
  lcd_string("830");
180
   //Interrupts aktivieren
181
   sei();
182
   sleep_mode();
183
  }
184
}
Gast #2394724
Lesenswert?

E. O. schrieb:
> Und jetzt kannst du mir vielleicht noch ein Hinweis zum
> internen Pulldownwiderstand geben.

steht alles auf Seite 47.

> Wenn ich den Sleepmode auf Standby stellen würde, dann könnt ich den
> Controller mit den externen Interrupt doch dennoch aus dem Schlaf holen
> oder?
Warum testest du es nicht einfach (oder liest das Datenblatt, dort steht 
erstmal ob es gehen müsste) oder hast du Angst das etwas Explodiert?
Gast #2394831
Lesenswert?

E. O. schrieb:
> Ne explodieren sollte hier wenig, aber wenn der nicht mehr aufwacht,
> dann hab ich keinen Controller mehr :) Hätte ja sein können, dass du
> darüber schon bescheid weißt.
ich weiss das, weil ich mich intensiv mit den Datenblatt beschäftig 
habe. Und auch die nebensätze lese wo drin steht unter welchen 
bedingungen er wir arbeitet.


> "for INT0 only level interrupt"
> Was soll mir das sagen?

das soll dir sagen das es im zusammenhang mit einer Flanken-Erkennung 
nicht geht.
Gast #2394854
Lesenswert?

E. O. schrieb:
> Also wenn ich die Flankenerkennung auskommentiere sollte es gehen?

nich auskommentieren, anpassen. Du musst dich dann entscheiden ob du auf 
High oder Low reagieren willst. Wenn du auf "spannung" den Taster 
angeschlossn hast dann must du auf High reagieren. Aber der interupt 
wird dann ständig aufgerufnen wenn der Taster gedrückt ist. Wenn das 
stört muss die den Interupt abschalten wenn du wach bist und ihn erst 
wieder anschalten wenn du schlafen gehst.  (oder eine anderen Atmel 
verwenden, die Megas können das was du willst)
#2394890
Lesenswert?

Peter II schrieb:
> Damit sollte das Aufwachen aus dem PowerDown mit INT0 und level gehen.

Ja dachte ich auch, aber es passiert nicht. Den Sleepmode tu ich jetzt 
mit
1
MCUCR |= (0<<SM1) | (1<<SM0);

anstelle von vorher
1
set_sleep_mode(SLEEP_MODE_IDLE);
setzen. Das sollte aber nicht das Problem sein.

Für den Powerdownmode weiß ich allerdings noch nicht so recht ob es egal 
ist SM1 = 0 und SM0 = 1 oder SM1 = 1 und SM0 = 0. Ich habe beide 
Varianten versucht. Erfolglos.
#2394958
Lesenswert?

Laut Datenblatt sollte das eigentlich wirklich funktionierne. Ich weiß 
nicht wo ich weiter suchen soll.

Also wenn ich das ganze im idlemode mache, hab ich ein Strom von ca. 
4mA, bring ich den Controller in den powerdownmode dann hab ich 
lediglich 1mA mit LCD. Aus dem Grund ist es für mich sehr 
erstrebenswert, den Controller in den powerdownmode zu bekommen und den 
mit den Interrupt wieder daraus zu erwecken.
1
#include "main.h"
2
#include "temp_eigen.h"
3
#include "lcd-routines.h"
4
 
5
 
6
char array[16];
7
volatile uint8_t tick;
8

9
uint8_t scratchpad[2];
10
uint8_t error;
11
uint8_t light;
12
uint8_t flash;
13

14

15
ISR(INT0_vect)          //aller 10msek.
16
{
17

18
}
19

20
int main(void)
21
{ 
22
//Sleep_Mode Init Power Down, Idle oder Standby
23
MCUCR |= (1<<SM1) | (0<<SM0);
24

25
//Anzeige init
26
lcd_init();
27

28
// Interrupts auf Eingang legen
29
DDRD  &= ~(1<<DDD2);  
30

31
//Steigende Flanke für INT0
32
MCUCR |= (1<<ISC01) | (1<<ISC00);
33
//Aktiviere INT0
34
GIMSK |= (1<<INT0);
35

36

37
//Interrupts aktivieren
38
sei();
39

40
  for(;;)
41
  {
42
    lcd_setcursor( 0, 1 );
43
  lcd_string("-Happy Birthday-");
44
  lcd_setcursor( 0, 2 );
45
  lcd_string("read            ");
46
    uint8_t digit;
47
   //Interrupts deaktivieren
48
  cli();
49

50
  _delay_ms(10);
51
      if(therm_reset())
52
        error = 1;
53
      else
54
        error = 0;
55
      if (!(error))
56
      {
57
        therm_write_byte(THERM_CMD_SKIPROM);
58
        therm_write_byte(THERM_CMD_CONVERTTEMP);
59
      }
60

61

62
  _delay_ms(800);
63
      if (!(error))
64
      {
65
        therm_reset();
66
        therm_write_byte(THERM_CMD_SKIPROM);
67
        therm_write_byte(THERM_CMD_RSCRATCHPAD);
68
        scratchpad[0]=therm_read_byte();
69
        scratchpad[1]=therm_read_byte();
70
      }
71

72
   _delay_ms(10);
73
      if (!(error))
74
      {
75
        if (scratchpad[1] != 0)    //negative Temperatur
76
        {
77
          digit = ((0xff-scratchpad[0]) +1)>>1;
78
          if (digit < 10)
79
          {
80
            array[0] = ' ';
81
            array[1] = '-';              //Minus-Zeichen setzen
82
            array[2] = (digit%10) + '0';
83
            array[3] = 0xDF;
84
            array[4] = 'C';
85
            array[5] = '\0';
86
          }
87
          else
88
          {
89
            array[0] = '-';              //Minus-Zeichen setzen
90
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
91
            array[2] = (digit%10) + '0';      //einer stelle
92
            array[3] = 0xDF;
93
            array[4] = 'C';
94
            array[5] = '\0';
95
          }
96
          
97
        }
98
        else
99
        {
100
          digit=scratchpad[0]>>1;
101
          if (digit < 10)
102
          {
103
            array[0] = ' ';          
104
            array[1] = ' ';            //vorstellen-Null ausblenden
105
            array[2] = (digit%10) + '0';
106
            array[3] = 0xDF;
107
            array[4] = 'C';
108
            array[5] = '\0';
109
          }
110
          else
111
          {
112
            array[0] = ' ';  
113
            array[1] = ((digit/10)% 10)+ '0';    //zehner Stelle
114
            array[2] = (digit%10) + '0';      //einer stelle
115
            array[3] = 0xDF;
116
            array[4] = 'C';
117
            array[5] = '\0';
118
          }
119
        }
120
      }
121

122
  _delay_ms(10);
123
      if (!(error))
124
      {
125
        lcd_setcursor( 0, 2 );
126
        lcd_string("Temperatur:");
127
        lcd_setcursor( 11, 2 );
128
        lcd_string(array);
129
      }
130
      else
131
        if (!(flash))            //abwechselnde Anzeige Sensor Error
132
        {
133
          lcd_string("Sensor Error    ");
134
          flash = 1;
135
        }
136
        else
137
        {
138
          lcd_string("                ");  //Löscht die 2. Zeile
139
          flash = 0;
140
        }
141
      tick = 0;
142

143
   //Interrupts aktivieren
144
   sei();
145
   sleep_mode();
146
  }
147
}
Angehängte Dateien:

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