www.mikrocontroller.net

Forum: Compiler & IDEs Variable besichtigen


Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: MeinerEiner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Debugger starten + Variable ins Watch-Window eintragen.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich gemacht.

Entweder steht für mehrere Variable

Not in Scope
Location not valid

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann optimiert er da weg ...

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie meinst du das?

Das Programm wird in diesen Zeilen ausgeführt.

Meine Vermutung ist dass man Register nicht in Dez. ausgeben kann.
unsigned int variable

zahl =   TIME*1000/(8*125);
funktion(8, zahl);


funktion(...., unsigned int zahl)
{
  OCR0A= zahl;
}


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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie groß ist TIME?

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

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

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich habe wieder irgendwelche Probleme

define ZEIT 10000

main
{
funktion(ZEIT);
}


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

}

unterfunktion()
{
          if(xy == 8)
    CLKPR = 0x80; 
     CLKPR = 0x00;

      TCCR0A= 0x02; 
      TIMSK0= 0x02;
    

    OCR0A= nummer;
}

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

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Unterfunktion sieht so aus
unterfunktion(8, nummer)
{
          if(xy == 8)
          {
          CLKPR = 0x80;
          CLKPR = 0x00;

          TCCR0A= 0x02;
          TIMSK0= 0x02;

          OCR0A= nummer;
          }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist kein int-Fehler zumindest bei variable.

Vielleicht ist es ein Fehler hier
>variable = TIME*8/1024;
weil TIME ein Integer ist.
main
{
else if ( (ZEIT >= 1000) && (TIMER == 0) )
  delay_t0_ms(ZEIT);
}

void delay_t0_ms(unsigned int TIME)
{  
        unsigned long int variable;

  else if( (TIME > 8192) && (TIME <= 32767) )  //Prescaler 1024
  {  
    TCCR0B= 0x05;
    variable =   TIME*8/1024;
    init_t0(8, variable);
  }

}

void init_t0 (unsigned int MHZ, unsigned int num_us_tick)
{
  else if(MHZ==8)
  {
    CLKPR = 0x80; 
     CLKPR = 0x00;

      TCCR0A= 0x02; 
      TIMSK0= 0x02;
    

    OCR0A= num_us_tick;
  }

sei();
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 Moderator
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void init_t0 (unsigned int MHZ, unsigned int num_us_tick)
{
  else if(MHZ==8)   //  sosososo... 
  {
      :
      :
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.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
if( (a == time) && (b == 10) )
 soll die ISR-Funktion ausgeführt werden.
void delay_t1_s(unsigned long int time)
{
  unsigned long int variable;
  int i, a, b;
  
  timer_init(7);

  if(MHZ == 1)
  {
    variable= 12;

     if( (time >= 1) && (time <= 999) )
    {
      for(a=1; a <= time; a++)
      {
        for(b=1; b <=10; b++)
        {
          if( (a == time) && (b == 10) )
          {
            //init_t1(MHZ, variable);
          }
        }
      }
    }
  }
}



void init_t1 (unsigned int mhz, unsigned int num_us_tick)
{
  if(mhz==1)
  {
      TCCR1A= 0x00; 
      TIMSK1= 0x02;
    

    OCR1A= num_us_tick;
  }

sei();
}


ISR (TIMER1_COMPA_vect) 
{
  PORTB^= 0x04; 
}

MfG

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

volatile int zaehler;
volatile int sek;

void delay_t1_s(unsigned long int time)
{
  unsigned long int variable;
  int i;
  

  timer_init(7);                      //Prescaler 8

  if(MHZ == 1)
  {
    variable= 62500;            //OCRB1=62500 = 500ms
    init_t1(MHZ, variable);     //initialisiert Timer 

     if( (time >= 1) && (time <= 999) )
    {
      while(1)
      {
        if (zaehler == 2)
        {
          zaehler=0;
          sek++;
          
          if(sek==time)
          {
            PORTB^= 0x01;
            b=0;
          }
        }

      }
    }
  }
}


ISR (TIMER1_COMPA_vect) 
{
    if (fehler == 1)
  {
      PORTB= ~PORTB;
  }

  else if(1)
  {
    zaehler++;
  }

  else
  {
    PORTB^= 0x01;  
  }
}

Danke für die Hilfe
MfG

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zählt der Timer hoch? (Das sieht man im Simulator)

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

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Geschwindigkeit des Blinkens ist einstellbar.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.