Forum: Mikrocontroller und Digitale Elektronik Externer Interrupt am ATTINY 2313


von Le H. (beks)


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.

von Peter II (Gast)


Lesenswert?

ich seh gar keine Stelle wo die die Interupts aktivierst?

von Le H. (beks)


Lesenswert?

Du meinst den INT0 aktivieren? Ich hab schon geschaut im Datenblatt, 
kann das aber nicht richtig deuten.

von Peter II (Gast)


Lesenswert?

E. O. schrieb:
> Ich hab schon geschaut im Datenblatt,
> kann das aber nicht richtig deuten.

und was kannst du dort nicht deuten? Es gibt doch für jeden Interupt ein 
enable flag und bei den externen kann man sogar noch die die flanke für 
die erkennung einstellen.

von Le H. (beks)


Lesenswert?

In Assembler geht das einfach mit Enable INT0.

Ich schau im Datenblatt unter External Interrupts und da seh ich nicht 
durch. Muss ich dort unter EIFR schauen?

von Peter II (Gast)


Lesenswert?

E. O. schrieb:
> In Assembler geht das einfach mit Enable INT0.

das glaube ich nicht.


Du musst nur die passenden Bits im passenden Register auf 1 setzen

RegisterNameAusDatenblatt |= (1<<BIT_AUS_DATENBLATT)

von Peter II (Gast)


Lesenswert?

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.

von Le H. (beks)


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)

von Le H. (beks)


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 !?

von Peter II (Gast)


Lesenswert?

E. O. schrieb:
> EIFR = |= (1<<INTF0)

ja sorry der verweis mit der seite 30 war ein wenig falsch. Das sieht 
schon besser aus, dazu musst du noch die Flanke festlegen

Table 32. Interrupt 0 Sense Control
(seite 60)

von Le H. (beks)


Lesenswert?

Also so:
1
//Steigende Flanke für INT0
2
MCUCR |= (1<<ISC01) | (1<<ISC00);
3
//Aktiviere INT0
4
EIFR = |= (1<<INTF0)

Sieht das nur besser aus oder ist es auch richtig?

Für den Taster - den leg ich einmal auf den INT0 und auf der anderen 
Seite auf GND oder V++?

von Peter II (Gast)


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.

von Le H. (beks)


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

von Peter II (Gast)


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.

von Le H. (beks)


Lesenswert?

Peter II schrieb:
> Dafür kann man den Internen Pull-UP aktivieren oder man muss einen
> Externen Pull-UP oder Pull-Down verwenden.

Ich schalte also zwischen INT0 und GND einen Widerstand (z.B. 4,7k?). 
Dann leg ich den Schließer-Taster an Spannung und INT0?

von Peter II (Gast)


Lesenswert?

E. O. schrieb:
> Ich schalte also zwischen INT0 und GND einen Widerstand (z.B. 4,7k?).
> Dann leg ich den Schließer-Taster an Spannung und INT0?

wenn du unbedingt einen Widerstand verbauen willst: JA.

von Le H. (beks)


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
}

von Peter II (Gast)


Lesenswert?

ich glaube das EIFR ist doch falsch.

Setze mal lieber

 INT0: External Interrupt Request 0 Enable in GIMSK (Seite 60)

von Le H. (beks)


Lesenswert?

Super genau das war es! Jetzt erkennt er die externen Interrupts. Vielen 
Dank Peter! Und jetzt kannst du mir vielleicht noch ein Hinweis zum 
internen Pulldownwiderstand geben.

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?

von Peter II (Gast)


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?

von Le H. (beks)


Lesenswert?

Peter II schrieb:
> 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?

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.

von Le H. (beks)


Lesenswert?

So hab getestet mit
1
//Standbymodus
2
MCUCR |= (1<<SM1) | (1<<SM0);

Leider lässt sich durch den INT0 nicht der Controller daraus aufwecken. 
Wobei im Datenblatt für INT0 steht:

"for INT0 only level interrupt"

Was soll mir das sagen?

Hm ich weiß warum es nicht geht. Ich brauch wohl einen externen Takt, 
nutze bislang den internen.

von Le H. (beks)


Lesenswert?

Ok an dem interner RC-Oszillator sollte es nicht liegen.

Unter folgenden Link ist dafür nämlich eine Wartezeit im Powerdownmode 
angegeben. Die ich vielleicht nicht einhalte?

http://www.mikrocontroller.net/articles/Sleep_Mode

von Peter II (Gast)


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.

von Le H. (beks)


Lesenswert?

Peter II schrieb:
> das soll dir sagen das es im zusammenhang mit einer Flanken-Erkennung
> nicht geht.

Also wenn ich die Flankenerkennung auskommentiere sollte es gehen? Wenn 
ich das mache, dann hängt er sich dort wohl auf, also es werden erst gar 
keine Messungen gestartet. Er brauch das wohl eine Flankenerkennung 
bevor ich INT0 aktivere.

von Peter II (Gast)


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)

von Le H. (beks)


Lesenswert?

Achso ich hatte dich so verstanden das Standbymodus allgemein mit 
Flankenerkennung nicht geht. Du meinst aber ich muss die 
Flankenerkennung jetzt noch um den Pegel ergänzen? Wenn mir jetzt 
nochmal bei dem entsprechenden Register behilflich sein könntest? Das 
MCU Control Register ist es nicht.

von Peter II (Gast)


Lesenswert?

E. O. schrieb:
> Wenn mir jetzt
> nochmal bei dem entsprechenden Register behilflich sein könntest?

Table 31. Interrupt 1 Sense Control
Seite 60

von Peter II (Gast)


Lesenswert?

Ich habe noch mal die Doku genau gelesen. Bei INT0 sollte auch die 
Flanke gehen wie du es schon gemacht hast.

Seite 31:
Power-down : INT0, INT1 and Pin Change[2]
2. For INT0, only level interrupt.


Damit sollte das Aufwachen aus dem PowerDown mit INT0 und level gehen.

von Le H. (beks)


Lesenswert?

Versteh ich nicht, das hab ich doch längst im Quellcode drin. Zumal es 
Tabelle 32 für INT0 sein sollte.

//Steigende Flanke für INT0
MCUCR |= (1<<ISC01) | (1<<ISC00);

von Le H. (beks)


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.

von Le H. (beks)


Angehängte Dateien:

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
}

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.