www.mikrocontroller.net

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


Autor: Retzo (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M103 Fuse


Peter

Autor: VanKurt (Gast)
Datum:

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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steht im Datenblatt...

Ralf

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

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

Autor: VanKurt (Gast)
Datum:

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

Autor: peter dannegger (Gast)
Datum:

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

Autor: Branko Golubovic (Gast)
Datum:

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

Autor: Retzo (Gast)
Datum:

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

Autor: Retzo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Es ist ein AT90S8515, sorry :-(

Autor: Stefan (Gast)
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: Retzo (Gast)
Datum:

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

Autor: peter dannegger (Gast)
Datum:

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

Autor: Retzo (Gast)
Datum:
Angehängte Dateien:

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

Autor: A.K. (Gast)
Datum:

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

Autor: peter dannegger (Gast)
Datum:

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

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.