Forum: Compiler & IDEs AVR und GCC machen Unfug!?!?!


von Retzo (Gast)


Lesenswert?

Hallo Leute!
Ich hab hier ein kleines, einfaches Programm. Allerdings wird der Code
unlogisch und FALSCH auf meinem AVR ausgeführt!

Die Sitution ist folgende: am Port C hängt eine LED. Der folgende Code
schaltet diese ein, und dann nach 2 Sekunden aus. So:


//-------------- INCLUDES
------------------------------------------------
#include <avr/io.h>      // Input/output an den Pins
#include <avr/interrupt.h>  // Interrupts


//-------------- DEFINES
------------------------------------------------
#define FRAMES_PER_MS 11


//-------------- GLOBALS
------------------------------------------------
unsigned int  msCounter      = 0;        // MilliSekunden Zähler


//-------------- PROTOTYPES
------------------------------------------------
void ledAus( void );



int main(void)
{
  // Timer initialisieren
  TCCR0 |= (1<<CS00)|(1<<CS02);

  DDRC = 0xff;  // C als Ausgang
  PORTC = 255;  // C anschalten

  // MainLoop
  while(1)
  {
    // Timer und MS aktualisieren
    if( TCNT0 > FRAMES_PER_MS )      // Eine Millisekunde ist vergangen
    {
      TCNT0 -= FRAMES_PER_MS;
      msCounter++;

      if( msCounter > 2000 )  // Alle 2 Sekunden...
      {
        msCounter -= 2000;
        ledAus();
        //PORTC = 0; // -HIER OBACHT WICHTIG!!!
      }//end if
    }//end if
  }//end while

}//end main


void ledAus( void )
{
  PORTC = 0;
}//end doSingleBeep

Es sollte sofort klar sein, was dieser Code tut ;-)
Jetzt aber zum Problem: Eigentlich sollte es ja keinen Unterschied
machen, ob die Zeile mit "PORTC = 0; // -HIER OBACHT WICHTIG!!!" drin
ist oder nicht. Der Port wird ja so oder so auf 0 gesetzt.... Aber halt!
Das wird er eben nicht!!! Wenn ich die Zeile nämlich rauskommentiere,
bleibt die LED leuchtend. Nur mit dieser Zeile geht sie aus. Was soll
das?
Kann es sein, dass die Funktion "ledAus" garnicht ausgeführt wird???

Ist mein C-Verständnis falsch, oder was könnte hier das Problem sein?
Danke für eure Hilfe!!!

von Peter D. (peda)


Lesenswert?

M103 Fuse


Peter

von VanKurt (Gast)


Lesenswert?

Hi Peter!
Ich hab mal danach Gegoogelt, bin aber nicht wirklich schlau draus
geworden... Was ist so ein Fuse eigentlich, und viel Wichtiger: kann
ich diesen bösen M103 irgendwo an/aus schalten?

von Ralf (Gast)


Lesenswert?

Steht im Datenblatt...

Ralf

von Karl H. (kbuchegg)


Lesenswert?

Zunaechst mal sollten wir etwas abklaeren:
Arbeitest Du mit einem Mega128?

Nur bei diesem Prozessor gibt es diese Fuse und koennte
das von dir beobachtete Verhalten erklaeren.

von VanKurt (Gast)


Lesenswert?

Nein, tu ich nicht. Ich habe einen 90815 dingsbums ;-)
Aber wenn es daran nicht liegt, was soll es dann sein? Der Code ist
doch Wasserdicht!!! creeep

von peter dannegger (Gast)


Lesenswert?

"Ich habe einen 90815 dingsbums"


Wenn Du jetzt noch die richtige und vollständige Bezeichnung angibst
und das bereits am Anfang getan hättest, hätten wir uns ne Menge
Rumraterei gespart.


Peter

von Branko Golubovic (Gast)


Lesenswert?

>Aber wenn es daran nicht liegt, was soll es dann sein? Der Code ist
>doch Wasserdicht!!!

