AVR und GCC machen Unfug!?!?!

Gast #364166
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!!!
Gast #364168
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?
Gast #364172
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
Gast #364173
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
Moderator Persönliche Seite #364177
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.
Gast #364178
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...)
Gast #364179
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
Gast #364180
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! :-)
Angehängte Dateien:
Gast #364181
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren