Forum: Compiler & IDEs AVR241 mit Code für anderen Compiler


von Bruno M. (brumay)


Lesenswert?

Hallo,

ich versuche seit geraumer Zeit den Code aus der AVR241 zum Laufen zu 
bringen. Da es nicht gelungen ist, versuche ich jetzt den Code 
schrittweise aufzubauen. Aber schon bei den ersten paar Zeilen bekomme 
ich jede Menge Warnungen und Fehler.
1
unsigned char state_counter = 8; 
2
 
3
initialization(void)
4
{
5
  TCCR0B = (1<<CS01)|(1<<CS00);   // = 8MHz/64   3/22/05
6
  TCNT0=0xC1;
7
  TIMSK0 |= (1<<TOIE0);
8
}
9
10
isr (TIMER0_OVF_vect)
11
{
12
  TCNT0=5;            
13
  if (state_counter > 7) state_counter = 0;
14
}
15
16
int main(void)
17
{  
18
  initialization();      
19
  sei();           
20
21
  while (1)  
22
  {
23
  state_counter++;
24
  }
25
}

Nachfolgend die Fehlerliste:
Warning  1  return type defaults to 'int' [enabled by default]    10  1
Warning  2  return type defaults to 'int' [enabled by default]    17  1
Warning  3  type of '__vector_16' defaults to 'int' [enabled by default] 
17  1
Warning  4  control reaches end of non-void function [-Wreturn-type] 
21  1
Warning  5  control reaches end of non-void function [-Wreturn-type] 
15  1

Was muß ich tun um diese Warnungen weg zu bekommen?

Völlig unerklärlich ist mir aber, daß er beim debuggen im Studio 6 nach 
einer Datei libgcc.S verlangt und dann im Nirwana landet.

Kann jemand helfen?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> isr (TIMER0_OVF_vect)

C unterscheidet zwischen Groß- und Kleinschreibung --> ISR muss das 
heißen

von Bruno M. (brumay)


Lesenswert?

Johann L. schrieb:

> C unterscheidet zwischen Groß- und Kleinschreibung --> ISR muss das
> heißen

Super, damit ist die Fehlerliste erheblich kürzer geworden und der Timer 
funktioniert jetzt.

Warning  1  return type defaults to 'int' [enabled by default]  10  1
Warning  2  control reaches end of non-void function [-Wreturn-type]  15 
1

von Oliver S. (oliverso)


Lesenswert?

Bruno M. schrieb:
> Warning  1  return type defaults to 'int' [enabled by default]    10  1

C-Buch vorhanden? Wenn nein, kaufen, und nachlesen, wie Funktionen in C 
definiert werden.

Oliver

von Bruno M. (brumay)


Lesenswert?

Problem ist gelöst!

Es fehlte ein void vor initialization(void), d.h. void 
initialization(void)

von Bruno M. (brumay)


Lesenswert?

So, ich habe das Programm jetzt etwas erweitert und hänge wieder fest.

1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include <avr/pgmspace.h>
4
#include <avr/interrupt.h>
5
#include <stdlib.h>
6
 
7
unsigned char segs_out    = 0; 
8
unsigned char state_counter = 8; 
9
unsigned char output_change = 0; 
10
unsigned char LCD_d_1       = 0;    // counter starts at "000" 
11
unsigned char LCD_d_2       = 0;  
12
unsigned char LCD_d_3       = 0;  
13
unsigned char LCD_d_4       = 0;  
14
unsigned char Pt_1_sec      = 0; // 0.1 second counter 
15
16
void initialization(void)
17
{
18
  TCCR0B = (1<<CS01)|(1<<CS00);   // = 8MHz/64   3/22/05
19
  TCNT0=0xC1;
20
  TIMSK0 |= (1<<TOIE0);
21
}
22
23
ISR (TIMER0_OVF_vect)
24
{
25
  TCNT0=5;               
26
  state_counter++; 
27
  output_change = 1;          
28
  if (state_counter > 7) state_counter = 0; 
29
}
30
31
int main(void)
32
{  
33
   initialization();
34
   sei();           
35
36
   while (1)  
37
   {
38
      if(output_change)
39
      {  
40
    output_change = 0;    
41
    switch (state_counter)
42
    { 
43
        case 0:
44
    DDRD = 0;    
45
    PORTD = 0x00; 
46
    PORTC = segs_out; 
47
    DDRC  = 0xFF;      
48
    DDRD  = 0x01;      
49
               break; 
50
      
51
       default: 
52
    DDRC = 0; 
53
    DDRD = 0;        
54
     }  
55
       }    
56
   }
57
}

