Interrupt ATtiny85 - Hilfe

OP #7552418
Lesenswert?

Bin nun aus Langeweile dabei eine alte Taschenlampe umzubauen. Ehemals Bleiakku ..., nun Hardware (NE555) alles fertig. Will die Steuerung aber mit einem ATtiny85 vornehmen. Habe vor langer Zeit so etwas programmiert (Z80 noch mit HEX-Code) und mit dem Versuchssteuerungen für physiologische Experimente aufgebaut. Sehe nun offensichtlich durch die IR-Funktionsweise des uC nicht durch. Programmablauf ist ja relativ simpel. Power on schaltet Modus 1 ein. Tasterdruck setzt Variable auf true und schaltet Modus weiter (4 Leuchtmodi). Diese werden in der while Schleife ausgewertet (wenn true, nächster Modus, sonst alter). Vor dem Verlassen der IR-Routine wird IR disabled und nach dem neuen Modus wieder enabled. Die IR wird auch ausgeführt. Mit der meiner While() komme ich nicht weiter. Simulieren geht (Variable event & modus von Hand gesetzt). AT85 sitzt auf Breadboard mit entsprechender Hardware zum testen. Kann mir da jemand helfen. Kenne das Datenblatt mitterlerweile fast auswendig und auch ein paar Bücher neben mir. Den Skript habe gekürzt (Bibliotheken, Definition und Deklarationen) denn der Compiler zeigt keine Fehler an. (Skript nochmal als Anhang). Hoffe jemand gibt mir etwas Nachhilfe.

1
//Interrupt Service Routine for INT0
2
ISR(INT0_vect) {
3
  Button_event=true;
4
  _delay_ms(10);        // button debounce
5
  GIMSK &= ~ (1<<INT0);    // disable IR
6
  //Test_LED_toggle();      // visual control toggle PORTB 
7
  //_delay_ms(20);
8
}
9

10
int main(void)
11
{
12
  // setting i/o ports
13
  DDRB &= ~ (1<< PB2);                            // PB2 input - clear bit
14
  PORTB |= (1 << PB2);                            // PB2 pull up
15
  DDRB  |= (1<< PB1) ;
16
  DDRB |= (1<< PB4);                              // PB1 and PB4 output
17
  PORTB &= ~( (1<<PB1) | (1<<PB4));                      // LED off  
18
  //PORTB |= (1<<PB1) | (1<<PB4);                        // LED on 
19
    
20
  Full_Light();                                
21
    
22
  // setting interrupt
23
  GIMSK |= (1<<INT0);                              // ext. interrupt enable
24
  MCUCR |=(1<<ISC00); 
25
  MCUCR |= (1<<ISC01);                            //  Trigger INT0 on rising edge
26
  sei();  
27
                                    
28
  Light_mode=0;
29
  Button_event=true;
30
  
31
  while (1)
32
    {
33
      if (Button_event==true) {
34
        Button_event=false;
35
        Light_mode++;
36
      }
37
      if (Light_mode>=4) {
38
        Light_mode=0;
39
      }    
40
      while (Light_mode==0) {
41
        Full_Light();
42
        GIMSK |= (1<<INT0);
43
        sei();
44
      }
45
      while (Light_mode==1){
46
        Half_Light();
47
        GIMSK |= (1<<INT0);
48
        sei();
49
      }
50
      while (Light_mode==2) {
51
        SOS();
52
        GIMSK |= (1<<INT0);
53
        sei();
54
      }
55
      while (Light_mode==3)  {
56
        Flash_Ligt_1();
57
        GIMSK |= (1<<INT0);
58
        sei();
59
        //Light_mode=0;
60
      }    
61
    }
62
}
63

64
void Test_LED_toggle() {
65
  PORTB=~PORTB;  
66
  //_delay_ms(1000);
67
}
68

69
void Full_Light() {
70
  
71
  PORTB |= (1 << LED_Vcc_Warning);          // red on blue 0ff
72
}
73

74
void Half_Light() {
75
  PORTB |= (1 << LED_Light);              // blue on red off
76
  PORTB &=~(1 << LED_Vcc_Warning);                          
77
}
78

79
void SOS() {
80
  PORTB |= (1 << LED_Vcc_Warning);          // rot blau an               
81
}
82

83
void Flash_Ligt_1()  {
84
  _delay_ms(2000);                  // blinc              
85
  PORTB |= (1 << LED_Light);                            
86
  _delay_ms(500);
87
  PORTB &=~(1 << LED_Light);                            
88
  _delay_ms(500);
89
  PORTB &=~(1 << LED_Vcc_Warning);                      
90
}

