mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zugriff auf eine "volatlie" Variable aus zwei verschiedenen Interrupts möglich?


Autor: Variable aus zwei versch. Interrupts (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, vielleicht könnt ihr mir weiterhelfen.

Ich habe ein Programm für einen ATmega32 geschrieben, das auf der 
Drehencoder-Routine von Deter Dannegger beruht (hier aus der 
Codesammlung). Das einlesen der 4 Drehencoder die ich an Port A 
angeschlossen habe, funktioniert auch prima.

Jetzt zu meinem Problem: Das einlesen der Drehencoder erfolgt über den 
Timer-Overflow-Interrupt mit Timer0 (ca. 7 KHz).

Die Ausgabe der zweistelligen Zahl erfolgt mit 7-Segment-Anzeigen, von 
denen habe ich ingesamt vier Paare (Also viermal eine zweistellige 
Anzeige) die an Port C parallel angeschlossen sind. Die 
7-Segment-Anzeigen werden durch einen BCD-to-7 Segment Treiber/Latch 
angesteuert. Die Parallelen Anzeigen werden über den Latch-Eingang des 
4543 gemultiplext der auf Port B liegt.

Da es ja aber schwachsinn ist, das multiplexen mit 7 Khz zu machen, hab 
ich einen zweiten Interrupt über Timer2 realisiert, der mit 200 Hz 
arbeitet.

Das Problem: wenn ich den zweiten Interrupt benutze werden auf den 
Anzeigen nur noch Nullen angezeigt, die durch Drehen nicht verändert 
werden. Die einzige Variable im zweiten Interrupt ist die counter1_high 
und counter1_low, die ich als global und volatile deklariert habe. Diese 
wird in der ersten Interruptroutine geschrieben und in der zweiten nur 
gelesen. Mach ich da irgendwo nen Denkfehler?

Wenn ich das setzen der Anzeigen mit in die erste Routine packe wird 
alles so angezeigt wie es soll.

Ich weiß nicht mehr weiter!

Vielen Dank für alle Antworten!
MfG Matthias

Autor: aaa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Updaten eines Displays mit 7kHz ist Unsinn. Eine zweiten Timer zu 
verblasen ist auch Unsinn. Einfacher waere es das Dasplay im Ersten zu 
machen, aber zb nur jedes 1000. Mal.

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht vielleicht besser, wenn du auch beide interrupts aktivierst 
;)
  TCCR0 = 1<<CS01;      //divide by 8 * 256
  TIMSK = 1<<TOIE0;      //enable timer interrupt
  
  TCCR2 = (1<<CS22) | (1<<CS21);  /*Timertakt= CPU-Takt/256 (nochmal
                  durch 256 wegen 8-Bit Timer, ist Freq. der Anzeige)*/
  TIMSK = (1<<TOIE2);         //Enable Timer Interrup
//      ^ Hier wird der erste Timer interrupt wieder abgeschaltet
//    '|=' waere besser

hth, Jörg

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aaa wrote:
> Das Updaten eines Displays mit 7kHz ist Unsinn.

Was er schon selber sagte.


> Eine zweiten Timer zu
> verblasen ist auch Unsinn.

Nein, ist es beim AVR nicht. Der hat ja keine Interruptprioritäten.
Wenn der 2. Timer-Handler länger braucht, könnte der 1. Handler 
Überläufe verlieren.
Man müßte dann tricksen (SEI im Interrupt), was gefährlich sein kann.
Daher ist ein 2. Timer durchaus sinnvoll, wenn er noch frei ist.


Peter

Autor: oha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein BCD ueber parallellatch anzusteuern braucht ja praktisch keine Zeit, 
solange man keine Float umrechnung vorschaltet. Vernuenftigerweise hat 
man die Werte im Main aufbereitet, sodass der Timerinterrupt nur noch 
laden muss.
Zwei konkurrierende Timer ersetzt man besser durch eine Statusmaschine 
im Timer.

Autor: "10indahose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>"Deter Dannegger"
lol :D

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Nein, ist es beim AVR nicht. Der hat ja keine Interruptprioritäten.
> Wenn der 2. Timer-Handler länger braucht, könnte der 1. Handler
> Überläufe verlieren.
> Man müßte dann tricksen (SEI im Interrupt), was gefährlich sein kann.
> Daher ist ein 2. Timer durchaus sinnvoll, wenn er noch frei ist.


Ist natürlich quatsch, was ich da geschrieben habe.
Der 2.Timer ändert kaum was.

Wenn ein Interrupt zu lange dauert, ist wurscht, ob er sich selber 
blockiert oder nen anderen.
Daher lange Sachen beim AVR möglichst im Main machen.


Peter

Autor: Matthias (natürlich) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh man, danke leute. Ist schon ganz schön doof, wenn man copy and paste 
macht ohne die zu schreibenden Registerbits zu ändern.
Ich hab noch eine weitere Frage: Das hier sollte erstmal eine primitive 
Grundversion sein, die genau das ermöglicht was ich geschrieben hab.

Ich hab auch schon über verbesserungen nachgedacht, da der erste 
Interrupt ja doch ziemlich "lang" ist. Auf der anderen Seite braucht die 
Drehencoder-Auswertung auch nicht öfter laufen, und soo kompliziert ist 
die ja auch nicht
(Dank PETER (sorry, war noch etwas fertig vorhin), großes kompliment 
dafür. Hat zwar augenblick gedauert bis so ein Anfänger wie ich das 
kapiert hatte, aber im endeffekt ist es Genial. Vielleicht solltest du 
noch mal erwähnen das der Code für drehencoder ist die pro "Raste" nur 
zwei wechsel haben. war schwer für mich den Fehler und die Behebung zu 
finden da ich einen mit 4 Zuständen hab.)

Könnte man nicht nur mit dem Interrupt die Eingänge sozusagen 
"kontrollieren" ob sich da was geändert hat, und nur dann die 
Einleseroutine laufen lassen?

In einer vorigen version hatte ich die "nebenberechnung" der counter 
(>23, <0), counter_high und counter_low variablen im Hauptprogramm 
gemacht, was ja aber auch blödsinn ist, weil die ja gar nicht so oft 
geändert werden!

Demnächt soll da noch ein externer Interrupt rein der dann die counter 
inhalte über USART verschickt. Das sollte doch ohne probleme gehen oder?

Hat irgendwer noch gröbere Schnitzer gefunden? Oder 
optimierungsvorschläge?

Trotzdem schon mal vielen Dank für die schnellen Antworten hier.
Mathhias

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.