Hallo,
möchte die Uhrzeit in einer Funktion berechnen.
Dafür übergebe ich ihr die Adressen von std,min und sec (Stunden,
Minuten, Secunden)
In der timer.c soll dann mithilfe eines SekundenFlags aus dem
TimerInterrupt die Zeit berechnet werden und die Werte an die durch die
Zeiger referenzierten Speicherplätze für std,min und sec gelegt werden.
Da das nicht funktioniert lass ich die Funktion gerade nur feste Werte
verarbeiten, lasse also die Zeitberechnung weg. Um zu sehen ob die
Funktion überhaupt angesprungen wird gibt sie einen Zähler zurück. Der
zählt in der Main auch artig hoch, Funktion wird also angesprungen.
Anbei der, zugegebenermaßen umfangreiche, Code in C, aber man soll ja
alles posten. Entscheident sind warscheinlich die timer.c und timer.h
sowie die RedDisplayClock.c
Vielleicht enddeckt ja jemand den Fehler.
Jens
Hallo Oliver,
die Ausgabe auf dem Display ist falsch. sec hat immer den Wert 5, min
und std bleiben 0.
Wenn ich in der Main statt der Variablen Zahlen in den Ausgabeaufruf für
das Display setze funzt es. Ich denke irgendetwas mit der
Zeigergeschichte funktioniert nicht, die 5 sieht so nach Speichermüll
aus.
Jens
midibrain schrieb:> Hallo Oliver,>> die Ausgabe auf dem Display ist falsch. sec hat immer den Wert 5, min> und std bleiben 0.> Wenn ich in der Main statt der Variablen Zahlen in den Ausgabeaufruf für> das Display setze funzt es. Ich denke irgendetwas mit der> Zeigergeschichte funktioniert nicht, die 5 sieht so nach Speichermüll> aus.
Die Zeigersache ist in Ordnung.
Aber hier, diese Funktion ist fehlerhaft.
//setzt eine Zahl bis max. 99 rechtsbündig an position a, b
3
{
4
uint8_ti=0;
5
if(number<10)
6
{
7
put_string_lcd(a,b,"0");
8
b+=1;
9
i=1;
10
}
11
if((number<100)&&(number>9))
12
{
13
i=2;
14
}
15
16
chartmp[i];
17
itoa(number,tmp,10);
18
put_string_lcd(a,b,tmp);
19
}
Um einen String "23" zu bilden, benötigst du ein Array der Länge 3(!),
und nicht 2.
Denn der String besteht aus 3 Zeichen. '2', '3' und dem abschliessenden
'\0' Zeichen, welches jeden String beendet.
Korrigier das mal und sieh nach, ob das dann schon alles war.
Ich weiss, das steht (stand zumindest) im Kernighan&Ritchi auch so
drinnen. Aber warum schreibst du
1
return(i);
return ist kein Funktionsaufruf. return kann man einen Ausdruck angeben,
der ausgewertet wird und dessen Ergebnis zurückgegeben wird. Nirgendwo
in der Syntax wird gefordert, dass der Ausdruck in Klammern stehen muss.
Bringt auch nicht viel.
1
returni;
ist genausogut lesbar, wenn nicht sogar besser. Und sogar mit weniger
Aufwand und einfacher zu tippen.
Du schreibst ja auch nicht
Hallo Karl-Heinz,
erstaunlich was Du alles sehen kannst...
Es war tatsächlich die falsche Stringlänge in der Displayroutine!
Habe die Stringlänge geändert und nun ist die Ausgabe korrekt, die
Zeigergeschichte war es also nicht.
Vielen Dank und einen geruhsamen Sonntag Abend aus Berlin.
Jens
aber so eine Zahlenausgabe an sich ist ja auch nützlich.
Merke: du brauchst an solchen Stellen nicht kleckern. Ob du temporär ein
Array der Länge 3 oder 10 anlegst, ist Jacke wie Hose. Wenn diese
Differenz im Speicherverbrauch dein Programm sprengt, dann ist die Kacke
sowieso schon am dampfen.
Karl Heinz schrieb:> aber so eine Zahlenausgabe an sich ist ja auch nützlich.
Allerdings solltest du dir mal überlegen, was deine Funktion
put_number_lcd so alles macht, wenn du der mal irrtümlich zb die Zahl
587 übergibst, wie sie zb durch einen ungewollten Programmfehler
durchaus auch schon mal vorkomme kann.
Das letzte was du nämlich brauchen kannst ist, dass dir deine
Basis-Ausgabefunktionen abkratzen, weil da Fälle entstehen, die du
selbstverständlich nicht bedacht und auch nicht berücksichtigt hast,
weil die im Nichtfehlerfall nicht vorkommen. Nur ist halt selten etwas
von Anfang an perfekt.
Wenn die führenden 0-en dann nicht stimmen, dann ist das kein Beinbruch.
Wenn du dann aber versucht ein Array der Länge 0 zu allokieren, dann IST
das ein Beinbruch. Kein Beinbruch hingegen ist es, wenn du itoa den
Integer 7 konverteren lässt und itoa dazu ein char Array der Länge 7 zur
Verfügung stellst. Dann werden eben temporär ein paar Teile des Arrays
nicht benutzt, aber erst mal passiert sonst nicht viel. Insbesondere
zerschiesst du dir dann auch nicht den Stack, indem du ein Array
überläufst.
Hallo Karl-Heinz,
hab die Ausgaberoutine dahingehend geändert das sie Zahlen > 99
ignoriert. Das ist keine elegante lösung aber verhindert erst einmal
merkwürdiges Verhalten aufgrund falscher (zu großer) Werte.
Das mit dem return(x) habe ich mir wohl am Anfang des programmierens
"eingefangen". Ist wirklich unnütz, werde es mir abgewöhnen.
Vielen Dank noch einmal für die Hilfe und die Tip`s, immer wieder toll
bei Euch im Forum!
Jens
P.S.: Wie kann ich diesen Beitrag als "gelöst" kennzeichnen?