[Mod: c-Tags das nächste Mal bitte selber einfügen. Und längeren Sourcecode als Anhnag posten]

Angehängte Dateien:
#7552427
Lesenswert?

Michael schrieb:

Sehe nun offensichtlich durch die IR-Funktionsweise des uC nicht durch.

IR? Infrarot? Oder eher Interrupt?

Programmablauf ist ja relativ simpel. Power on schaltet Modus 1 ein. Tasterdruck setzt Variable auf true und schaltet Modus weiter (4 Leuchtmodi). Diese werden in der while Schleife ausgewertet (wenn true, nächster Modus, sonst alter). Vor dem Verlassen der IR-Routine wird IR disabled und nach dem neuen Modus wieder enabled. Die IR wird auch ausgeführt. Mit der meiner While() komme ich nicht weiter.

Dein Programm ist nicht sonderlich sinnvoll.

Den Skript habe gekürzt (Bibliotheken, Definition und Deklarationen) denn der Compiler zeigt keine Fehler an. (Skript nochmal als Anhang).

Warum nicht den originalen Quelltext unverändert anhängen? Zu einfach? Zu wenig fehleranfällig? OMG! Und wozu dann nochmal als Text im Beitrag?

Hoffe jemand gibt mir etwas Nachhilfe.

Ja, lies was über Netiquette. Und Entprellung. Tasten wertet man im Normalfall NICHT per externem Interrupt aus. Dann braucht man dort auch keine komischen Delays. Das macht man bestenfalls, wenn man sehr stromsparend mit dem Sleep Mode arbeitet, was du hier aber nicht tust. Deine Tastenauswertung und zentrale Programmlogik ist auch nicht sonderlich brauchbar.

OP #7552446
Lesenswert?

Vermute, dass die IR da nicht reinkommt.

prinzipielle Funktionsweise der IR habe ich getestet mit (funzt auch). Vielleicht hast Du, Steve, eine Idee?.

/Interrupt Service Routine for INT0/ ISR(INT0_vect) { PORTB=~PORTB; /* Toggle PORTC / _delay_ms(50); / Software debouncing control delay */ }

int main(void) { //DDRB=0xFF; /* Make PORTC as output PORT*/ // PB2 - input DDRB &= ~ (1<< PB2); // PB2 input PORTB |= (1 << PB2); // Pull Up PIN7-PB2

// PB1 - output DDRB = (0<< PB1); // PB1 output PORTB |= (1 << PB1); //PB1 (PIN6)

// PB4 - output DDRB = (0<< PB4); // PB4 output PORTB &= ~(1 << PB4); //PB4 (PIN3)

GIMSK = 1<<INT0; /* Enable INT0*/ MCUCR = 1<<ISC01 | 1<<ISC00; /* Trigger INT0 on rising edge / sei(); / Enable Global Interrupt */

while (1); }

Gast #7552447
Lesenswert?

Falk B. schrieb:

Dein Programm ist nicht sonderlich sinnvoll. Tasten wertet man im Normalfall NICHT per externem Interrupt aus. Dann braucht man dort auch keine komischen Delays.

Für mich sieht das Programm durchaus sinnvoll und Prinzipiell funktionsfähig aus.

Konzentriere dich auf das Problem, nicht auf den Programmierstil. Lass die Kurve mal gerade sein. Jeder hat mal angefangen.

Gast #7552452
Lesenswert?

Du könntest den Wert der Variable Button_event in main() kontrollieren, indem du ihren Wert durch ein Blinkmuster anzeigst.

Ich nehme an, dass das Schlüsseldorf "volatile" vor "Button_event=true;" helfen wird. Probiere das aus.

#7552454
Lesenswert?

Steve van de Grens schrieb:

Michael schrieb:

Mit der meiner While() komme ich nicht weiter.

Was ist denn dein Problem mit der while Schleife?

Es sind Endlos-Schleifen: while (Light_mode==0) { Full_Light(); GIMSK |= (1<<INT0); sei(); }

statt 'while' muss es 'if' heißen. :-))

Davon abgesehen ist das Programm verwirrend und viel zu kompliziert. In diesem einfachen Fall braucht man gar keinen Interrupt. Man kann die Taste in der Hauptschleife abfragen.

Gast #7552467
Lesenswert?

Rolf schrieb:

