mikrocontroller.net

Forum: Compiler & IDEs Lauflicht in C


Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend.

Mache gerade meine ersten Versuche mit C. Ich probiere jetzt schon ne 
ganze Zeit herum, ein Lauflicht auf Portb auszugeben (nur im AVR 
Studio,--> daher kein delay),aber ich kann den Fehler nicht entdecken.

Könnte mal jemand kurz draufschauen?

#include <avr/io.h>

int main (void)

 {
  int x,y;

   DDRB  = 0b11111111;
   PORTB = 0b00000000;
loop1:
     x = 7;y=1;
 {
      while (x >= 0)
      {
          PORTB = y;
        y=y*2;
          x--;
    }
  {
  x = 7;y=64;
    while (x >= 0)
        PORTB = y;
        y=y/2;
        x--;
      }}
  goto loop1;
   return 0;
}


Also die erste while Schleife funktioniert ja noch, aber bei der zweiten 
da bleibt er dann hängen. Was mach ich da falsch? Kann das daran liegen, 
das man zu viele geschwungene Klammern hat?

Gruß Walter

Autor: uwegw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rück das Zeug mal vernünftig ein, dann wirst du schon bemerkren, wo da 
die geschweiften Klammern falsch sitzen.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt mal so gemacht, geht aber doch noch nicht. Ist da wirklich ne 
Klammer schuld, oder was anderes?



#include <avr/io.h>

int main (void)

 {
    int x,y;

     DDRB  = 0b11111111;
     PORTB = 0b00000000;
loop1:
  {
     x = 7;y=1;
     {
        while (x >= 0)
      {
            PORTB = y;
          y=y*2;
            x--;
      }
      }
  x = 7;y=64;
    {
      {
      while (x >= 0)
        PORTB = y;
        y=y/2;
        x--;
      }
    }
  }
  goto loop1;
   return 0;
}

Autor: guro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter schrieb:
--------------------
while (x >= 0)
        PORTB = y;
--------------------

wird da irgendwo 'x' verändert?
schätze, du musst noch mal ein c-tutorial durcharbeiten.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt geschafft. Falls ein Anfänger es brauchen kann, hier mein 
Anfänger Code:

#include <avr/io.h>

int main (void)

{
    int x,y;

     DDRB  = 0b11111111;
     PORTB = 0b00000000;
loop1:
  {
     x = 7;y=1;
     {
        while (x >= 0)
       {
            PORTB = y;
          y=y*2;
            x--;
      }
    }


  x = 5;y=64;
    {
      while (x >= 0)
      {
          PORTB = y;
          y=y/2;
          x--;
      }
    }
  }
  goto loop1;
   return 0;
}


Danke für Eure Antworten.

Gruß Walter

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, das geht auch mit weniger Klammern...
#include <avr/io.h>

int main (void)

{
    int x,y;
     DDRB  = 0b11111111;
     PORTB = 0b00000000;

loop1:

     x = 7;y=1;
      while (x >= 0)
       {
            PORTB = y;
          y=y*2;
            x--;
      }

   x = 5;y=64;
    while (x >= 0)
      {
          PORTB = y;
          y=y/2;
          x--;
      }

   goto loop1;
return 0;
}

Autor: Thomas^ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Anfänger sollten das:

> loop1:
> {
> ...
> }
> goto loop1;

am Besten durch ein

for (;;)
{
...
}

ersetzen.
In meinem C-Buch wird ein goto auch nur ganz zum Ende erwähnt.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder durch ein

do{
.
.
.
}while(1);

Da mit goto ein komplexeres Orogramm sehr unübersichtlich wird!
Habe für ein goto eine auf den Deckel bekommen von meinem Prof!!!

Autor: Thomas^ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt Fälle wo ein goto sicher sinnvoll oder einfach 
praktischer/übersichtlicher ist.

Aber gerade eine Endlosschleife lässt sich mit einem for(;;) oder 
while(1) sofort erkennen, was bei einem goto nicht der Fall ist.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab da jetzt noch ein Programm probiert. Das gleich hab ich damals vor 
15 Jahren mit meinem C64 in Basic angestellt. Einen Zapfenrechner..

