www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik mit Interrupt Variable verändern


Autor: Eugen V. (eugen_v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, wie kann ich eine globale Variable mit Hilfe eines Interrupts 
veränder, diese soll auch nach dem das Interrupt beendet ist den neuen 
wert behalten?
Und wieso dauert die Abarbeitung des Interrupts ca 1-2 Sekunden?


Mein Code


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

unsigned char level;


void Init_Interrupt()  {
GICR|=(1<<INT0);
MCUCR = (1<<ISC01) | (0<<ISC00);
sei();
}

ISR(_VECTOR(1))
{ cli();
_delay_ms(50);
level++;
PORTB=~level;
  sei();
}





int main() {

  unsigned char i;
  level = 0;
  Init_Interrupt();


while(1)  {

switch(level)  {
case 1:  {
............
break;
case 2:
.........
break;

default  :{
level = 0;
...
}

...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>unsigned char level;

volatile unsigned char level;

ISR(_VECTOR(1))
{ cli();          //rausschmeissen
_delay_ms(50);    //Igitt!
level++;
PORTB=~level;
  sei();          //rausschmeissen
}

Autor: Eugen V. (eugen_v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke, habs gerade auch im net gefunden :)

habe aber noch eine Frage.
Wieso dauert die Bearbeitung des Interrupts ca. 1-2 Sekunden?
Mein Code


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

unsigned char level;


void Init_Interrupt()  {
GICR|=(1<<INT0);
MCUCR = (1<<ISC01) | (0<<ISC00);
sei();
}

ISR(_VECTOR(1))
{
level++;
}





int main() {

  unsigned char i;
  level = 0;
  Init_Interrupt();


while(1)  {

switch(level)  {
case 1:  {
............
break;
case 2:
.........
break;

default  :{
level = 0;
...
}

...

Autor: Eugen V. (eugen_v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es ist eher so dass nach dem interrupt das Hauptprogramm erst nach einer 
Verzögerung (ca. 1-2 Sekunden) weiter läuft.
Wie kann man Taster bei einem Interrupt entprellen (ohne 
_delay_ms(...))?

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eugen V. schrieb:
> es ist eher so dass nach dem interrupt das Hauptprogramm erst nach einer
> Verzögerung (ca. 1-2 Sekunden) weiter läuft.

Dem ist sicher nicht so, wenn Deine obige Interrupt-Routine mit der 
Wirklichkeit übereinstimmt.  Du suchst an der falschen Stelle.

Autor: Wolfgang Mües (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Eugen,

was hältst Du davon, dem Vorschlag von Holger zu folgen und die Variable 
"volatile" zu deklarieren?

Damit sagst Du dem Compiler, dass er nicht annehmen darf, dass die 
Variable den gleichen Wert behält, wenn er sie im Programmablauf nicht 
selbst verändert. Also muss er sie immer wieder neu aus dem Speicher 
laden, wenn er den aktuellen Inhalt haben will.

Ist eine Variable nicht volatile, dann optimiert der Compiler alle 
Zugriffe auf die Variable außer dem ersten weg. Und wenn sich dann eine 
Schleife als bedeutungslos herausstellt, wird sie gleich mit 
wegoptimiert.

Gruß

Wolfgang

Autor: Eugen V. (eugen_v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>was hältst Du davon, dem Vorschlag von Holger zu folgen und die
>Variable "volatile" zu deklarieren?

Das habe ich gemacht, habe leider vergessen es hier rein zu kopieren.

Autor: Namenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie kann man Taster bei einem Interrupt entprellen (ohne _delay_ms(...))?

Ich versuche mal eine Übersetzung: Du hast einen Taster an einem Pin 
(Input, Pullup/-down Widerstand, Taster gegen Ground/Vcc), und wenn man 
jenen Drückt, dann soll entprellt werden, sodass Du den Tastendruck 
eindeutig erkennen kannst?

Falls das soweit stimmt: Entprellung

Hierzulabor bevorzuge ich die Hardwareentprellung mit 1u und 15k, alles 
andere braucht (hier, für mich, und nur für mich gültig) zu viele 
Ressourcen, die anderweitig sinnvoller einzusetzen sind. Falls Du den µC 
hinreichend überdimensioniert hast, dann spricht nichts gegen eine 
Softwareentprellung. Die Details gibbet im Link :-)

HTH

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Namenlos schrieb:
> Falls Du den µC
> hinreichend überdimensioniert hast, dann spricht nichts gegen eine
> Softwareentprellung.

Das ist Quatsch, da muß man überhaupt nichts überdimensionieren.

SW-Entprellung braucht max 4Byte SRAM, etwa 50Byte Code und kleiner 1% 
CPU-Leistung.


Peter

Autor: 12er Dude (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eugen,

> es ist eher so dass nach dem interrupt das Hauptprogramm erst nach einer
> Verzögerung (ca. 1-2 Sekunden) weiter läuft.

wenn ich es richtig sehe, wird die ISR bei jedem Pegelwechsel 
angesprungen. Ein prellender Taster erzeugt reichlich Interrupts und die 
Variable wird häufiger inkrementiert, als Du eigentlich wünschst.

Tschü Dude

Autor: Namenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> SW-Entprellung braucht max 4Byte SRAM, etwa 50Byte Code und kleiner 1%
> CPU-Leistung.

Ahja, und wo nimmst Du 4 Bytes SRAM und und 50 Bytes Flash her, wenn Du 
nix mehr übrig hast? Genau, du nimmst einen Controller, der hinreichend 
groß ist, vulgo einen größeren, als (ursprünglich) nötig. Mithin nennt 
man das 'überdimensionieren'.

Ganz abgesehen von der Tatsache, dass man, ohne den CPU-Takt zu kennen 
(hat der TO was dazu geschrieben? falls ja dann hab ichs wahrscheinlich 
überlesen), lieber gaanz kleine Brötchen backen sollte. Ich hab hier 
z.B. einen Controller, der läuft mit knapp 1000Hz (ja, eintausend Hertz, 
nicht Kilo- und nicht Mega-, einfach nur Hertz). Da tut jeder 
vermeidbare ISR-Aufruf richtig weh. Von vergeudeten (Hardware)Timern 
ganz zu schweigen.

Wie immer heisst die Devise: Der mündige Entwickler muss selbst 
entscheiden (jaja, ich weiss genau, was jetzt kommt: 'Die böse 
PR/Chefetage/Kosten-Leistungs-Vergleich/.. lässt mich nicht 
entscheiden'. Nixdan, wir sind hier im Hobbybereich, und da darf jeder 
mündige Entwickler eigene Entscheidungen treffen :-) was er braucht. Und 
anhand der gewünschten Ziele und der verfügbaren Hardware darf er dann 
eine Entscheidung treffen.

★Mir★ kommt keine Softwareentprellung ins Haus, weil ★ich★ mich als 
mündiger Entwickler bewusst für die Hardwareentprellung entschieden hab. 
Bei meinem nächsten Projekt sieht das möglicherweise ganz anders aus, 
aber da werde wieder ★ich★ entscheiden. Wenn ein anderer Entwickler was 
an ★seinem★ Projekt anders entscheiden will, dann nur zu. Wie so oft 
kann man nämliche keine allgemeingültige Antwort geben, was nun besser 
ist - der Kontext ist entscheidend. Reinzupflaumen
> Das ist Quatsch
ist jedenfalls völlig unangebracht.

Autor: Eugen V. (eugen_v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Beiträge, jetzt läufts auch :)

Fand nur den letzten Beitrag leicht übertrieben :) Aber jedem das Seine!

Autor: Namenlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1kHz (ich muss mich übrigens korrigieren: etwas über 1kHz, nicht knapp 
1kHz..) ist ziemlich krass, ich weiss :-) Aber der Zweck 
heili^W^W^Wwenns anders nicht geht, dann muss mans nehmen, wies kommt.. 
:-) Wenn andererseits genug Ressourcen vorhanden sind (vulgo: 
hinreichend überdimensioniert ;-) dann spricht nix gegen 
Softwareentprellung.

HTH und HF

Autor: asdf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Datentyp "int" >8 bit ist (bei AVR ist er normalerweise 16 
bit), dann erfolgen die Lesezugriffe in main nicht atomar, da der 
Prozessor immer nur 8 bit auf einmal verarbeiten kann. Der Vergleich im 
case wird daher z.B. zuerst das obere Byte und danach das untere Byte 
vergleichen und wenn beide gleich sind zum Ausführen der zugehörigen 
Anweisungen führen.

Wenn dieser Ablauf zufällig durch einen Interrupt unterbrochen wird 
können unerwartete Effekte auftreten. War der Zähler z.B. 255 und es 
erfolgt ein Vergleich auf 0 könnte es so ablaufen:
- high-byte wird verglichen, passt (beide 0)
- Interrupt erhöht den Zähler auf 256
- low-byte wird verglichen, passt (beide 0)
=> das high-byte ist zwar inzwischen 1, wird jedoch nicht nochmal 
verglichen

D.h. bei Datentypen >8bit auf einem 8-bit-Prozessor die in 
Interruptroutinen verändert werden können muss (bis auf wenige 
Ausnahmen, in denen man ganz genau wissen muss was man tut...) vor dem 
Auswerten im Hauptprogramm eine Interruptsperre erfolgen, die danach 
wieder aufgehoben werden kann. Man kann auch (wenn es der 
Verwendungszweck zulässt) einfach eine Kopie unter Interruptsperre 
erstellen und dann mit dieser Arbeiten.

Alternativ wäre der Einsatz von 8-bit-Datentypen möglich, aber auch hier 
muss man etwas aufpassen, z.B. bei if((i>8)&&(i<7)) sollten die 
folgenden Anweisungen eigentlich nie ausgeführt werden, aber was, wenn i 
zuerst 9 war und mitten in der Prüfung auf 6 geändert wurde...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.