Es sind Endlos-Schleifen: while (Light_mode==0) { statt 'while' muss es 'if' heißen. :-))

Stimmt, Adlerauge sei wachsam!

Änderungsvorschlag (zusätzlich zum Volatile):

1
  while (1) {
2

3
      if (Button_event==true) {
4
        Button_event=false;
5
        Light_mode++;
6
      }
7

8
      switch (Light_mode) {
9
        case 4: {
10
          Light_mode=0;
11
        }  
12

13
        case 0:
14
          Full_Light();
15
          break;
16

17
        case 1:
18
          Half_Light();
19
          break;
20

21
        case 2:
22
          SOS();
23
          break;
24

25
        case 3:
26
          Flash_Ligt_1();
27
          break;
28
   
29
       default:
30
          Light_mode=0;
31
    }
32
}

Bitte entschuldige, falls da Syntaxfehler drin sind. Ich arbeite seit mehr als einem Jahr mit anderen Programmiersprachen.

Den Teil "Light_mode++" könnte man in die ISR verschieben, dann entfällt die Variable Button_event. Light_mode sollte müsste dann volatile sein.

Gast #7552470
Lesenswert?

Michael schrieb:

ja das ist eine Endlosschleife aber nur solange bis ein IR erfolgt dachte ich. Oder liege ich da falsch?

Dein Fehler ist: Light-mode wird bei Tastendruck nicht geändert, weil

1
      if (Button_event==true) {
2
        Button_event=false;
3
        Light_mode++;
4
      }

außerhalb der "endlosen" while Schleife liegt.

OP #7552496
Lesenswert?

ja das war es, nun muss ich nur den Unterschied verstehen. Danke Dir sehr. Mit dem Break kommt er wieder in die Endlosschleife, das ist bei mir nicht so. Da hatte ich gedacht, dass er diese mit dem IR-Request verlässt und mit der Whileschleife wieder anfängt. Gruß Michael p.s. benutze Atmel7 mit einem STK500-Clone

OP #7552500
Lesenswert?

Steve van de Grens schrieb:

Michael schrieb:

ja das ist eine Endlosschleife aber nur solange bis ein IR erfolgt dachte ich. Oder liege ich da falsch?

Dein Fehler ist: Light-mode wird bei Tastendruck nicht geändert, weil

1
>       if (Button_event==true) {
2
>         Button_event=false;
3
>         Light_mode++;
4
>       }
5
>

außerhalb der "endlosen" while Schleife liegt.

das verstehe ich nicht. Der Code lautet:

while (1) { if (Button_event==true) { Button_event=false; Light_mode++; }

#7552516
Lesenswert?

@Michael Du scheinst die Vorstellung zu haben, mit einem Interrupt könne man Schleifen verlassen. Nein, kann man nicht. Eine Schleife kann man nur durch eine 'break'-Anweisung verlassen, oder dadurch, dass die Schleifenbedingung nicht (mehr) erfüllt ist.

(Firma: Gast) #7552523
Lesenswert?

Reduziert, und getestet mit einem Digispark in der Arduino IDE. Als C und nicht C++ kompiliert

1
#include <Arduino.h>
2

3
/*Interrupt Service Routine for INT0*/
4
ISR(INT0_vect)
5
{
6
  PINB  = (1 << PB1); // toggle
7
}
8

9
int main(void)
10
{
11
  PORTB |= (1 << PB2);    // Pullup
12
  DDRB  |= (1 << PB1);    // output
13

14
  GIMSK = 1<<INT0;              // Enable INT0
15
  MCUCR = 1<<ISC01 | 1<<ISC00;  // Trigger INT0 on rising edge
16
  sei();                        // Enable Global Interrupt 
17

18
  while (1);
19
}
OP #7552528
Lesenswert?

Rolf schrieb:

@Michael Du scheinst die Vorstellung zu haben, mit einem Interrupt könne man Schleifen verlassen. Nein, kann man nicht. Eine Schleife kann man nur durch eine 'break'-Anweisung verlassen, oder dadurch, dass die Schleifenbedingung nicht (mehr) erfüllt ist.

Ja, die hatte ich, dass war zumindest beim Z80 so. Kannst Du mir auch erklären, warum das so ist???

(Firma: Gast) #7552537
Lesenswert?

Michael schrieb:

ist Dir wohl entgangen, dass das ein Kommentar ist und in in der Anweisung PORTB steht.

Nein, mir ist da gar nichts entgangen!

Ich formuliere das mal so um, dass es jeder versteht:

Kein Kommentar, ist besser, als ein falscher Kommentar!

Falsche Kommentare haben nur einen einzigen Zweck, Sinn oder Aufgabe, sie sollen den Leser und vielleicht sogar den Autor selber ins Bockhorn jagen. Ich möchte nicht so verarscht werden, und ich möchte auch nicht dass sich der TO so selber verarscht.

Michael schrieb:

| ist Unterlassung aber unauffällig da Port trotzdem getoggelt wird ein Pin als Ausgang geschaltet ist. What now???

Der Pullup wird auch abgeschaltet, und damit endet die kontrollierte ISR Aufruferei. Datt is now!

OP #7552538
Lesenswert?

Steve van de Grens schrieb:

Rolf schrieb:

Es sind Endlos-Schleifen: while (Light_mode==0) { statt 'while' muss es 'if' heißen. :-))