Nach Durchlaufen des timer müßte eigentlich case0 angesprungen werden, 
aber im Studio 6 wird immer default angesprungen. Im Studio 4 hingegen 
springt er zurück in die ISR und bleibt dort hängen, weil TCNT0 ja immer 
zurückgestellt wird.

von Bruno M. (brumay)


Lesenswert?

Ich habe jetzt versuchsweise, in die ISR den Sprungbefehl main() 
eingesetzt, da das ja eigentlich passieren müßte. Damit funktioniert es 
auch, aber jetzt kommt die Warnung:

Warning  1  implicit declaration of function 'main' 
[-Wimplicit-function-declaration]  30  2


Wie kann ich das vermeiden?

von Boston (Gast)


Lesenswert?

Bruno M. schrieb:
> Ich habe jetzt versuchsweise, in die ISR den Sprungbefehl main()
> eingesetzt,

Du hast wirklich gar keine Ahnung von dem was du da grad machst oder?

von Bruno M. (brumay)


Lesenswert?

Boston schrieb:

> Du hast wirklich gar keine Ahnung von dem was du da grad machst oder?

Gar keine Ahnung ist übertrieben, aber C ist wirklich nicht mein Thema. 
Deshalb gebe ich mir ja Mühe den Code nachzuvollziehen, damit ich ihn in 
asm realisieren kann.

von Karl H. (kbuchegg)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

> Ich habe jetzt versuchsweise, in die ISR den Sprungbefehl main() eingesetzt

Facepalm.

>> Du hast wirklich gar keine Ahnung von dem was du da grad machst oder?
>
> Gar keine Ahnung ist übertrieben

das ist sogar untertrieben, denn ...

> , aber C ist wirklich nicht mein Thema.

... das hat auch nichts mit C zu tun.
Auch in Assembler macht man keinen Spring aus einer ISR in die 
Hauptschleife, sondern geht den normalen vorgesehenen Weg. Alleine schon 
die Idee eines derartigen Sprunges zeigt ... ja, was ... das dir so 
manches nicht wirklich klar ist. Assembler hin, C her

von Bruno M. (brumay)


Lesenswert?

Diese Beiträge sind wirklich eine super Hilfe.

Wenn ihr die Einleitung gelesen hättet, dann wüßtet ihr, daß es nicht 
mein Code ist, sondern ein Code aus der AVR241 und dort ist in der ISR 
gar kein Sprungbefehl enthalten.

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:

> Wenn ihr die Einleitung gelesen hättet, dann wüßtet ihr, daß es nicht
> mein Code ist, sondern ein Code aus der AVR241 und dort ist in der ISR
> gar kein Sprungbefehl enthalten.

Es geht darum, dass alleine die Idee eines derartigen Sprungs schon sehr 
viel über deine Kenntnisse aussagt.
Ja, das kann man. Man kann aus der Art und Weise, wie jemand ein Problem 
analysiert und welche Lösungsstrategie er einschlägt Aussagen darüber 
treffen, wie gut er in der Materie drinn ist. Wenn ein Automechaniker 
mit dem Problem konfrontiert wird, dass der Motor nicht anspringt und er 
nähert sich dem Fahrzeug mit einer Heckenschere, dann sollte man sein 
Fahrzeug da möglichst schnell rausholen.

: Bearbeitet durch User
von Uwe B. (boerge) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Ich habe jetzt versuchsweise, in die ISR den Sprungbefehl main()
> eingesetzt, da das ja eigentlich passieren müßte. Damit funktioniert es
> auch, aber jetzt kommt die Warnung:

Bruno M. schrieb:
> Wenn ihr die Einleitung gelesen hättet, dann wüßtet ihr, daß es nicht
> mein Code ist, sondern ein Code aus der AVR241 und dort ist in der ISR
> gar kein Sprungbefehl enthalten.

häääää, funktioniert dein Kurzzeitgedächtnis nicht richtig?

von Oliver S. (oliverso)


Lesenswert?

Bruno M. schrieb:
> aber im Studio 6 wird immer default angesprungen. Im Studio 4 hingegen

Der Simulator vom Studio 6 springt im Einzelschrittbetrieb keine ISRs 
an. Klingt blöd, ist auch so.

Oliver

von Bruno M. (brumay)


Lesenswert?

Herzlichen Dank. Wieder mal ein vernünftiger Beitrag!

Hätte mir jemand gesagt, daß in C auch der reti Befehl gilt, wäre es 
einfacher gewesen.

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:
> Herzlichen Dank. Wieder mal ein vernünftiger Beitrag!
>
> Hätte mir jemand gesagt, daß in C auch der reti Befehl gilt, wäre es
> einfacher gewesen.

Das Lustige ist, dass du dich darum überhaupt nicht kümmern musst. Das 
macht der Compiler für dich. Du schreibst einfach nur
1
ISR (TIMER0_OVF_vect)
2
{
3
  TCNT0=5;            
4
  if (state_counter > 7) state_counter = 0;
5
}
und alles ist gut. Dass diese Funktion mit einem RETI abgeschlossen 
werden muss ist nichts, was dich irgendwie interessieren muss.

Was dich aber sehr wohl interessieren muss das ist, dass state_counter 
volatile sein muss. Steht im verlinkten Artikel und dazu auch die 
Erklärung, warum das so sein muss.

von Bruno M. (brumay)


Lesenswert?

Karl Heinz schrieb:

> Steht im verlinkten Artikel und dazu auch die
> Erklärung, warum das so sein muss

Link habe ich zwar nicht gesehen, aber mein schlaues Buch sagt mir, daß 
der Compiler daran nichts mehr ändert.

> Das Lustige ist, dass du dich darum überhaupt nicht kümmern musst. Das
> macht der Compiler für dich.

Gilt das auch für WINAVR, da im Studio 4 die ISR nicht verlassen wird.

Nach Einsetzen von volotile hat sich aber an dem eigentlichen Problem 
nichts geändert, d.h. daß er nach default springt und nicht nach case0.

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:
> Karl Heinz schrieb:
>
>> Steht im verlinkten Artikel und dazu auch die
>> Erklärung, warum das so sein muss
>
> Link habe ich zwar nicht gesehen,

Beitrag "Re: AVR241 mit Code für anderen Compiler"

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:

> Nach Einsetzen von volotile hat sich aber an dem eigentlichen Problem
> nichts geändert, d.h. daß er nach default springt und nicht nach case0.

Tja. Das wird wohl daran liegen, dass dein state_counter nicht den Wert 
0 hat.
Was auch nicht weiter verwundert. Denn state_counter beginnt mit dem 
Wert 8 und so einfach glaub ich die nicht, dass du im Single Step im 
Simulator soweit vorgesteppt bist, bis der Timer mal in den Overflow 
gelaufen ist.

: Bearbeitet durch User
von Eric B. (beric)


Lesenswert?

Probier mal so:
1
ISR (TIMER0_OVF_vect)
2
{
3
  TCNT0=5;               
4
  output_change = 1;          
5
}
6
7
int main(void)
8
{  
9
  initialization();
10
  sei();           
11
12
  while (1)  
13
  {
14
    if(output_change)
15
    {  
16
      output_change = 0;    
17
      state_counter ++;
18
      if(state_counter > 7)
19
      { 
20
        DDRD = 0;    
21
        PORTD = 0x00; 
22
        PORTC = segs_out; 
23
        DDRC  = 0xFF;      
24
        DDRD  = 0x01;      
25
        state_counter = 0; 
26
      }
27
      else
28
      {
29
        DDRC = 0; 
30
        DDRD = 0;        
31
      }  
32
    }    
33
  }
34
}

von Bruno M. (brumay)


Lesenswert?

Karl Heinz schrieb:

> Tja. Das wird wohl daran liegen, dass dein state_counter nicht den Wert
> 0 hat

