Guten Tag,
ich bin am verzweifeln. Und brauche euren Rat. Ich habe einen ATMega168
mit einer RTC.
Ich möchte nun zu bestimmten Zeiten schalten. Hierfür habe ich mir eine
funktion geschrieben, mit welcher 2 Zeiten verglichen werden können. Nur
wenn ich das ganze auf einem PC Teste als Konsolenproramm tut alles wie
gewünscht.
Auf dem AVR habe ich jedoch unsinnige Werte, und der Vergleich schlägt
fehl. Ich habe den Code angehängt, und die Werte die ich im AVR erhalte
als Kommentar geschrieben (dort Wandlung mit ultoa und Ausgabe auf LCD).
Was kann dieses Verhalten verursachen? RAM zu voll? Wie kann ich das
Prüfen. Meine Toolchain AVRStudio 4 + MKII, demnächst AVR Dragon.
Für Ideen wäre ich sehr dankbar.
Grüßle
Studentle
hallo
> iTime1 = time1->hour*3600 + time1->min*60 + time1->sec;
probiere es einmal mit dedizierten cast anweisungen. vielleicht gibt es
unterschiede beim compiler.
gruss
hans
--
Studentle schrieb:> uint8_t hour;> ...> iTime1 = time1->hour*3600 + ...
Da muß man nicht probieren. Der Compiler führt time1->hour*3600 als
16-bit Multiplikation aus, da 3600 zunächst uint ist.
Mit iTime1 = time1->hour*3600UL + ... paßt das besser.
Hi, Studentle,
in welcher Reihenfolge werden die Additionen iTime1 = time1->hour*3600 +
time1->min*60 + time1->sec; durchgeführt?
Zum Debuggen mit JTAG/ICE ist es günstiger, diese Ziele aufzudröseln in
drei separate Anweisungen.
Im Single-Step-Modus siehst Du dann, was in welcher Reihenfolge
geschieht.
Ciao
Wolfgang Horn
Ok ... muss man wohl nicht typecasten.
aber ich hab das Problem gefunden:
lokale Variablen und Zeiger.
der Compiler versucht tatsächlich die lokalen Variablen in Registern
unterzubringen .... deswegen deklariere die alle Variablen die du
brauchst global.
besonders fürs Debuggen ist das Sinnvoll, da so Variablen nicht dauernd
aus dem Scope sind. und für den Speicherverbrauch ist das wohl das Selbe
oder besser.
@ Wolfgang
Nun ja die Reihenfolge ist mir unbekannt. Ich habe nur den MKII kann
also nicht onchip debuggen kann.
Allerdings könnte ich es mir noch im Simulator anschauen.
@ Sam
Für das Testen kann ich schon mal mit globalen Variablen arbeiten, doch
für das finale Programm nicht gewünscht. Die Übersichtlichkeit leidet
sonst zu sehr.
Grüßle Studentle
Studentle schrieb:> Für das Testen kann ich schon mal mit globalen Variablen arbeiten, doch> für das finale Programm nicht gewünscht. Die Übersichtlichkeit leidet> sonst zu sehr.
Lieber nicht global, aber ausnahmsweise die Variablen für den
Simulator mal volatile deklarieren. (Dann liegen die auf jeden Fall im
Speicher.)
genau diesen Ansatz hatte ich am Anfang auch.
Allerdings hat das ganze einen Haken, der Vergleich schlägt fehl:
Zeit 1 = 08:00:30
Zeit 2 = 23:00:00
8 > 23 ok
0 > 0 ok
30 > 0 ! -> return 1
sam schrieb:> hier ein anderer ansatz zum Zeitenvergleichen ...> ist nicht so Rechenlastig:> int rtc_time_compare(time* time1, time* time2)> {> if(time1->hour > time2->hour) return 1;> else if(time1->min > time2->min) return 1;> else if(time1->min > time2->min) return 1;> else return 0;> }
ich merk gerade, dass das nicht so funktioniert :)
so sollte es aber gehen :)
int rtc_time_compare(time* time1, time* time2)
{
if(time1->hour < time2->hour) return 0;
if(time1->hour > time2->hour) return 1;
if(time1->min < time2->min) return 0;
if(time1->min > time2->min) return 1;
if(time1->sec < time2->sec) return 0;
else return 1;
}
sam schrieb:> ich merk gerade, dass das nicht so funktioniert :)>> so sollte es aber gehen :)
Immer noch falsch.
Überleg dir einfach was das Ergebnis ist, wenn die beiden Zeiten gleich
sind.
Der Schlüssel liegt darin, dass so ein allgemeiner Vergleich 3
Ergebnisse haben muss:
* A ist größer als B
* A ist kleiner als B
* A ist gleich B
Oder aber man baut eine Funktion, die definitiv auf 'größer' vergleicht.
Dann kann man das so lassen, wie du das hast. Nur ist es dann weise,
wenn sich das auch im Funktionsnamen niederschlägt.
>> int rtc_time_compare(time* time1, time* time2)> {> if(time1->hour < time2->hour) return 0;> if(time1->hour > time2->hour) return 1;> if(time1->min < time2->min) return 0;> if(time1->min > time2->min) return 1;> if(time1->sec < time2->sec) return 0;> else return 1;> }
nach einem return brauchst du kein else.