Stimmt, Adlerauge sei wachsam!

also mit if funktioniert das, wie gewünscht. Das bedeutet nun wirklich, dass diese while-Schleifen nicht unterbrechbar sind. WEiß jemand warum das so ist???

Danke Euch allen. Wünsche einen fleißigen Weihnachtsmann. Michael

(Firma: Gast) #7552539
Lesenswert?

Michael schrieb:

Das bedeutet nun wirklich, dass diese while-Schleifen nicht unterbrechbar sind.

Natürlich sind sie unterbrechbar! break beendet eine Schleife (allerdings nur von innen, nicht von außen)

Michael schrieb:

Kannst Du mir auch erklären, warum das so ist???

Ja! Weil C und C++ so definiert sind, wie sie definiert sind. Es ist eine Spezifikation und kein "ich wünsch mir was"

Moderator (Firma: Titel) Persönliche Seite #7552555
Lesenswert?

Michael schrieb:

Das bedeutet nun wirklich, dass diese while-Schleifen nicht unterbrechbar sind.

Nochmal, weil es offenbar untergegangen ist: klar können die jederzeit unterbrochen werden, aber sie können eben durch diese Unterbrechungen nicht abgebrochen werden.

WEiß jemand warum das so ist???

Ja: weil es die Sprachdefinition so verlangt.

Und weil es zudem die alltäglich erlebte Logik nahelegt: ein "Interrupt" ist eben nur eine "Unterbrechung" und kein "Teminator", der jede aktuelle Tätigkeit abbricht. Nach einer "Unterbrechung" arbeitet der Prozessor dort weiter, wo er unterbrochen wurde.

Wenn du Milch koscht und der Postbote klingelt an der Tür, dann holst du schnellstmöglich das Einschreiben ab und siehst zu, dass du mit der Milch weitermachen kannst. Denn sonst könnte ja der Postbote den Pudding zur Nachspeise durch sein Klingeln vehindern.

Arduino F. schrieb:

break beendet eine Schleife

Sie könnten auch bei jedem Druchlauf ganz regulär abgebrochen werden, wenn einfach die Schleifenbedingung nicht mehr zutrifft.

(Firma: Gast) #7552556
Lesenswert?

Michael schrieb:

Wenn Du meinst, teste doch mal auf Deinem Digi den Script. Da wirst Du staunen.

Da gibts nichts zu testen! Vielleicht solltest du nochmal ins Datenblatt schauen und die C Operatoren = und ~ in der Sprachdoku nachlesen.

Michael schrieb:

PORTB=~PORTB;

Dort werden alle Bits im PORTB Register invertiert/getoggelt Und damit ist der Pullup an PB2 auch aus.

OP #7552590
Lesenswert?

Michael schrieb:

Das bedeutet nun wirklich, dass diese while-Schleifen nicht unterbrechbar sind.

Nochmal, weil es offenbar untergegangen ist: klar können die jederzeit unterbrochen werden, aber sie können eben durch diese Unterbrechungen nicht abgebrochen werden.

ok, dass war eine falsche Schlussfolgerung von mir.

ein "Interrupt" ist eben nur eine "Unterbrechung" und kein "Teminator", der jede aktuelle Tätigkeit abbricht. Nach einer "Unterbrechung" arbeitet der Prozessor dort weiter, wo er unterbrochen wurde.

stimmt, war wieder mein Gedankenfehler

Arduino F. schrieb im Beitrag #7552539: Sie könnten auch bei jedem Druchlauf ganz regulär abgebrochen werden, wenn einfach die Schleifenbedingung nicht mehr zutrifft.