Also ich hab da jetzt statt dem goto eine for schleife am Anfang 
eingebunden. Stimmt das so, das ich dann i einfach nie mit ++ 
incrementiere?

Hier das Beispiel:

#include <cstdlib>
#include <iostream>

using namespace std;

int main ()
{
    int zapfen,n,i,ergebnis;

for (i=0;i=1;i)       //loop: Anfang ohne ++
    {
         cout << "\nWelchen Zapfen willst du berechnen? ";
         cin >> zapfen;



         for (n=2;n<12;n++)
             {
                       ergebnis = zapfen*n;
                       cout << " \n\t" << ergebnis;
                       zapfen = ergebnis;

             }



         for (n=2;n<12;n++)
             {
                       ergebnis = zapfen/n;
                       cout << " \n\t" << ergebnis;
                       zapfen = ergebnis;

             }
    }

    //goto loop; Ende und wieder zum Anfang

    return 0;
}


Gruß Walter

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups...

for (n=2;n<12;n++)

soll eigentlich

for (n=2;n<10;n++)

heißen.

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

Bewertung
0 lesenswert
nicht lesenswert
> for (i=0;i=1;i)       //loop: Anfang ohne ++

Na ja.
Das ist eine eher unübliche Schreibweise.
Zuächst mal ist  i = 1  nicht das was du denkst das
es ist. Das ist eine Zuweisung und kein Vergleich!

Die Syntax einer for Schleife ist:

  for( Initialisierungsteil;
       Schleifenabbruchbedingung;
       Anweisung die am Ende eines jeden Schleifendurchgangs
       durchgeführt wird )

Nun. Du willst eine Endlosschleife. Dazu brauchst du aber
keine Variable. Daher brauchst du auch nichts zu initialisieren
und du brauchst auch die keine Anweisung am Ende jedes
Schleifendurchlaufs. Daher können die beiden Teile auch
leer sein.

Alles was du brauchst ist die Schleifenabbruchbedingung.
Das ist irgendein Ausdruck, der logisch wahr ergibt. In
C ist aber jeder arithmetische Ausdruck auch gleichzeitig
ein logischer Ausdruck, wobei 0 als logisch falsch gewertet
wird und alles was nicht 0 ist als logisch wahr gewertet wird.
Das heist aber auch: Ein simples 1 ist bereit logisch wahr.

Eine for-Schleife für eine Endlosschleife schreibt man
daher so:

   for( ; 1; ) {
   }

ABer auch das würde man so nicht machen. Zum einen ist das
viel zu viel Schreibaufwand, zum anderen sieht das etwas
seltsam aus. Daher das sehr viel einleuchtendere:

    while( 1 ) {
    }

Autor: AVR-Jünger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Eine for-Schleife für eine Endlosschleife schreibt man
>daher so:

>   for( ; 1; ) {
>   }

for(;;) sollte sogar reichen (je nach Compiler...).

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die ersten Schritte.

Es funktioniert beides.

2 letzte Fragen noch.

Zum programmieren für die AVR`s, sollte ich mich da auf C oder C#, <-- 
falls da ein Unterschied besteht, oder auf C++ spezialisieren?

Gehört da auch Visual C dazu?

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

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mich auf C stürzen.

C++:  der gcc hat zwar C++ Unterstützung. Allerdings wirst du
      auf einem Mega8 oder Mega16 nur eher spärlich in
      typischer C++ Manier programmieren können. Bei den
      beschränkten Resourcen kann C++ seine Vorteile nicht
      wirklich ausspielen.
      C++ ist eher was für etwas 'größere' Maschinen

C#:   Nun ja. Die notwendige Runtime sowie die Klassenbibliothek
      haben auf einem PC schon ein paar Megabytes. Mit dem paar
      KB in einem Mega8 wird das wohl nichts.


Visual C
********
   Die Programmiersprache heist C
   Ein spezifisches Produkt eines bestimmten Herstellers, der
   unter anderem auch einen C Compiler samt Programmierumgebung
   dazu anbietet und verkauft, heist Visual C.
   Ist ein bischen so wie PKW und VW-Käfer. Ein VW-Käfer ist
   ein spezifischer PKW. Aber neben dem Käfer gibt es natürlich
   noch andere PKW.

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Atmel hat dazu eine AppNote AVR035 ( 
http://atmel.com/dyn/resources/prod_documents/doc1497.pdf )
Efficient C Coding for AVR:

Dort steht über Endlosschleifen, dass sie mit for(;;){} den wenigsten 
Speicher verbrauchen. Könnt ihr gern ausprobieren; ein paar Byte werden 
bei AVR-GCC eingespart.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin,

>Dort steht über Endlosschleifen, dass sie mit for(;;){} den wenigsten
>Speicher verbrauchen. Könnt ihr gern ausprobieren; ein paar Byte werden
>bei AVR-GCC eingespart.

na zeig mal bitte. kann ja jeder behaupten :)
bye kosmo

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl-Heinz:
Du schreibst 0 wird als logisch flasch ausgewertet. Jetzt bin ich völlig 
verwirrt. Vor ein paar Tagen habe ich gedacht jetzt habe ich es endlich 
gerafft und nun schreibst du das völlige Gegenteil. Ich dachte 0=Wahr 
und !=0 ist falsch. Was den nun jeder schreibt was anderes.....

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

Bewertung
0 lesenswert
nicht lesenswert
Definitiv:

0 ist 'logisch falsch'
und alles was nicht 0 ist gilt als 'logisch wahr'

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  if (0)
    cout << "0 ist wahr" << endl;
  if (1)
    cout << "1 ist wahr " << endl;

Du hast recht wenn ich das compilire wird das 2. ausgegeben.
Jetzt hoffe ich das ich es mir endlich merken kann....
wobei das eigenltich auch logisch ist. Aber irgendwo wars mal anders und 
seitdem kann ichs mir nimmer merken....

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@kosmonaut pirx:
dann öffne mal die AppNote, geh auf Seite 21 und schau unter Punkt 7.

Wenn du das nicht glaubst, dann kompilier doch mal eine Endlosschleife 
mit while(1) und einmal mit for(;;), dann wirst schon sehen, dass die 
zweite Lösung kleiner ist.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@wulf:
ich glaube dir, das das da steht. aber man muss ja nicht alles blind 
glauben :)

ein experiment gehört immer dazu. man nehme folgendes beispiel für den 
atmega32 uart:
#include <avr/io.h>

int main(){
  uint8_t __br = 25;
  UBRRH = __br >> 8;
  UBRRL = __br;
  UCSRB = (1 << RXEN) | (1<<TXEN);
  UCSRC = (1 << URSEL) | (3<<UCSZ0);

//  while(1){
  for(;;){
    loop_until_bit_is_set(UCSRA, UDRE);
    UDR = 0x41;
  }
}

gcc version 4.1.1, -O0 (optimierung aus)

avr-size output
mit for-loop:
text    data     bss     dec     hex
92       0       0      92      5c

mit while-loop:
text    data     bss     dec     hex
92       0       0      92      5c

auch mit optimerung -O1 oder -Os ändert sich nichts, einfach mal so 
glauben, bin nur zu unfleißig, das auch noch zu posten.

hilf mir auf die sprünge, wenn ich einen fehler gemacht habe.
bye kosmo

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmmm...

interessant.
ich hab mit AVR Studio 498 Build
und AVR-GCC bei Optimierung -Os
der MCU ist ein Mega8;
da hab ich (nur durch Änderung der Schleife) 2 Byte einsparen können.

Allerdings muss ich dir Recht geben, jetzt gerade ein kleines Stück Code 
kompiliert und da geht nix. Vielleicht ist das nur bei größerem Code in 
der Schleife?!?

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.