Eben nicht!

 >   if( TCNT0 > FRAMES_PER_MS )   // Eine Millisekunde ist vergangen
     Hier ist TCNT0=FRAMES_PER_MS +1
 >  {
 >    TCNT0 -= FRAMES_PER_MS; // 1 bleibt übrig

TCNT0 erhöht sein Inhalt bei jedem Durchlaf (1,2,3...) und am ende ist
Bendigung if(TCNT0 > FRAMES_PER_MS)  immer erfült bis zum Überlauf.

     TCNT0 =0; // Sollte richtig sein

>if( msCounter > 2000 )  // Alle 2 Sekunden...
>      {
>       msCounter -= 2000;//???

        msCouter=0; //

oder noch besser:
    if( msCounter >= 2000 )
      {
       msCouter=0;


Branko

von Retzo (Gast)


Lesenswert?

Das Timing ist ja garnicht so wichtig. Das funktioniert sogar!
Das Problem ist ja ein anderes - nämlich dass mit der rauskommentierten
Zeile...
(im andren Fall geht die LED genau nach 2 Sek. aus!)

von Retzo (Gast)


Lesenswert?

@Peter:
Es ist ein AT90S8515, sorry :-(

von Stefan (Gast)


Lesenswert?

Wenn ein Bug im AVR-GCC vermutet wird, dann braucht man zur Kontrolle
mindestens die Versionsnummer des GCC. Damit kann man in der Buglist
http://rtems.org/phpwiki/index.php/GCCAVRBugs nachsehen. Nicht schlecht
wären z.B. Angaben zu eventuell verwendeten Optimierungseinstellungen
und ggf. auch noch die produzierte Assemblerdatei (*.s).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich habe (GCC 3.4.4, -Os) das Ganze im VMLAB simuliert, und
nachdem der Counter die 2000 erreicht hat, schaltet die LED
korrekt um (bei mir ist sie dann ein, da in VMLAB die LEDs
gegen Vcc geklemmt werden).  Sie schaltet natürlich nie wieder
zurück, weil du diese Funktionalität nicht implementiert hast.

Wäre auch schön, wenn du statt magischer Konstanten lieber die
CPU-Frequenz mit hingeschrieben hättest und dann den Wert 11
für die Millisekunde daraus abgeleitet (per Formel).  Compiler
können selbst rechnen, man muss also nicht unbedingt alles mit
dem Taschenrechner vorher ausrechnen.

von Retzo (Gast)


Lesenswert?

"Wäre auch schön, wenn du statt magischer Konstanten lieber die
CPU-Frequenz mit hingeschrieben hättest und dann den Wert 11
für die Millisekunde daraus abgeleitet (per Formel)"

Darum gehts es ja auch garnicht ;-) Man könnte das mit dem Timing
glaubich vollkommen ignorieren. Es ist ja nur so, dass die LED
irgendwann ausgehen soll. Egal ob jetzt genau 2 Sekunden oder nicht.

"Angaben zu eventuell verwendeten Optimierungseinstellungen
und ggf. auch noch die produzierte Assemblerdatei (*.s)."

Oha, da hab ich gar keine Ahnung (habe nichts bestimmtes
eingestellt...)

von peter dannegger (Gast)


Lesenswert?

Stell doch einfach mal den wirklichen Quelltext, einmal den
funktionierenden und einmal den nicht funktionierenden als Anhang
rein.

Oftmals sind Leute nicht dazu fähig, d.h. sie stellen etwas völlig
anderes rein, als das, was sie ausprobiert haben.

Und dann sucht man sich natürlich dumm und dämlich.


Probier auch mal aus, ob es einen Unterschied macht, ob das main() oder
ledAus() die letzte Funktion ist.

Mit ledAus() als letzte Funktion klappt nämlich das Einfügen des
Quelltextes ins Listing nicht mehr, d.h. das Listing ist schwerer zu
lesen.


Peter

von Retzo (Gast)


Angehängte Dateien:

Lesenswert?

OK, ich habe den Code jetzt so umgestrickt, dass er nur noch halb so
lang ist, und ohne Timer auskommt. Aber immernoch macht das Ding
totalen Quatsch!

Für alle, die's nicht runterladen wollen:

Code 1  (LED leuchtet nicht!!!):

//-------------- INCLUDES
------------------------------------------------
#include <avr/io.h>      // Input/output an den Pins
#include <avr/interrupt.h>  // Interrupts

void ledAus( void )
{
}//end ledAus

int main(void)
{
  DDRC = 0xff;  // C als Ausgang
  PORTC = 255;  // C anschalten

  while(1)  {;}
}//end main



Code 2  (LED leuchtet!!!):

//-------------- INCLUDES
------------------------------------------------
#include <avr/io.h>      // Input/output an den Pins
#include <avr/interrupt.h>  // Interrupts

//void ledAus( void )
//{
//}//end ledAus

int main(void)
{
  DDRC = 0xff;  // C als Ausgang
  PORTC = 255;  // C anschalten

  while(1)  {;}
}//end main


Wie ihr seht ist nur die eine Funktion herauskommentiert, DIE ABER DOCH
GAR KEINE AUSWIRKUNGEN AUF DAS PROGRAMM HABEN DÜRFTE!!!! Oder sehe ich
da was falsch???

Danke für eure Hilfe! :-)

von A.K. (Gast)


Lesenswert?

Programm ist korrekt, Ergebnis ist korrekt. Bei mir jedenfalls. Daher
wird's nötig, dass du deutlich mehr als bisher rausrückst -
Compiler/Winavr-Version, in welcher Umgebung du das baust, evtl. das
Makefile oder APS-File, oder was auch immer du verwendest, Info über
den kompletten Weg mit dem du vom C-File zum Controller kommst. Denn
mit der von dir bisher gelieferten Info ist das schlichtweg nicht
reproduzierbar und auch nicht zu erraten.

von peter dannegger (Gast)


Lesenswert?

Der M103-Fehler ist im Prinzip der, daß man für ein falsches Target
kompiliert.

Kann also auch mit dem AT90S8515 passieren, wenn Du den nicht als
Target gesetzt hast.


Peter

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.