-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: Programm wird nur einmal durchlaufen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2009
    Beiträge
    10

    Programm wird nur einmal durchlaufen

    Anzeige

    Hallo Liebe Robotergemeinde.
    Ich hab von nem Freund ein RN-Control geschenkt bekommen. Ich mich deshalb einbisschen mit der Programmierung von Mikrocontroller auseinandergesetzt. Hab auch ein paar Progrämchen geschrieben. Leider bleib ich an einem Ort hängen und zwar bei if und else...
    Mein Ziel wäre es das sich bei Tastendurck auf einer der 5 Tasten etwas verändert und zwar die LEDs. Leider muss ich jedes mal wieder auf die Taste Reset drücken damit sich was ändert, was eigentlich nicht sein sollte. Ich schätze mal das liegt daran, dass das Programm nur einmal durchlaufen wird.
    Das Programm sieht so aus:
    Code:
    #include <avr/io.h>
    
    int main (void)
    
    {
    
    DDRA = 0x00;
    if (PINA & (1<<PINA7)) //Bedingung1
    {
    DDRC = 0xff; //Port c als Ausgang
    PORTC = (1<<PC0); //Alle LEDs ausser LED1 sollten leuchten
    }
    else
    
    {
    DDRC = 0xff;  //Erneut als Ausgang definieren, weil 
                  //es nicht mehr im selben Blck ist wie voher
    PORTC = (1<<PC1); //Alle LEDs ausser LED2 sollten leuchten
    }
    for (;;) //Endlosschleife
    
    return 0; //Wieder an den Anfang
    
    }
    Vielleicht entdeckt jemand einen Fehler?
    [-o<
    Karl

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von vohopri
    Registriert seit
    11.09.2004
    Ort
    südlich der Alpen
    Beiträge
    1.708
    Hallo Karl,

    du hast auch alle Abfragen und Aktionen vor die For Schleife gestellt, anstatt hinein in die Schleife.

    Dafür gehört das return nicht in in die Schleife. return 0 hat nichts mit "wieder an den Anfang" zu tun. In der Hilfe steht, was es bedeutet.

    grüsse,
    Hannes

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    30.08.2006
    Ort
    Frankfurt
    Alter
    26
    Beiträge
    62
    Hi,

    Ich verwende als Endlos Schleife immer while(1)

    Code:
    #include <avr/io.h>
    
    int main (void)
    
    {
    
    while(1) {
    
    DDRA = 0x00;
    if (PINA & (1<<PINA7)) //Bedingung1
    {
    DDRC = 0xff; //Port c als Ausgang
    PORTC = (1<<PC0); //Alle LEDs ausser LED1 sollten leuchten
    }
    else
    
    {
    DDRC = 0xff;  //Erneut als Ausgang definieren, weil
                  //es nicht mehr im selben Blck ist wie voher
    PORTC = (1<<PC1); //Alle LEDs ausser LED2 sollten leuchten
    }
    
    } // Ende der While Schleife
    
    return 0; //Wieder an den Anfang
    
    }
    Jetzt wird einfach die komplette int main(void) unendlich oft wiederholt.

    Ich glaube du kannst auch die Definition PortC als Ausgang außerhalb der Schleife setzen, dann musst du sie nicht immer neu Definieren.

    Ich bin in C auch noch nicht ganz so weit. Kann durchaus sein, dass die while schleife falsch gesetzt ist.

    Gruß
    Spanky

    EDIT: Hmm eben war wieder Critical Error. Hätte nicht gedacht das mein Beitrag ankommt.^^

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Probier mal den Code:
    Code:
    #include <avr/io.h>
    
    int main (void)
    
    {
    
    while(1)
    {
    DDRA = 0x00;
    if (PINA & (1<<PINA7)) //Bedingung1
    {
    DDRC = 0xff; //Port c als Ausgang
    PORTC = (1<<PC0); //Alle LEDs ausser LED1 sollten leuchten
    }
    else
    
    {
    DDRC = 0xff;  //Erneut als Ausgang definieren, weil
                  //es nicht mehr im selben Blck ist wie voher
    PORTC = (1<<PC1); //Alle LEDs ausser LED2 sollten leuchten
    }
    
    };
    
    }

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.383
    DDRC = 0xff; //Erneut als Ausgang definieren, weil
    //es nicht mehr im selben Blck ist wie voher
    das hat nichts mit dem "block" zu tun, wenn du etwas in den registern des controller veränderst ist es statisch, soll heissen verändert sich nur, wenn du etwas veränderst! das gilt auch für variablen, jede variable die du in deinem programm einmal verwendest (ausser natürlich rekursivaufrufe) wird immer wiedern an der selben speicherstelle liegen

    das ständige "neu einstellen" kostet dich 125nS @ 16Mhz

    also das doppelte DDRC raus, udn alle DDRs falls du sie zur programmlaufzeit nicht ändern willst, VOR die while(1)


    PS: das war nicht gegen dich WKrug, eher ein zeichen an den "code-kommentator"

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    @ spanky & wkrug: Wenn Ihr Euch selber nicht sicher seid, solltet Ihr nicht antworten. Das verunsichert doch nur...

    1. Initialisierungen gehören nicht in eine Schleife.
    2. Hinter eine geschweifte Klammer kommt niemals ein Semikolon
    3. Das return 0; gehört immer ans Ende der main-Funktion hat aber nichts mit "wieder an den Anfang" springen zu tun.

    Ein korrektes Programm sähe so aus:

    Code:
    #include <avr/io.h>
    
    int main (void)
    
    {
    DDRA = 0x00; //PORTA als Eingang definieren (kann man sich aber auch schenken, da Standart-Einstellung)
    DDRB = 0xFF; //PORTB als Ausgang definieren
    
    for (;;) //Beginn der Endlosschleife
    {
    
    if (PINA & (1<<PINA7)) //Bedingung1
    PORTC = (1<<PC0); //Alle LEDs ausser LED1 sollten leuchten
    
    else
    PORTC = (1<<PC1); //Alle LEDs ausser LED2 sollten leuchten
    
    } //Ende der Endlosschleife
    
    return 0;
    }
    PS: Ob man while(1) {} oder for(;;){} für die Endlosschleife verwendet, ist eigentlich egal. Laut einer Application Note von Atmel ist die for-Variante aber effektiver (warum auch immer).

    Gruß,
    askazo

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Das mit der Initialisierung hab ich glatt übersehen.
    Die Variante mit der for( ; ; ) war mir unbekannt - wieder was dazu gelernt.
    Vermutlich kommt es auch auf den Compiler an, was der draus macht.

    Bei einer If Anweisung sind bei den Code Templates nach der geschweiften Klammer immer ";" dran - Jedenfalls bei meinem Compiler.
    Wenn die Entwickler von Compiler Software sowas machen, dürfte es nicht ganz verkehrt sein ?!

    CodeVision verwendet für die Haupschleife nur die while(1) Variante.
    Das return 0 hab ich rausgenommen, wenn Dir das aufgefallen ist, weil es ja keinen Sinn macht, ohne eine Funktion aufgerufen zu haben.
    Anscheinend ist das aber wieder Compiler abhängig.

    Die Anweisung int main(void) kommt mir auch etwas seltsam vor.
    Sollte es nicht void main(void) heissen ?

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Hab's gerade mal mit dem GCC ausprobiert - ein Semikolon hinter der geschweiften Klammer lässt er tatsächlich ohne zu meckern zu.
    Gängig ist das aber nicht, ich hab's zumindest bis jetzt noch nie in einem C-Code gesehen.

    Wie die main-Funktion auszusehen hat, scheint wirklich Compiler-abhängig zu sein. Der GCC möchte auf jeden Fall einen Rückgabewert haben, auch wenn's eigentlich sinnlos ist. Aber ansonsten gibt's ne Warnung.
    Und wenn man einen Rückgabewert hat, muss man die Funktion natürlich auch dementsprechend deklarieren, daher int main(void)....

    Das mit der for(;;)-Schleife scheint allerdings Compilerunabhängig zu sein. Zumindest bezieht sich die entsprechende Application-Note nicht auf einen bestimmten Compiler. Hier der Link dazu:
    http://www.atmel.com/dyn/resources/p...ts/doc1497.pdf
    siehe S.19

    [edit]Die Application-Note scheint doch für einen bestimmten Compiler zu gelten, und zwar für den IAR. Naja, ich lass' es trotzdem mal so stehen...[/edit]

    Gruß,
    askazo

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.383
    der winavr compiler muckt bei void main rum, und wenns int main ist verlangt er auch nach return 0; auch wenns nie erreicht wird

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2009
    Beiträge
    10
    Hallo.
    Die Antworten sind ja massenhaft gekommen. Danke euch!

    Jetzt ists auch gegangen, das Problem war, dass ich while (1) oder for (; eben für return genutzt und nicht am Anfang gesetzt.

    Lg

    Karl

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •