www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tim. Inter. soll Buchstaben im Wechsel anzeigen


Autor: Mirko Kamm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche ein einfaches Programm zu schreiben mit dem
Ziel, dass im 3 Sekunden Abstand jeweils ein "F" und ein "K"
angezeigt werden soll. Eigentlich recht simpel.

        LCD Anzeige:        "F"
        3 Sekunden warten
        LCD Anzeige:        "K"
        3 Sekunden warten
        LCD Anzeige:        "F"
        usw.....

Zum Timerverständnis habe ich schon LEDs in 1 Sekunden Takt blinken
lassen, realisiert mit einem Timer Overflow bzw. auch mit einem
TimerCompare Match.

Mein Problem:

Wie schaffe ich es, das Programm so zu gestalten, dass in der Timer
Interrupt Routine erkannt wird,
welcher Buchstabe gerade angezeigt wird? Ich will keine Code Beispiele,
sondern ein Tip. Ich habe mal
gehört, dass in einer Interrupt-Routine selbst so wenig Aktion wie
möglich sein sollte.

Prozessor: AVR
Sprache: Assembler
Software: AVR Studio

Danke für eure Tips.

MFG

Mirko

Autor: Reiner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mirko,

Im Timerinterrupt einfach ein bit togglen ( 0-1-0-1...)

Ausserhalb des Interrupthandlers:
Wenn bit gesetzt:  LCD Anzeige "F"
ansonsten LCD Anzeige "K"

Der Interrupthandler braucht ja nicht zu wissen welcher Buchstabe
gerade angezeigt wird.  Er soll den Takt liefern.

Reiner

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich organisiere inzwischen alle meine Programme so, dass sie durch
einen Timer synchronisiert werden. Das heißt, dass die Mainloop mit all
ihren Unterprogrammen nach getaner Arbeit in den Sleep fällt und "die
nächste Runde" erst nach einem weiteren Interrupt (meist Timer)
absolviert.

Wenn auch andere Interrupts genutzt werden, dann setzt der
Timer-Interrupt ein Flag, das von der Mainloop zur Verzweigung genutzt
wird. Somit wird der "getaktete Teil" der Mainloop im genau
definierten Zeitraster aufgerufen und kann auch Zeitmessaufgaben
übernehmen.

Soll nun, wie in deinem Fall, in einem definierten Zeitabstand eine
Aktion stattfinden, so nimmt man eine Variable (Register, Hilfsregister
und SRAM-Zelle) als Software-Timer, indem man sie (in jeder "Runde")
hoch bzw. runter zählt und bei Erreichen des Zählumfangs wieder auf
Startwert setzt und die Aktion auslöst.

Sollen wechselweise verschiedene Werte ausgegeben werden, dann muss man
sich den zuletzt ausgegebenen Wert merken und danach beim nächsten mal
bestimmen, welcher Wert jetzt an der Reihe ist. Da LCDs meist im
WriteOnly-Mode betrieben werden, ist ein Zurücklesen des zuletzt
geschriebenen Zeichens meist nicht möglich. Also muss man sich das
Zeichen in einer Variablen (Register oder SRAM) merken.

Wenn das Zeichen immer an die selbe Stelle des LCDs soll, dann muss die
Ausgabeposition des LCDs auch jedesmal neu gesetzt werden.

Du wolltest zwar keinen fertigen Code, darfst aber gerne mal bei
www.hanneslux.de/avr/ nachschaun, wie ich das gemeint habe. In den
Projekten Stoppuhr und Zünduhr dürftest du fündig werden.

...

Autor: Mirko Kamm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

dass bedeutet also, dass wenn ich eine sich im 3 Sekunden Abstand
ändernde reele Zahl anzeigen lassen will (Temperatur),
dann muss ich mir mal Deine Routine anschauen Hannes.

MFG

Mirko

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dass bedeutet also, dass wenn ich eine sich im 3 Sekunden Abstand
> ändernde reele Zahl anzeigen lassen will (Temperatur),
> dann muss ich mir mal Deine Routine anschauen Hannes.

Neee... - Denn da wird keine Temperatur alle 3 Sekunden angezeigt 8D

Aber da werden laufende Zeiten und andere Informationen im festgelegten
Zeitraster angezeigt, woran du nachvollziehen kannst, was ich mit meiner
Beschreibung meinte.
Es geht dabei mehr um das Grundkonzept eines Programms als nur um die
Anzeige im bestimmten Zeitraster. Wenn nämlich dieses Grundkonzept
schon eine solide Zeitbassis zur Verfügung stellt, braucht man nicht
für jede zeitabhängige Aktion einen eigenen Timer oder sogar eine
Warteschleife, sondern man ruft diesen Programmteil eben in einem
gröberem Zeitraster auf. Dabei lässt man diesen Teil "links liegen"
wenn er in der aktuellen "Mainloop-Runde" nicht an der Reihe ist. Die
Steuerung, wann jeder Teil an der Reihe ist, wird von einfachen
Variablen übernommen, Z.B. BOOLschen Variablen (Flags in einem
Register, Tastenflags der Entprellroutine) oder Zählregister. Somit
wird an keiner Stelle im Programm gewartet (Warteschleife), sondern der
betreffende Teil einfach übersprungen. Dies spart Rechenzeit, die man am
Ende der Mainloop durch Sleep wieder "entsorgen" kann... ;-)

Spaß beiseite, durch das Vermeiden von Wartezeiten erreicht man eine
dermaßen schnelle Abarbeitung der einzelnen Programmteile, dass der
Eindruck entsteht, der Controller würde im Multitasking-Betrieb
arbeiten. Da dies durch LCD-Routinen mit Warteschleife ausgehebelt
werden würde, habe ich die LCD-Ausgabe inzwischen auf
Ringbuffer-Betrieb umgestellt. Das eigentliche Programm schreibt die
Ausgabetexte und die Positionierung einfach nur in den Ringbuffer. Ein
Timer-Interrupt setzt dann alle etwa 1ms ein Flag, worauf die Mainloop
die Ausgabe eines Zeichens aus dem Buffer veranlasst. Im
Stopuhr-Projekt übernimmt die LCD-Routine sogar die Ausgabe auf UART,
was die gesamte Ausgabeprogrammierung total vereinfacht. (Jedes
Locate-Macro schaltet auf LCD um, jedes Schreiben einer $01 schaltet
auf UART um, womit alle Print-Macros wahlweise auf LCD oder UART wirken
können.)

Schau es dir ruhig mal an, denn mit diesem Programmierkonzept werden
viele Probleme leichter lösbar. Schau auch mal unter Beispielprogramme,
da wird das Grundkonzept an einem sehr kleinen Programm für ATtiny15
erläutert.

...

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn eine Funktion bei jedem Durchluaf verschiedene Sachen machen soll,
setzt man einen Zähler (Variable) auf, erhöht ihn bei jedem Durchlauf
und entscheidet daran, was als nächste zu tun ist. Solls wieder von
vorne anfangen, setzt man sie auf 0.

Bei der Ausgabe verschiedener Zeichen ist dieser Zähler z.B. der Index
in einem String:
unsigned char zaehler;
unsigned char text[] = "FK";

void print_next( void )
{
  if( text[zaehler] == 0 )      // == 0 ?
    zaehler = 0;                // von vorne
  printchar( text[zaehler] );   // Zeichen ausgeben
  zaehler++;                    // weiterzaehlen
}


Peter

Autor: Mirko Kamm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs,

vielen Dank für eure Hilfe,
werde mich heute abend mit diesen Infomationen
auseinandersetzen.

MFG

Mirko

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.