Daran liegt es sicher nicht! Ich stelle den Curser einfach auf 
output_change = 1 und mit "run to curser" warte ich ab bis das Register 
den Wert 8 annimmt. Im nächsten Befehl wird er dann sicher auf 0 
gestellt.

Eric B. schrieb:

> Probier mal so:

Das geht leider nicht, da ich nicht nur case0 habe sondern weiter bis 
case7. Die habe ich nur zum Testen weggelassen.

von g457 (Gast)


Lesenswert?

> [..] mein schlaues Buch sagt mir [..]

Wen hast Du denn alles volatilisiert?

von Bruno M. (brumay)


Lesenswert?

g457 schrieb:
> Wen hast Du denn alles volatilisiert?

Die Frage war erst etwas kryptisch, aber es war tatsächlich der 
entscheidende Hinweis. Ich mußte auch output_change als volotile 
deklarieren. Nun läuft es richtig und ich hoffe, daß ich nun auch den 
Rest des Programms zum Laufen bringen kann.

von Bruno M. (brumay)


Lesenswert?

Oliver S. schrieb:
> Der Simulator vom Studio 6 springt im Einzelschrittbetrieb keine ISRs
> an. Klingt blöd, ist auch so.

Bei mir funktioniert das. Ich kann mich jetzt auch erinnern, daß ich vor 
längerer Zeit den Hinweis bekommen habe, daß das eine Einstellungssache 
ist. Ich weiß jetzt aber nicht mehr was und wo.

von Bruno M. (brumay)


Angehängte Dateien:

Lesenswert?

Das Programm funktioniert! Danke an alle Beteiligten.
Ich hänge den kompletten Code mal dran, vielleicht hat ja noch jemand 
Verwendung dafür.

Gruß Bruno

von Eric B. (beric)


Lesenswert?

Bruno M. schrieb:
> Eric B. schrieb:
>
>> Probier mal so:
>
> Das geht leider nicht, da ich nicht nur case0 habe sondern weiter bis
> case7. Die habe ich nur zum Testen weggelassen.

Dann mach halt ein switch/case anstatt der if-Afbrage für den 
state_conuter. Der wichtige Punkt war den state_counter nicht im ISR 
sondern in der main -Schleife zu inkrementieren.

von Karl H. (kbuchegg)


Lesenswert?

Eric B. schrieb:
> Bruno M. schrieb:
>> Eric B. schrieb:
>>
>>> Probier mal so:
>>
>> Das geht leider nicht, da ich nicht nur case0 habe sondern weiter bis
>> case7. Die habe ich nur zum Testen weggelassen.
>
> Dann mach halt ein switch/case anstatt der if-Afbrage für den
> state_conuter. Der wichtige Punkt war den state_counter nicht im ISR
> sondern in der main -Schleife zu inkrementieren.

Ich würds sogar umgekehrt machen.
Ich würde die ganze LCD Statemaschine in die ISR verfrachten.
Der Code sieht zwar recht umfangreich aus, aber da immer nur 1 Pfad 
durch den switch case genommen wird, ist das zur Laufzeit nicht wirklich 
ein Problem.
Was aber ein Problem sein kann: wenn in der Hauptschleife an anderer 
Stelle getrödelt wird. Die LCD Ansteuerung muss aber deswegen trotzdem 
zuverlässig Status für Status weiterlaufen. Mit dem Code in der ISR ist 
das gewährleistet, solange die Interrupts aktiviert sind und nicht 
gerade eine andere ISR trödelt.
Das wäre mir wichtiger als das (oft falsch verstandene) Dogma: "ISR so 
kurz wie möglich". Tatsächlich sollte es lauten "So kurz wie möglich 
aber so lang wie notwendig". Und die Notwendigkeit ist hier nunmal, dass 
das LCD zuverlässig seine Umschaltungen kriegt.

: Bearbeitet durch User
von Bruno M. (brumay)


Angehängte Dateien:

Lesenswert?

Karl Heinz schrieb:

> Alleine schon
> die Idee eines derartigen Sprunges zeigt ... ja, was ... das dir so
> manches nicht wirklich klar ist. Assembler hin, C her.

Trotz dieser schlauen Sprüche habe ich mein Programm fertig. Es ist in 
manchen Dingen vielleicht nicht ganz professionell, aber es 
funktioniert.

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.