www.mikrocontroller.net

Forum: Compiler & IDEs Zu blöd für Interrupt an Atmega32


Autor: Chris G. (chris_g)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend zusammen.
Ich brauche dringend einen frischen Denkansatz für mein Problem,
darum hoffe ich auf Hilfe durch dieses Forum, bzw. seine Nutzer.

Folgendes Problem raubt mir seit drei Tagen den letzten Nerv und
ich glaube, ich habe mich da etwas verfahren. Jedenfalls finde ich 
selber keine Lösung.

Es geht um eine Temperaturregelung.
Eine Temperatur wird eingelesen, mit einem Sollwert verglichen und 
anhand dessen ein Regelungsvorgang vollzogen.

Grundsätlich wird die Regelung nur über zwei Taster bedient:
Solltemperatur "Auf" und "Ab".
Soll- und Ist-Wert werden über ein LCD-Display ausgegeben.

Bei einem Tastendruck auf die Tasten "Auf" oder "Ab" wird ein Interrupt
ausgelöst, der den µController aus der Regelschleife holt und den 
Sollwert
inkrementiert bzw. dekrementiert. Danach geht's wieder in die 
Regelschleife.

Als Testplatform nutze ich hier ein STK500 und einen Atmega32.
Auf meiner Fehlersuche habe ich das Programm bereits soweit abgespeckt, 
daß eigentlich nur noch die Interruptfunktion für einen Taster über ist,
die primitiver Weise den LED-Block des STK500 Board löschen soll.

Aber trotz des reduzierten Codes begreife ich nicht, was ich falsch 
geschrieben habe. Evtl. liegt hier ein "Man sieht den Wald vor lauter 
Bäumen nicht"-Effekt vor, weil ich schon zu lange an diesem Fehler 
arbeite.

Jedenfalls möchte ich mich jetzt schonmal bedanken,
falls sich jemand die Mühe macht, mit mir zu grübeln und mir zu helfen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht noch die Register GICR und ggf. MCUCR passend setzen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris G. schrieb:

> Aber trotz des reduzierten Codes begreife ich nicht, was ich falsch
> geschrieben habe.

Du musst den INT0 schon auch noch freigeben. Im Moment sind zwar 
Interrupts gnerell freigegeben, aber die spezifische Freigabe des INT0 
ist nicht vorhanden.

Aber eigentlich ist das sowieso keine gute Idee, Taster über einen 
Interrupt Eingang auszuwerten. Die bessere Variante sind die 
Komfort-Taster Entprellroutinen, die über einen Timer Interrupt die 
Taster pollen und gleichzeitig entprellen

*) sie funktionieren wesentlich besser, egal wie stark die Taster
   prellen
*) durch die Autorepeatfunktion ermöglichen sie auch komfortable
   Eingaberoutinen, ohne dass sich der Benutzer an den Tasten einen
   Wolf drückt.
*) Sie sind einfach in der Verwendung

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

Autor: Torsten K. (ago)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem 1: Du hast nicht geschrieben, wo du jetzt eigentlich ein Problem 
hast :-)

Problem 2: Tastenabfrage im Interrupt ist - zumindest ist das die 
Meinung hier im Forum - ein großes "No Go!"

Entprellung ist hier das Stichwort (such mal im Forum nach "Entprellung 
in Software"

Das was ich alleine an Deinem Codeschnipsel sehe ist folgendes:

- Ein Interrupt wird ausgelöst, "keypressed" wird gesetzt
- Hauptschleife fragt "keypressed ab uns setzt keypressed auf 0
- Tastenprellen löst weiteren Interrupt aus und setzt keypressed wieder 
auf 1 ;-)

Ein Ansatz wäre zum Beispiel, die Tastatur regelmäßig im Timerinterupt 
abzufragen, z.B. (Pseudocode)


// Beispiel: 4 Tasten an Port D, Bit 0-3
static uint8_t keypressed[3], keydebounce[3];

ISR(...)  /* aufruf alle 10ms */
{
  uint8_t i;
  for (i=0; i<=3; i++)
  {
    if (PIND & 1<<i)
    {
      if (keydebounce[i]++ == 10)   /* nach 0.1s wird Taste erkannt */
        keypressed[i]++;
      if (keydebounce[i] > 80)
        keydebounce[i] = 0;
    }
    else
      keydebounce[i] = 0;
    /* Alternative: oder keydebounce[i] = keypressed[i] = 0 */
  }
}

hiermit wird alle 0.8+0.1 = 0.9 Sekunden ein Tastendruck erkannt 
(auto-repeat). Du könntest sogar im Hauptprogramm 5 Sekunden schlafen 
und würdest nun in keypressed[i] entsprechend der Dauer des Tastendrucks 
eine "5" vorfinden

im Hauptprogramm fragst du nun nur keypressed[x] ab:

..
if (keypressed(0)
{
   x = x + 1;    /* oder x = x + keypressed(0); */
   keypressed(0) = 0;
}

Mit dem "Alternativen" Codeschnippsel würde die Interruptroutine bei 
Loslassen auch den Taste-gedrückt-Code löschen, falls also das 
Hauptprogramm noch nicht dazu gekommen wäre keypressed[0] auszuwerten 
würde es nichts tun.

Just my 2 cent

PS: Ich kriege - auch mit 3 Glas Rotwein intus - jedes mal Augenkrebs 
wenn ich "LCD-Display" lese ;-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nimm noch ein paar und es wird besser. :-)

PS: Gute Idee, prost!

Autor: Torsten K. (ago)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten K. schrieb:
> if (keypressed(0)
> {
>    x = x + 1;    /* oder x = x + keypressed(0); */
>    keypressed(0) = 0;
> }

Es muß latürnich

if (keypressed[0])
{
  x++;  /* oder: x = x + keypressed[0]; */
  keypressed[0] = 0;
}

heißen... und statt static eventuell volatile ;-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten K. schrieb:
> und statt static eventuell volatile ;-)

oder beides

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.