Hallo,
ich suche nach einer Anregung oder Lösungsansatz zu folgendem "Problem".
Ein Bestandteil meines derzeitiges "Projektes" ist es eine
Countdown-Zeit vorzuwählen, diese auf einem LCD auszugeben und
anschließend mit ISR runterzählen zu lassen.
Ich habe es auch soweit realisiert, dass ich mttels Poti an ADC7(PA7)
eine Zeit zwischen 0 und 15 Minuten vorwählen kann und diese auf dem LCD
ausgebe.
Der Start des Countdown wird dem Controller dann mittels Tasterdruck
signalisiert, in Folge dessen Timer 2 initialisiert wird und die Zeit
runtergezählt wird.
Die ermittelte Countdown-Zeit wird aus dem ADC Wert errechnet und
mittels
dtostrf gewandelt und an mein LCD (4Bit Modus ohne R/W) nach der LCD
Routine aus dem hiesigen Tutorial( lcd_string(...); ) übergeben.
Timer 2 initialisiere ich wie folgt:
void timer_an(void)
{
TCCR2|=(1<<CS22); // Vorteiler 64
TCNT2 = 0x00;
TIMSK|=(1<<TOIE2);
}
ISR des Timer 2
ISR (TIMER2_OVF_vect)
{
ovf++;
TCNT2=0;
}
mein Systemtakt ist 7,3728MHz bei 450 OVFs sollte 1 Sekunde vergangen
sein?!
Im Hauptprogramm übergebe ich den Inhalt von ovf an eine andere Variable
und verringere nach einer Sekunde in einer if Schleife den Wert der
Variablen für die Sekundenanzeige um 1 und wandel ihn erneut mit
dtostrf, um den vermeindlich aktualisierten Wert erneut auszugeben.
Leider tut sich auf meinem Display rein gar nichts.
Habe Momentan keinen Ansatz wo der Fehler stecken könnte. Muss ich
womöglich den Wert der im string aufs Display ausgegeben wurde, erst
mittels atol oder ähnlichem zurückwandeln, um ihn dann verändern zu
können oder stimmt was mit dem Timer nicht?
Vielen dank im Voraus für eure Antworten.
Michel Schl. schrieb:> Muss ich> womöglich den Wert der im string aufs Display ausgegeben wurde, erst> mittels atol oder ähnlichem zurückwandeln, um ihn dann verändern zu> können oder stimmt was mit dem Timer nicht?
Nein du musst nichts zurückverwandeln. Neuen Wert in String und aufs LCD
ausgeben reicht.
Wo wird dein Wert an das LCD ausgegeben? Ist deine Zählvariable
volatile?
Aber ohne den ganzen Code wirds nix.
gruß cyblord
Hallo ...
meine Zählvariable in der ISR ovf ist volatile.
Hab mir "spaßenshalber" mal in einer neuen Zeile des LCDs die Variable
ausgeben lassen, an die ich volatile unsigned int ovf im Hauptprogramm
übergebe bzw. in die ich sie kopieren diese ist unsigened int tc.
Diese wird munter hochgezählt.
Nur scheint das Programm meine if schleifen zu ignorieren und setzt sie
nicht zurück bzw. minimiert die LCD Anzeige nicht?!
Hab den Code mal kopiert, nur weiß ich nicht ob es verständlich ist, da
es nur ein Ausschnitt ist.
Michel Schl. schrieb:> Ist sicher auch einiges überflüssig...
mit Sicherheit.
Aus deinem Code kann ich wirklich nicht viel machen, selten etwwas
derart kompliziertes gesehen.
Allerdings frage ich mich, wozu du für Zeiten ein dtostrf brauchst?
Was genau umfasst eigentlich dein komplettes Projekt. Eine Countdown-Uhr
mit LCD benötigt vieleicht in Summe eine oder eineinhalb
Bildschirmseiten und da steckt der meiste Code in der ISR, die die Uhr
runterzählt.
Michel Schl. schrieb:> if schleifen
Hopfen und Malz verloren für den der sowas schreibt.
Ausserdem ist das doch nicht dein ganzer Code, da fehlt doch einiges.
Und poste ihn als .c damit man den auch gescheit angucken kann.
Von einem strukturierten Programmierstil hast du wohl noch nie was
gehört? Gerade bei komplexeren Programmen musst du die Funktionalität
sinnvoll in Funktionen auslagern, diese Funktion sinnvoll benennen und
auch die Variablennamen "sprechend" machen. Ein Spaghetticode ist das,
herrje...
gruß cyblord
> mein Systemtakt ist 7,3728MHz bei 450 OVFs sollte 1 Sekunde> vergangen sein?!> ovf++
Dann sollte
1/ ovf eine globale Variable sein, die z.B. so definiert ist
1
volatileuint16_tovf;
2/ bei der Abfrage der Variable ovf im Hauptprogramm sollten Lese- und
Schreibzugriffe atomar gemacht werden (Artikel Interrupt). In deinem
Code fehlt das z.B. an diesen Stellen:
Krapao schrieb:>> mein Systemtakt ist 7,3728MHz bei 450 OVFs sollte 1 Sekunde>> vergangen sein?!>> ovf++>> Dann sollte>> 1/ ovf eine globale Variable sein, die z.B. so definiert ist>
1
>volatileuint16_tovf;
2
>
>> 2/ bei der Abfrage der Variable ovf im Hauptprogramm sollten Lese- und> Schreibzugriffe atomar gemacht werden (Artikel Interrupt). In deinem> Code fehlt das z.B. an diesen Stellen:>
1
>tc=ovf;// nicht atomarer Zugriff auf ovf!
2
>if(tc==450)
3
>{
4
>ovf=0;// nicht atomarer Zugriff auf ovf!
5
>
grundsätzlich richtig.
Es schadet aber auch nichts, wenn er die komplette Uhrenlogik in die ISR
verlagert. Auf die Art zählt die Countdownuhr auch dann noch im
Hintergrund richtig weiter, wenn auf dem LCD gerade irgendwelche
Benutzerinteraktionen laufen.
So wie das aussieht, will er ja einfach nur ein paar Pins einschalten,
den Countdown runterzählen und nach der Vorgabezeit sollen sich die Pins
wieder ausschalten. Das Runterzählen und Ausschalten kann ruhig alles
geschlossen in der ISR passieren (nicht jedoch den LCD update!), die
paar Takte die dafür notwendig sind, hat man mit Leichtigkeit.
> Leider tut sich auf meinem Display rein gar nichts.
Den sei() nach dem Aufruf von timer_an() hast du schon im Code, oder?
Aber selbst ohne den solltest du auf dem Display was sehen und wenn es
nur Nullen bei der Ausgabe von tc sind oder der Vorwahlwert für s und m.
Ich erkenne im Code das Starten des Countdowns nicht und denke der
Countdown wird bei jedem Durchlauf der while Schleife bearbeitet.
dtostrf() ist Overkill, wie andere auch schon schrieben.
Hallo,
vielen Dank für euren zahlreichen und hilfreichen Antworten.
Hatte es derweil bereits selber zum Laufen gebracht, nach eurer Anregung
hab ich allerdings es doch vorgezogen die Minimierung der Zeitvariablen
innerhalb der OVF ISR vorzunehmen.
Zu meiner "Verteidigung" bzw. in Bezug zu eurer sicher angebrachten
Kritik bezüglich meines "Programierstils", sofern man es so nennen darf
... möchte ich sagen, dass ich bis Dezember letzten Jahres weder von
Mikrocontrollern, noch von irgendeiner Programmiersprache Ahnung hatte.
Habe dann kurz mit Assembler begonnen und bin seit ca.Februar bei C
gelandet.
Daher bin ich noch ein vollkommener Neuling auf diesem Gebiet und lerne
noch bzw. probiere viel aus und mache es erstmal so wie ich es mir in
meiner einfachen Logik denke ... ;)