AVR verrechent sich / Speicherproblem ?

Gast #2215088
Lesenswert?

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 #2215139
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

@ 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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren