Forum: Compiler & IDEs Variable besichtigen


von AVR (Gast)


Lesenswert?

Hallo

ich benutze AVR Studio mit WinAVR.

Ich habe einen 8 Prescaler mit einem OCR0A-Wert.

Das Problem ist dass es den Interrupt immer bei 256 auslöst.

Mich würde interessieren wie ich bei AVR Studio die Variablen 
besichtigen kann um zu sehen welcher Wert zugewiesen wurde.

MfG

von MeinerEiner (Gast)


Lesenswert?

Debugger starten + Variable ins Watch-Window eintragen.

von AVR (Gast)


Lesenswert?

Habe ich gemacht.

Entweder steht für mehrere Variable

Not in Scope
Location not valid

von gast (Gast)


Lesenswert?

dann optimiert er da weg ...

von AVR (Gast)


Lesenswert?

Wie meinst du das?

Das Programm wird in diesen Zeilen ausgeführt.

Meine Vermutung ist dass man Register nicht in Dez. ausgeben kann.
1
unsigned int variable
2
3
zahl =   TIME*1000/(8*125);
4
funktion(8, zahl);
5
6
7
funktion(...., unsigned int zahl)
8
{
9
  OCR0A= zahl;
10
}

Ich vermute der Fehler liegt bei der zahl. Sie wird in INT berechnet und 
dann weise ich die Zahl dem Register OCR0A zu.

Brauchen Register eine HEX-Zahl. Gibt es einen Befehl zur umformung von 
DEZ in HEX

von Karl H. (kbuchegg)


Lesenswert?

In einem Computer gibt es kein dezimal oder hexadezimal. Zahl ist Zahl. 
Was sagt denn der Debugger, welcher Wert nach OCRA0 eingetragen wird?

von Karl H. (kbuchegg)


Lesenswert?

Wie groß ist TIME?

von Klaus (Gast)


Lesenswert?

Zunächst mal Dez und Hex ( und auch binär) sind nur verschiedene 
Darstellungen für das selbe Bitmuster. Ist also nur einen andere 
schreibweise.


Die Variable Zahl wird in der Tat wegoptimiert, da der Compiler erkennt, 
dass sie nicht benötigt wird, weil der Wert konstant ist. Also der 
Compilier verwendet statt der Variable direkt den Wert, den du 
zugewiesen hast. Das darf der Compiler machen, solange die Funktion des 
Programms die selbe bleibt. Das einzige was du von der Optimierung 
(neben einem kleineren Programm) mitbekommst, ist eben, dass du die 
Variable nicht mehr im debugger anschauen kannst.  Dafür gibt es nun 2 
lösungen:

1) du schaltest in den Projekteinstellungen die Optimierung komplett aus 
(-O0). Dadurch wird nichts mehr wegoptimiert, aber das Programm wird 
auch größer.

2) du deklarierst die Variable zum Debuggen als volatile. Das verhindert 
unter anderem, dass die Variable wegoptimiert wird.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hex, Dezimal und Binär ist alles nur eine jeweils andere Darstellung 
einer Zahl. Ich kann jede ganze Zahl in allen Schreibweisen 
darstellen.
Als char betrachtet gibt es dafür nur 8 Bit. Schön ist, dass diese 8 Bit 
in 2 Nibble passen, von denen wieder jedes einzelne die Hälfte einer 
Hex-Zahl ist.
0xff = 0b11111111 = 255 =   -1
0x07 = 0b00000111 =   7 =   +7
0xf0 = 0b11110000 = 248 =  -16
usw. usf.

Ein short (=int bei AVR) sind dann nur 2 Bytes hintereinander und 
demnach 4 Hex-Zeichen.
0xffff = 0b1111111111111111 = 65535 =   -1
0x0007 = 0b0000000000000111 =     7 =   +7
0xfff0 = 0b1111111111110000 = 65520 =  -16

von AVR (Gast)


Lesenswert?

TIME ist ein irgendein Wert in us.

Irgendwas stimmt mit der Berechnung nicht.

Habe zb. 90 genommen. Beim Prescaler 8 sollte der OCR0A Wert auch 90 
sein.

Bei 8MHz

OCR0A= 90*1000/ (8*125)= 90

Zugewiesen wird aber 0x18

von Karl H. (kbuchegg)


Lesenswert?

90*1000 ist ein bischen zu groß, als das diese Berechnung im Zahlenraum 
int durchgeführt werden könnte.
int endet bei 32767. Sobald du drüberkommst und sei aus auch nur bei 
einem Zwischenergebnis, hast du verloren :-)

Berechnung ein wenig umstellen und schon geht sich alles aus.

von Stefan E. (sternst)


Lesenswert?

Karl heinz Buchegger schrieb:

> Berechnung ein wenig umstellen und schon geht sich alles aus.

"Umstellen"? Wie wäre es mit "weglassen"? ;-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> OCR0A= 90*1000/ (8*125)= 90
Frei nach Karl heinz Buchegger könntest du es so machen:
OCR0A = (90*(1000/8))/125;

> OCR0A= 90*1000/ (8*125)= 90
Frei nach  Stefan Ernst: warum schreibst du nicht einfach
OCR0A = 90;

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Karl heinz Buchegger schrieb:
>
>> Berechnung ein wenig umstellen und schon geht sich alles aus.
>
> "Umstellen"? Wie wäre es mit "weglassen"? ;-)

Er wird schon seinen Grund haben :-)
Und sei es nur, daß er den Vorteiler einfach wechseln kann, was ja 
grundsätzlich nicht schlecht ist.

von AVR (Gast)


Lesenswert?

Danke für die Hilfe. Das int war der Fehler.

Für unterschiedliche Werte brauche ich unterschiedliche Prescaler.

Das einzige was ich noch machen könnte ist alle zb. 10us einen Interrupt 
auslösen.

Bei 1000 us würde ich da aber viele Interrupts auslösen aber beinahe 
nichts machen.

von AVR (Gast)


Lesenswert?

Hallo

Ich habe wieder irgendwelche Probleme

1
define ZEIT 10000
2
3
main
4
{
5
funktion(ZEIT);
6
}
7
8
9
funktion(ZEIT)
10
{
11
  else if( (ZEIT > 8000) && (ZEIT <= 30000) )
12
  {  
13
    TCCR0B= 0x05;           //CS=5 => 1024
14
    nummer =  ZEIT*8/1024;
15
    unterfunktion (8, nummer);
16
  }
17
18
}
19
20
unterfunktion()
21
{
22
          if(xy == 8)
23
    CLKPR = 0x80; 
24
     CLKPR = 0x00;
25
26
      TCCR0A= 0x02; 
27
      TIMSK0= 0x02;
28
    
29
30
    OCR0A= nummer;
31
}

Laut Berechnung sollte "nummer==78 sein", OCR0A wird aber 0x0E 
zugewiesen.

von AVR (Gast)


Lesenswert?

Die Unterfunktion sieht so aus
1
unterfunktion(8, nummer)
2
{
3
          if(xy == 8)
4
          {
5
          CLKPR = 0x80;
6
          CLKPR = 0x00;
7
8
          TCCR0A= 0x02;
9
          TIMSK0= 0x02;
10
11
          OCR0A= nummer;
12
          }
13
}

von Karl H. (kbuchegg)


Lesenswert?

Selbes Problem

 else if( (ZEIT > 8000) && (ZEIT <= 30000) )
  {
    TCCR0B= 0x05;           //CS=5 => 1024
    nummer =  ZEIT*8/1024;


Wenn ZEIT minmial den Wert 8000 hat, dann ergibt 8000 * 8 ein 
Zwischenergebnis von 64000. Damit bist du über den magischen 32767 
drüber :-)

(Was sagt eigentlich dein C-Buch zum Thema 'long')

Und bitte: Übertrage deinen Code per Copy&Paste hier ins Forum. Es ist 
ziemlich mühselig, deine wirklichen Probleme von den Tippfehlern zu 
unterscheiden.

von AVR (Gast)


Lesenswert?

Es ist kein int-Fehler zumindest bei variable.

Vielleicht ist es ein Fehler hier
>variable = TIME*8/1024;
weil TIME ein Integer ist.
1
main
2
{
3
else if ( (ZEIT >= 1000) && (TIMER == 0) )
4
  delay_t0_ms(ZEIT);
5
}
6
7
void delay_t0_ms(unsigned int TIME)
8
{  
9
        unsigned long int variable;
10
11
  else if( (TIME > 8192) && (TIME <= 32767) )  //Prescaler 1024
12
  {  
13
    TCCR0B= 0x05;
14
    variable =   TIME*8/1024;
15
    init_t0(8, variable);
16
  }
17
18
}
19
20
void init_t0 (unsigned int MHZ, unsigned int num_us_tick)
21
{
22
  else if(MHZ==8)
23
  {
24
    CLKPR = 0x80; 
25
     CLKPR = 0x00;
26
27
      TCCR0A= 0x02; 
28
      TIMSK0= 0x02;
29
    
30
31
    OCR0A= num_us_tick;
32
  }
33
34
sei();
35
}

von Karl H. (kbuchegg)


Lesenswert?

AVR schrieb:
>
> Vielleicht ist es ein Fehler hier
>>variable = TIME*8/1024;
> weil TIME ein Integer ist.


Morgen früh, gleich als allererstes, gehst du in die nächste 
Buchhandlung und besorgst dir ein C-Buch.

Das sind alles Grundlagen. Und zwar von der Sorte, die in jedem noch so 
grindigen C-Buch in den ersten 4 Kapiteln (von 25) erklärt werden.

>     TCCR0B= 0x05;
>     variable =   TIME*8/1024;

Zu dem Zeitpunkt, zu dem an 'variable' zugewiesen wird, ist das Kind 
längst in den Brunnen gefallen.

   TIME * 8
interessiert nicht die Bohne, dass du das Endergebnis an einen unsigned 
long zuweist. TIME ist ein unsigned int, 8 ist ein int. Also wird in 
unsigned int gerechnet und das Ergebnis ist wieder ein unsigned int.

Was anderes ist allerdings

   TIME * 8L
TIME ist ein unsigned int, 8 ist jetzt ein long. Also wird in long 
gerechnet.

   TIME * 8UL
Jetzt ist 8 ein unsigned long und es wird im Zahlenraum unsigned long 
gerechnet.


Wieso hältst du dich eigentlich nicht an die übliche Konvention, dass 
Namen, welche komplett in Grossbuchstaben geschrieben sind, 
ausschliesslich für Makros reserviert sind.

: Wiederhergestellt durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
void init_t0 (unsigned int MHZ, unsigned int num_us_tick)
2
{
3
  else if(MHZ==8)   //  sosososo... 
4
  {
5
      :
6
      :
Was sagt eigentlich dein Compiler dazu?

> Morgen früh, gleich als allererstes, gehst du in die nächste
> Buchhandlung und besorgst dir ein C-Buch.
Ja, das wäre wohl das Beste...

BTW:
Es ist oft einfacher, das C-Programmieren am PC zu lernen. Und wenns 
dort klappt, dann erst in die Einschränkungen der uC-Welt einzusteigen.

von AVR (Gast)


Lesenswert?

Hallo

Könnte einen Denkanstoß gebrauchen. Es heißt man soll möglichst viel in 
den Hauptcode verlagern und nicht im ISR lassen. Habe es so versucht 
aber der Timer wird nicht richtig ausgeführt.

delay_t1_s geht das Programm nur einmal durch und bleibt dann in der 
ISR-Funktion.

Ich wollte dass alle 100ms die innere for-Schleife um 1 hochzählt. Wenn
1
if( (a == time) && (b == 10) )
 soll die ISR-Funktion ausgeführt werden.
1
void delay_t1_s(unsigned long int time)
2
{
3
  unsigned long int variable;
4
  int i, a, b;
5
  
6
  timer_init(7);
7
8
  if(MHZ == 1)
9
  {
10
    variable= 12;
11
12
     if( (time >= 1) && (time <= 999) )
13
    {
14
      for(a=1; a <= time; a++)
15
      {
16
        for(b=1; b <=10; b++)
17
        {
18
          if( (a == time) && (b == 10) )
19
          {
20
            //init_t1(MHZ, variable);
21
          }
22
        }
23
      }
24
    }
25
  }
26
}
27
28
29
30
void init_t1 (unsigned int mhz, unsigned int num_us_tick)
31
{
32
  if(mhz==1)
33
  {
34
      TCCR1A= 0x00; 
35
      TIMSK1= 0x02;
36
    
37
38
    OCR1A= num_us_tick;
39
  }
40
41
sei();
42
}
43
44
45
ISR (TIMER1_COMPA_vect) 
46
{
47
  PORTB^= 0x04; 
48
}

MfG

von Karl H. (kbuchegg)


Lesenswert?

Da scheint ein grundsätzliches Misverständnis vorzuliegen.

Der Timer arbeitet völlig unabhängig von allem anderen.
Wenn du also etwas alle 100ms ausführen lassen willst, dann setzt du den 
Timer so auf, dass er dir alle x Millisekunden einen Interrupt auslöst 
(zb. weil der Timer einen Overflow generiert). In der ISR zählst du mit, 
wie oft die ISR aufgerufen wurde und leitest davon die 100 Millisekunden 
ab.

Wird dein Timer zb alle 0.5 Millisekunden aufgerufen, dann muss 
innerhalb der ISR eine Variable bis 200 zählen, damit 100 Millisekunden 
vergangen sind.

von AVR (Gast)


Lesenswert?

Hallo Karl Heinz

hast du gemeint dass der Code ca. so zu programmieren wäre. Mein Problem 
ist dass ich nicht schauen kann wieviel Zeit vergeht weil AVR Studio in 
der Zeile if(zaehler == 2) hängen bleibt und im us-Takt weiter zählt. Es 
springt komischer Weise nicht ins ISR und berechnet die Zeit.

Gibt es hier irgendwo Infos zur Programmierung eines Callbacks.

1
volatile int zaehler;
2
volatile int sek;
3
4
void delay_t1_s(unsigned long int time)
5
{
6
  unsigned long int variable;
7
  int i;
8
  
9
10
  timer_init(7);                      //Prescaler 8
11
12
  if(MHZ == 1)
13
  {
14
    variable= 62500;            //OCRB1=62500 = 500ms
15
    init_t1(MHZ, variable);     //initialisiert Timer 
16
17
     if( (time >= 1) && (time <= 999) )
18
    {
19
      while(1)
20
      {
21
        if (zaehler == 2)
22
        {
23
          zaehler=0;
24
          sek++;
25
          
26
          if(sek==time)
27
          {
28
            PORTB^= 0x01;
29
            b=0;
30
          }
31
        }
32
33
      }
34
    }
35
  }
36
}
37
38
39
ISR (TIMER1_COMPA_vect) 
40
{
41
    if (fehler == 1)
42
  {
43
      PORTB= ~PORTB;
44
  }
45
46
  else if(1)
47
  {
48
    zaehler++;
49
  }
50
51
  else
52
  {
53
    PORTB^= 0x01;  
54
  }
55
}

Danke für die Hilfe
MfG

von Karl H. (kbuchegg)


Lesenswert?

Zählt der Timer hoch? (Das sieht man im Simulator)

Und was zum T.... verbirgt sich hinter all den timer Funktionen?

von AVR (Gast)


Lesenswert?

Die Geschwindigkeit des Blinkens ist einstellbar.

von Karl H. (kbuchegg)


Lesenswert?

LOL

Das die Funktionen nicht die Selbstzerstörung aktivierer war mir schon 
klar. Nur, was machen die? Code!

Wir betreiben hier Fehlersuche. Da kann alles relevant sein!

von AVR (Gast)


Lesenswert?

>Und was zum T.... verbirgt sich hinter all den timer Funktionen?

Dachte du wolltest wissen was die Funktionen machen.


Habe jetzt länger getestet. Der Simulator hat sehr lange gebraucht beim 
hochzählen deshalb blieb er bei der Zeile "if (zaehler == 2)" die ganze 
Zeit hängen.

Danke für die Hilfe.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.