AVR verrechent sich / Speicherproblem ?

Gast #2215088
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
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <inttypes.h>
4

5
typedef struct _time
6
{
7
  uint8_t sec;
8
  uint8_t min;
9
  uint8_t hour;
10
} time;
11

12
int rtc_time_compare(time* time1, time* time2)
13
{
14
  uint32_t iTime1, iTime2;
15
  iTime1 = time1->hour*3600 + time1->min*60 + time1->sec;
16
  iTime2 = time2->hour*3600 + time2->min*60 + time2->sec;
17

18
  printf("Time 1%i\n",iTime1);  // AVR: 4294937750
19
  printf("Time 2%i\n",iTime2); // AVR: 17264
20

21
  if(iTime1 > iTime2) return 1;
22
  else return 0;
23
}
24
  
25
int main(int argc, char *argv[])
26
{
27
    time switchOnTime, currentTime;
28
    
29
  currentTime.hour   = 9;
30
  currentTime.min    = 59;
31
  currentTime.sec    = 30;
32
    
33
    switchOnTime.hour   =  8;
34
  switchOnTime.min    =  0;
35
  switchOnTime.sec    =  0;
36
  
37
  printf("Compare : %i\n",rtc_time_compare(&currentTime,&switchOnTime));
38
  
39
  system("PAUSE");  
40
  return 0;
41
}
Gast #2215130
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.
Gast #2215139
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
Gast #2215144
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.
Gast #2215164
hier ein anderer ansatz zum Zeitenvergleichen ...
ist nicht so Rechenlastig:
1
int rtc_time_compare(time* time1, time* time2)
2
{
3
  if(time1->hour > time2->hour) return 1;
4
  else if(time1->min > time2->min) return 1;
5
  else if(time1->min > time2->min) return 1;
6
    else return 0;  
7
}
Gast #2215167
@ 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
Gast #2215177
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.)
Gast #2215178
Hallo Sam,

du meinst wohl:
1
int rtc_time_compare(time* time1, time* time2)
2
{
3
  if(time1->hour > time2->hour) return 1;
4
  else if(time1->min > time2->min) return 1;
5
  else if(time1->sec > time2->sec) return 1;
6
    else return 0;  
7
}

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
Gast #2215182
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;
}
#2216161
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.