Jetzt hab ich es gefressen. Meine While-Schleife wertet das Flag nicht aus und verbleibt. Ich müsste also die Variable Modus in der ISR inkrementieren, denn die wertet die While-Schleife aus.

Richtig???

#7552629
Lesenswert?

Michael schrieb:

@Michael Du scheinst die Vorstellung zu haben, mit einem Interrupt könne man Schleifen verlassen. Nein, kann man nicht. Eine Schleife kann man nur durch eine 'break'-Anweisung verlassen, oder dadurch, dass die Schleifenbedingung nicht (mehr) erfüllt ist.

Ja, die hatte ich, dass war zumindest beim Z80 so. Kannst Du mir auch erklären, warum das so ist???

Oh nein, das war nicht so. Und das war und ist todsicher bei keiner CPU so. Es ist eine Eigenschaft der Programmiersprache.

Übrigens hast du gesagt, du habest Z80 "in HEX-Code" programmiert. Da gibt es gar keine while-Schleifen und auch sonst keine Schleifen, die der Prozessor als solche erkennen kann.

(Firma: Gast) #7552638
Lesenswert?

Michael schrieb:

Daraus folgt aber nicht, dass die IR-Routine nicht aufgerufen wird.

Habe ich auch nicht behauptet!

Das sind meien Aussagen dazu: Arduino F. schrieb im Beitrag #7552502:

  1. damit stirbt der Pullup ab, und danach ist nix mehr mit kontrolliertem "rising"

Arduino F. schrieb:

Der Pullup wird auch abgeschaltet, und damit endet die kontrollierte ISR Aufruferei. Datt is now!

Da steht ausdrücklich nicht, dass keine rising ISR mehr kommen kann, sondern dass du und der Taster damit die Kontrolle über den Zeitpunkt verloren hast.

Natürlich kann ein floatender Pin jederzeit HIGH werden.

OP #7552661
Lesenswert?

Rolf schrieb:

Übrigens hast du gesagt, du habest Z80 "in HEX-Code" programmiert. Da gibt es gar keine while-Schleifen und auch sonst keine Schleifen, die der Prozessor als solche erkennen kann.

richtig, die mussten selbst gebaut werden. Denn einen Assembler geschweige denn eine IDE mit einer höheren Progranmmiersprache hatte ich nicht.

OP #7552667
Lesenswert?

Falk B. schrieb:

Michael schrieb:

Jetzt hab ich es gefressen. Meine While-Schleife wertet das Flag nicht aus und verbleibt.

Ja

Ich müsste also die Variable Modus in der ISR inkrementieren,

Nein. Du musst dein Software umstrukturieren.

Beitrag "Re: Interrupt ATtiny85 - Hilfe"

Ja, das wars. In der IR-Routine die Variable noch inkrementiert und schon geht alles. Ebenso wie die case-Variante als auch die if Variante.

Lothar M. (Firma: Titel) (lkmiller) (Moderator) hat mir auf die Sprünge geholfen.

Gast #7552707
Lesenswert?

Was das Unterbrechen der while Schleife angeht, habt ihr die Frage von Michael offenbar missverstanden. Ich zitiere nochmal den relevanten Code:

1
ISR(INT0_vect) {
2
  Button_event=true;
3
  ...
4
}
5

6
int main(void) {
7
  ...                           
8
  while (1) {
9

10
      if (Button_event==true) {
11
        Button_event=false;
12
        Light_mode++;
13
      }
14

15
      ...
16

17
      while (Light_mode==0) {
18
         ...
19
      }
20

21
      while (Light_mode==1){
22
         ...
23
      }
24

25
      while (Light_mode==2) {
26
         ...
27
      }
28

29
      while (Light_mode==3)  {
30
         ...
31
      }   
32
    }
33
}

Mit ungewollten "Endlosschleifen" meinte Rolf die inneren while Schleifen für die vier Licht-Modi.

Michael ist der Meinung, dass die Schleifen nur solange laufen, wie der jeweilige Licht-Modus gewählt ist. Sobald man den Licht-Modus ändert, wird die gerade laufende while Schleife verlassen und die nächste while Schleife für den nächsten Licht-Modus ausgeführt. Zumindest was das sein Plan.

Der Knackpunt ist, dass jedoch nichts den Licht-Modus ändert, während eine der vier inneren Schleifen läuft. Zwar gibt es eine ISR, die auf Tastendruck reagiert. Diese ändert aber nur die Variable Button_event und nicht Light_mode.

Wenn die ISR den Light_mode ändern würde, dann würde es wie gewünscht funktionieren. Etwa so:

1
ISR(INT0_vect) {
2
  Light_mode++;
3
  ...
4
}
5

6
int main(void) {
7
  ...                           
8
  while (1) {
9
      while (Light_mode==0) {
10
         ...
11
      }
12

13
      while (Light_mode==1){
14
         ...
15
      }
16

17
      while (Light_mode==2) {
18
         ...
19
      }
20

21
      while (Light_mode==3)  {
22
         ...
23
      }   
24
    }
25
}

Die Variable, die innerhalb der ISR geändert wird und außerhalb der ISR gelesen wird sollte volatile sein. Ansonsten kann es passieren, dass der vom Compiler erzeugte Code die Variable in einem Register cached und dann Änderungen im RAM durch die ISR gar nicht mit bekommt:

1
ISR(INT0_vect) {
2
  Light_mode++;
3
  ...
4
}
5

6
int main(void) {
7
  ...        
8

9
  R5 = Light_mode                   
10
  while (1) {
11
      while (R5==0) {
12
         ...
13
      }
14

15
      while (R5==1){
16
         ...
17
      }
18

19
      while (R5==2) {
20
         ...
21
      }
22

23
      while (R5==3)  {
24
         ...
25
      }   
26
    }
27
}

Der Compiler macht das, weil Zugriffe auf Register schneller sind, als Zugriffe auf RAM. Leider ist der Compiler so "dumm", nicht zu berücksichtigen, dass Light_mode verändert wird während main() läuft. Er liest die Speicherzelle nur einmal und benutzt dann wiederholt das schnellere Register R5.

Volatile ist eine einfache Holzhammer Methode, den Compiler dazu zu zwingen, jeden schreib- und Lesezugriff sofort im RAM auszuführen. Also nicht in einem Register zu cachen.

Die Registernummer sei hier nur ein Beispiel. Der Compiler kann dafür jedes beliebige freie Register verwenden. Man sieht das ggf. im Assembler-Listing.

#7553250
Lesenswert?

Michael schrieb:

Ja, die hatte ich, dass war zumindest beim Z80 so. Kannst Du mir auch erklären, warum das so ist???

Das bezweifle ich mal stark, daß Interrupts beim Z80 das blanke Chaos hinterlassen. Im Gegenteil, die CPU sichert den Status soweit, daß sich Seiteneffekte auf die unterbrochenen Programmteile vollständig vermeiden lassen. Dazu wurden auch PUSH/POP implementiert, damit keine Register zerstört werden. Nach einem Interrupt wird also genau da weiter gemacht, wo die Unterbrechung erfolgte.

In C kann man jedoch mit setjmp/longjmp einen Abbruch erzwingen. Aus guten Grund sind das aber mit Abstand die am seltensten benutzten Funktionen, da man genau wissen muß, was man tut.

#7553310
Lesenswert?

Steve van de Grens schrieb:

Leider ist der Compiler so "dumm", nicht zu berücksichtigen, dass Light_mode verändert wird während main() läuft.

Das ist nicht "leider dumm", sondern das Konzept von C/C++: Möglichst effizient sein.

Solche Veränderungen können ja auch in einer anderen Quelldatei vorkommen. Um das sicher zu erkennen, müsste der Compiler grundsätzlich immer die Inhalte aller Quelltexte beachten. Das wäre aufwendig und würde trotzdem nicht immer gut funktionieren, weil der Compiler die zeitlichen Abläufe nicht erkennen kann und deswegen auf Verdacht zu vorsichtig sein müsste. Das Compilieren würde also unnötig langsam, und das Compilat würde unnötig ineffektiv.

Außerdem kann der Compiler nur Quelltexte beachten, die er kennt. Die von vorübersetzten Libs (womöglich in anderen Sprachen) kennt er aber u. U. gar nicht.

#7553344
Lesenswert?

Falk B. schrieb:

Wenn das Programm sonst nichts zu tun hat, dann brauchts auch keinen Interrupt für einen Taster.

Doch, wenn man Strom sparen will und keinen extra Hauptschalter einbauen will.

Dann würde ich in diesem Fall zwar einen Interrupt auf den Taster setzen, aber die Interrupt-Routine leer lassen und alles in der Hauptschleife machen:

set_sleep_mode(SLEEP_MODE_PWR_DOWN); while(true) { sei(); sleep_cpu(); doAll(); } Wäre einfacher/übersichtlicher und kürzer.

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