Hallo Sven!
Ich glaube nicht, dass der Compiler den Fehler verursacht. _delay_ms o.ä. die irgendwo auftreten könnten Probleme machen,
wenn diese zu viel oder zu lange sind. delay.h benötigt F_CPU die Systemfrequenz. Hast du diese in den Projekteinstellungen
angegeben? Vielleicht gehen bei dir manchmal Sekunden "verloren" wenn
nicht oft genug aufgerufen wird. Ubrigens solltest du hier auf "größer gleich" prüfen.
Du hast innerhalb der while(1) Schleife sehr viele Display-Ausgaben, teilweise auch permanent, was nicht notwendig ist und
Taktzyklen "verbraucht". Der Display-Bus ist auch ständig aktiv. Du musst eigentlich immer nur dann etwas am Display ausgeben,
wenn sich die Sekunde ändert.
Ich würde das Programm etwas anders strukturieren, vom Prinzip in etwa so ...
Es muss gewährleistet sein, dass die if-Abfrage (blau) mindestens einmal die Sekunden ausgerufen wird, sonste gehen Sekunden verloren. Falls du das nicht gewährleisten kannst,
dann zählst du die "Uhr" komplett innerhalb der ISR und bei jeder Sekunde (Sekundensignal) gibst du die Uhrzeit auf dem Display aus.
Umschalten von 23:59:59 auf 00:00:00 kannst du ganz innerhalb der if-Abfrage prüfen, nachdem du einerstunden inkrementierst:
wenn einerstunden == 4 und zehnerstunden == 2 dann
- alles auf 0
Du kannst natürlich bei deiner Vorgehensweise bleiben, du solltest als erstes mal dafür sorgen, dass nur dann eine Displayausgabe gemacht wird, wenn es wirklich notwendig ist.
(siehe hierzu mein Beispiel).
Grüße,
Dirk
Was kann den Fehler noch verursachen? Vielleicht der Compiler?
Ich glaube nicht, dass der Compiler den Fehler verursacht. _delay_ms o.ä. die irgendwo auftreten könnten Probleme machen,
wenn diese zu viel oder zu lange sind. delay.h benötigt F_CPU die Systemfrequenz. Hast du diese in den Projekteinstellungen
angegeben? Vielleicht gehen bei dir manchmal Sekunden "verloren" wenn
Code:
if(einersek==10)
{
einersek = 0;
// ...
}
Du hast innerhalb der while(1) Schleife sehr viele Display-Ausgaben, teilweise auch permanent, was nicht notwendig ist und
Taktzyklen "verbraucht". Der Display-Bus ist auch ständig aktiv. Du musst eigentlich immer nur dann etwas am Display ausgeben,
wenn sich die Sekunde ändert.
Ich würde das Programm etwas anders strukturieren, vom Prinzip in etwa so ...
Code:
ISR(TIMER1_COMPA_vect)
{
sekundensignal = 1; // setzen, dem Hauptprogramm melden
}
// ...
while(1)
{
[COLOR=#0000ff]wenn sekundensignal == 1 dann
{
- sekundensignal löschen (=0)
- sekunde inkrementieren
wenn Sekunde größer gleich 10 dann
{
- sekunde = 0
- zehnersekunde inkrementieren
wenn zehnersekunde größer gleich 6 dann
{
zehnersekunde = 0
... usw.
}
}
- lcd locate
- string buffer füllen
- string ausgeben
}[/COLOR]
// sonstiges machen
}
Es muss gewährleistet sein, dass die if-Abfrage (blau) mindestens einmal die Sekunden ausgerufen wird, sonste gehen Sekunden verloren. Falls du das nicht gewährleisten kannst,
dann zählst du die "Uhr" komplett innerhalb der ISR und bei jeder Sekunde (Sekundensignal) gibst du die Uhrzeit auf dem Display aus.
Umschalten von 23:59:59 auf 00:00:00 kannst du ganz innerhalb der if-Abfrage prüfen, nachdem du einerstunden inkrementierst:
wenn einerstunden == 4 und zehnerstunden == 2 dann
- alles auf 0
Du kannst natürlich bei deiner Vorgehensweise bleiben, du solltest als erstes mal dafür sorgen, dass nur dann eine Displayausgabe gemacht wird, wenn es wirklich notwendig ist.
(siehe hierzu mein Beispiel).
Grüße,
Dirk