mikrocontroller.net

Forum: Compiler & IDEs "Wait"-Befehl in GCC?


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

habe bisher meine allerersten µC-Programmier-Anfänge mit BASCOM gemacht.

Nun habe ich mir gedacht, einmal auf das AVR Studio 4 (mit GCC -> 
WinAVR) umzusteigen. Nun möchte ich für eine Modelleisenbahn ein 
Blinklicht für eine Ampel programmieren. Die Ampelphasen kennt ja 
jeder...

Nur, welchen Befehl gibt es und WIE kann ich den BASCOM-"Wait"-Befehl in 
C schreiben? Möchte schließlich 3 sekunden rot-phase, 1 sek. grün, usw.

Bitte um eine detaillierte BEschreibung.

PS: Habe zwar den delay_ms (var); schon gefunden, aber wenn ich das 
Programm dann nach dem Compilieren im AVR Studio "simuliere" (ohne den 
µC zu programmieren) dann öffnet er immer, an der stelle wo delay_ms 
steht die Header-Datei  und springt zu dieser delay_ms funktion HILFEE!

vielen dank!

Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus den verwendeten Tools schliesse ich einfach mal darauf,das du einen 
AVR programmieren willst. :)

Darf ich fragen,wieso du das nicht mit einem Timer löst?Vom ganz kleinen 
Tiny bis zum Mega128 sind in jedem Derivat mindestens ein Timer 
nutzbar,in vielen sogar mehrere.Den Timer initialisieren kostet dich 
keine 3 Zeilen Code und 15min Studium des Datenblattes zum Controller.Um 
diese Lektüre wirst du nicht umhin kommen,wenn du deinen AVR ernsthaft 
in C programmieren willst.

Falls du noch gar keine Erfahrung in der hardwarenahen Programmierung 
hast,würde ich dir empfehlen mal einen Blick in das AVR-GCC Tutorial 
hier auf der Seite zu werfen,da sind die Grundlagen in deutscher Sprache 
erläutert.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke erstmal

wofür steht aber dieses CS00?

Ist es nicht etwas mühselig, durch Vorteiler auf exakt eine Sekunde zu 
kommen?
Ich weiß nicht, wie es bei BASCOM im Hintergrund funktioniert. Jedoch 
wird es kein Timer gewesen sein, denn BASCOM kann wohl nicht einen 
"kostbaren" Timer für einen wait-Befehl ohne mein Wissen 
"verschwenden"?!

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

Bewertung
0 lesenswert
nicht lesenswert
Johannes wrote:

> wofür steht aber dieses CS00?

Für das 0. ClockSelect-Bit des Timers 0.

> Ist es nicht etwas mühselig, durch Vorteiler auf exakt eine Sekunde
> zu kommen?

Irgendwie musst du den Prozessortakt immer herunterteilen (wenn er
nicht gerade 1 Hz ist :).  Warum willst du sinnlos Energie in der CPU
verheizen, indem du sie mit dem Herunterzählen eines Registers
beschäftigst, wenn du stattdessen einen Hardware-Timer völlig im
Hintergrund mit der Aufgabe betrauen kannst?  (Wenn die CPU nichts zu
tun hat derweil, kannst du sie mit sleep_mode() noch in den Idle-Modus
versetzen, damit sie Strom spart.)

> Ich weiß nicht, wie es bei BASCOM im Hintergrund
> funktioniert. Jedoch wird es kein Timer gewesen sein, denn BASCOM
> kann wohl nicht einen "kostbaren" Timer für einen wait-Befehl ohne
> mein Wissen "verschwenden"?!

Warum nicht?  BASCOM hat ein Laufzeitsystem (anders als C und die
avr-libc).  Es ist völlig logisch, dass es für die Implementierung
dieses Laufzeitsystems bestimmte Hardwareresourcen benutzen muss.
Üblich ist es, dass man einen "heartbeat"-Timer irgendwie
implementiert, der z. B. alle 10 ms oder auch alle 1 ms triggert und
dann eine Liste von Zeitgebern in der Software verwaltet.  Auf diese
Weise kann man sehr viele virtuelle Timer parallel implementieren
(jedoch nur mit einer Granularität eines "timer ticks").  Ich habe
keine Ahnung von BASCOM, kann mir aber vorstellen, dass es dort so
gelöst ist.

Für dich genügt natürlich erst einmal ein einfacher Timer.  Wenn du
einen der 16-bit-Timer benutzt, kannst du eine Sekunde Wartezeit bei
jeder beliebigen CPU-Taktfrequenz unmittelbar durch die Hardware
erzeugen lassen.  Wenn du mit dem Datenblatt nicht klar kommst, kannst
du uns ja auch noch den AVR verraten, den du benutzen willst sowie
dessen Taktfrequenz, dann kann dir hier jemand ein Rechenbeispiel
aufzeigen.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Simulieren des _delay_ms(); Makro ist langwierig (Breakpoints setzen 
und Tee trinken).

#include util/delay.h

volatile unsigned int i=0;  // volatile weil sonst vielleicht der 
Compiler die Schleife wegoptimiert.

for(i=0;i<1000;i++){_delay_ms(1);} // wartet circa 1Sek.

Das ist eine simple FOR Schleife die 1000mal durchlaufen wird und in der 
Schleife wird 1ms gewartet bzw. das Makro zaehlt eine Variable rauf o. 
runter.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

vielen Dank erstmal für die zahlreichen Antworten!
:-)

Also ich bin mir noch nicht ganz shclüssig welchen AVR ich denn 
verwende:
ich möchte also bis zu 6 Ampeln (je 3 LEDs, die auf einzelne Pins gehen) 
verwenden. Das macht dann schon mal 18 Ausgangspins.

Außerdem - als großes, weitentferntes Projekt, was mich jetzt noch nicht 
interessieren braucht - möchte ich ggf. die  Zeiten der Ampeln 
("Grün-/Gelb-/Rot-Phasenzeit") per RS232 am Notebook (Terminal - Visual 
Basic Programm) steuern.

Also zur Verfügung hätte ich ATTiny15 - die sowieso in dem Fall aus der 
Reihe fallen - ATMega8 und ATMega16.

Welcher wäre angebracht??

danke!

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, nimm erstmal den Mega16 dieser bietet dir 4*8 Bit Ports und bei 
deiner Stückzahl faellt der Preis gegenüber Mega8 auch nicht ins 
Gewicht.


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

Bewertung
0 lesenswert
nicht lesenswert
Außerdem kann man den ATmega16 mit einem Billig-Clone-JTAG-ICE
sogar via JTAG debuggen.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das macht dann schon mal 18 Ausgangspins.

Bau dir eine Schieberegisterkette aus 74HC595 auf.
Dann kannst du 100erte Leds oder Lichter anhängen
und jedes einzelne getrennt ein und ausschalten. Und das
ganze mit 4 Portpins.

Modelleisenbahner können doch nie genug Lichter
haben. Du wirst doch nicht für 6 popelige Ampeln
einen ganzen Mega16 verbraten, wenn der gleichzeitig
noch alle Lichter auf deiner Anlage steuern kann und
sich dabei immer noch langweilt.

Wenn du das geschickt aufbaust, dann baust du dir
einzelne Module mit je 1 oder 2 595 drauf wobei die
Module mit einer 5 Draht Leitung miteinander
verbunden werden. Wenn du mehr Lampen brauchst
hängst du an das bisher letzte Modul ein neues
Modul an und verfügst über 8 oder 16 Ausgänge mehr.
Programm angepasst und fertig.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hey, super Idee!

nun, im moment reizt mich das µC-Zeug aber gewaltig mehr als die 
Eisenbahn selber ;)

Ich habe schon ein Experimentierboard selbst aufgebaut (Lötarbeit: 
Nachbau des STK500). Auf dem ist auch ein ATmega16.

Werde dann wohl einen ATmega16 nehmen.

vielen dank für euere antworten!

PS: ich werde euch künftig höchstwahrscheinlich noch weiter mit dummen 
anfängerfragen belästigen! ;-)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch etwas :


wäre jemand vielleicht so freundlich und könnte mir samt kommentar 
schritt-für-schritt einen C-Code hier reinkopieren, wie ich nacheinander 
einen Timer für meinen ATmega16 aktiviere, um einen Takt von 1 sec.  in 
einer Funktion (wartezeit ();) zu bekommen?

vielen dank

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
siehe Codesammlung: Die genaue Sekunde von PD

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

Bewertung
0 lesenswert
nicht lesenswert
Lies mal hier:

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Lies dann auch weiter bis zum (und inklusive) dem
Kapitel über Interrupts.

Ich hab auch mal angefangen das Assembler Tutorial
um einen Abschnitt über Timer zu erweitern. Auch
wenn du nicht in Assembler programmierst: Die Vorgehens-
weise ist identisch.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
//---------------------------------------------------------
// Warte-Funktion (Delay)
// Parameter: Wartezeit in 0...65536 ms
// Stimmt exakt für -O1
// Stimmt ungefähr (5..10%) für andere Optimierungsstufen
//---------------------------------------------------------
void warte_ms(unsigned int wartezeit)
{
  volatile unsigned int i;    // Schlaufenzähler für Millisekunden-Loop
  while(wartezeit != 0)       // Schlaufe für jede Millisekunde
  {
    i = F_CPU/17000;          // Berechne Startwert für 
Millisekunden-Loop
    while(i != 0)             // Schlaufe, solange i nicht gleich null 
ist
    {
      i = i-1;                // i minus eins
    }                         // Schlaufen-Ende wenn i gleich null ist
    wartezeit = wartezeit-1;  // minus eine Millisekunde
  }                           // Schlaufen-Ende wenn wartezeit gleich 0 
ist
}                             // Funktionsende  => return

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-) Ein besonders schönes Beispiel für völlig sinnlose
Code Kommentierung.

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Herr Buchegger

Wenn hier etwas völlig sinnlos (und zudem noch total überflüssig) ist, 
dann ist es Dein Kommentar!

Die Funktion kommt per Copy&Paste aus meinem Lehrgang für unsere 
Elekroniker Azubi's, (C für uC, Lektion 2) daher die detaiilierten 
Kommentare!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry. Aber ein Kommentar ala

      i = i-1;                // i minus eins

ist ein Lehrbuchbeispiel für einen völlig sinnlosen Kommentar.
Die andern Kommentare der Statements sind auch nicht besser.

> aus meinem Lehrgang

Du solltest was anderes machen als unterrichten.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>    i = F_CPU/17000;          // Berechne Startwert für
>                                  Millisekunden-Loop

Der Kommentar ist sowas von bescheuert.
Was mich als Leser vielmehr interessieren würde:
Wie kommen die 17000 zustande? Warum gerade 17000, warum
nicht 16000
Aber darüber erzählt mir der Kommentar nichts.

Ein Kommentar soll nicht das wiedergeben, was sowieso
im Quelltext steht. Traurig, dass du als Lehrer das nicht
verstehst.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch eine Korrektur für die nächte Unterrichtsstunde:
Mit der Funktion lassen sich 65536ms nicht erreichen, da der Parameter 
Wartezeit zumindest als 16bit unsigned int nur die Werte 0..65535 
aufnehmen kann.

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, ich weiss auch ohne Ratschläge von irgendwelchen, hier im Forum 
herrumpöbelnden Klugscheissern, was ich zu machen habe!

Als Gleichung betrachtet ist i = i - 1 Unsinn, daher ist der Kommentar 
durchwegs gerechtfertigt, speziell für blutige Anfänger.

Vermutlich werden Dir meine Lerhlinge hier im Forum  schon bald 
wertvolle Programmiertips geben und Dir helfen, Deinen Code zu 
debuggen...!



Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Wolfram Danke!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Vermutlich werden Dir meine Lerhlinge hier im Forum  schon bald
> wertvolle Programmiertips geben und Dir helfen, Deinen Code zu
> debuggen...!

Da freu ich mich schon drauf :-)

Bevor du hier rumpöbelst solltest du dir mal
ein paar andere Antworten von mir in anderen
Threads zum Thema C reinziehen. Ich bin keineswegs
der Anfänger, für den du mich hältst. Ganz im
Gegenteil!


Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
//---------------------------------------------------------
// Warte-Funktion (Delay)
// Parameter: Wartezeit in 0...65535 ms
// Stimmt exakt für -O1
// Stimmt ungefähr (5..10%) für andere Optimierungsstufen
//---------------------------------------------------------
void warte_ms(unsigned int wartezeit)
{
  volatile unsigned int i;    // volatile um Optimierung zu verhindern
  while(wartezeit != 0)       // Schlaufe für jede Millisekunde
  {
    i = F_CPU/17000;          // 17000 Take je Schleifendurchlauf
    while(i != 0)             // Wieviele Takte dauert 
COMPARE(16BitWert)?
    {
     i--;                     // Wieviele Takte dauert DEC (16BitWert)?
    }
    wartezeit--;
  }
}

Was die einzelnen C-Befehle machen sollte in einem C-Lehrbuch erklärt 
sein und in den ersten Stunden gebracht werden.Auf dieses Wissen muss 
dann später aufgebaut werden können.Was ich vermisse,ist eine Rechnung 
WARUM die Berechnung exakt Stimmt und wieso der CPU-Takt durch 17000 
geteilt wird.Und das kann man nur anhand eines Disassembly ersehen (oder 
raten/probieren, aber sowas wird hoffentlich nicht gezeigt,oder?)

Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl-Heinz:

Ich hätte mich an deiner Stelle nicht gerechtfertigt.Manche Leute muss 
man auflaufen lassen.Nur schade um die Lehrlinge,die mit so mangelhafter 
Ausbildung versehen später mal auf reale Projekte losgelassen werden. :(

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> // Stimmt exakt für -O1

Hier fehlt der Zusatz, dass "stimmt exakt" nur exakt stimmt, wenn 
während der Ausführung der Schleife keine Interrupts auftreten.  Wird 
die Schleife durch Interrupts unterbrochen, verlängert sich die 
Delayzeit um die Ausführungszeit aller Interruptroutinen.  Die genaue 
Zeit, um die die Schleife verzögert, hängt dann also von externen 
Einflüssen ab, z. B. wie oft Daten an der seriellen Schnittstelle oder 
dem SPI-Interface des Controllers eintreffen, die etwa von einem PC oder 
einem anderen Baustein auf der Platine gesendet wurden.  Die zusätzliche 
durch die Interrupts bewirkte Verzögerungszeit kann dabei 
selbstverständlich beliebige Werte annehmen.

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ronny: Ist ja auch nur ne Funktion und nicht der Kurs selbst! Im 
Unterricht wird natürlich mit AVR-Studio durch den generierten ASM-Code 
gesteppt und die Schüler kriegen als Aufgabe, den genauen Teilerfaktor 
(anfänglich 10000) selbst zu optimieren. Es ist aber interessant, wie 
schnell Du den Lehrgang zu bewerten können denkst, ich finde das recht 
anmassend!


@Buchegger: Georg W. Bush denkt auch, er sei ein guter Präsident! ;o)) 
Ob Du fachlich kompetent bist oder nicht ist mir egal, im Forum hat's 
Platz für alle. Aber lass doch Deine überflüssigen, abschätzigen und 
nichtsbringenden Kommentare zukünftig bleiben. Auch in der Anonymität 
des Internets sollte man sich gegenseitig mit Respeckt und Anstand 
begegnen. Konstruktiver Feedback, wie z.B. von Wolfram oder AVRFan ist 
natürlich stets willkommen.

@AVRFan: Exakt ist relativ, Interrupts kommen natürlich erst später 
hinzu.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn wirklich solche Kommentare wie im Codebeispiel nötig sind, dürften 
das ziemlich harte Unterrichtsstunden (auch für den Lehrer) sein.
Bis die Karl-Heinz beim debuggen seiner Programme helfen können, dürfte 
es noch ganz schön dauern.
Das genaue Ausrechnen deines Timingwertes für die innere Schleife 
Anfängern zu erklären, dürfte nicht sehr sinnvoll sein. Sie sollen 
wahrscheinlich am Anfang die Fkt. so hinnehmen wie sie ist. Dann sehe 
ich aber bei dieser Alternative:

#include <util/delay.h>


//---------------------------------------------------------
// Warte-Funktion (Delay)
// Parameter: Wartezeit in 0...65535 ms
// Stimmt für alle Optimierungslevel + evt. Interruptausfuehrungszeiten
// mit for-Schleife da Fkt. delay_ms nicht für grosse Wartezeit geeignet
//---------------------------------------------------------
void warte_ms(unsigned int wartezeit)
{
unsigned int schleifenzaehler;
for (schleifenzaehler=0;schleifenzaehler<wartezeit;schleifenzaehler++)
  //wiederhole diese schleife so oft wie Wartezeit angibt
{
  delay_ms(1);  //warte 1ms; Einbinden von delay.h noetig
  }
}

wesentlich weniger Sachen die Anfänger verwirren könnten.
Ich bevorzuge aussagekräftige Variablennamen, das erspart manchen 
Kommentar.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde auf die schnelle auch eine Timer-Lösung im CTC-Mode probieren. 
Beispielsweise machst du mit dem Timer eine Zeitbasis von 1s oder 1ms 
und zählst dort eine "unsigned char"- oder "unsigned int"-Variable hoch. 
Im Hauptprogramm schaust du dann nach dem momentanen Variablenwert und 
setzt die entsprechenden Port-Pin oder ein Byte für serielle 
Port-Erweiterung.

/*Hauptprogramm
while(1)
{
  if ( (value % 1000) == 0 ) Port = grün;
  if ( (value % 1000) == 1 ) Port = gelb;
  if ( (value % 1000) == 2 ) Port = rot;
  if ( (value % 1000) == 6 ) Port = gelb;

}

/*Compare-ISR
{
  value++;
  if (value > 6999) value = 0;
}

oder so ungefähr...

Grüße

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Wolfram: Nuja, wenn ich irgendwas besser machen möchte und einen Post 
hier im Forum absetze, freue ich mich eigentlich schon im Voraus auf 
Antworten von diversen Personen. Dazu zählt zum Beispiel KH Buchegger, 
Peter Dannegger, Jörg Wunsch oder Rufus (und natürlich noch ein paar 
mehr, dessen Namen mir gerade nicht einfallen).
Und ehrlichgesagt finde ich, das KH da nicht ganz unrecht hat...

Nunja, wie auch immer, warum nimmt man solche Schleifen eigentlich in 
Lehrgängen/Unterrichtsgängen durch? Um nachher beigebracht zu kriegen, 
dass sie eine Art schlechten Programmierens sind? Scheint wohl.


>Exakt ist relativ
Ist es das? ;) Also exakt ist bei mir exakt und nicht abhängig von 
anderen Einflüssen...

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon: Geht mir genauso, nebenbei einen herzlichen Dank an die 
vorgenanten
für Vorschläge,Korrekturen und Meinungen.
>Und ehrlichgesagt finde ich, das KH da nicht ganz unrecht hat...
ja hat er völlig,wenn ich so was in einem Sourcecode von einem 
kommerziellen Projekt sehen würde, hätte ich auch Zweifel an den 
Fähigkeiten des Programmierers.
Nun offensichtlich hat Peter S. Lehrlinge die blutige Anfänger sind und 
da kann eine solche Kommentierung notwendig sein. Erstmal muss man 
krabbeln lernen bevor man gehen kann. Also erstmal schön seriell, bevor 
Pseudo-Parallelität hinzukommt. Interrupts kommen ja erst später.
Es würde mich durchaus interessieren, wenn sich einer seiner Lehrlinge 
hier outet, um mal einzuschätzen was von dem Kurs hängen bleibt.
Zumindest muss ich zugeben das das Auseinandernehmen des Codes in 
AVR-Studio und das eigenständige Tunen des Timingwertes durchaus eine 
sehr lehrreiche Erfahrung sein kann. Nicht unter dem Aspekt so 
Timingsachen zu programmieren, sondern um zu begreifen das hinter jeder 
C-Anweisung mehrere Assembleranweisungen stecken und hiermit auch die 
darunterliegende Ebene zu erkennen.


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

Bewertung
0 lesenswert
nicht lesenswert
> Nunja, wie auch immer, warum nimmt man solche Schleifen eigentlich in
> Lehrgängen/Unterrichtsgängen durch?

Um das anzusprechen.
Ich hab nichts gegen die Schleife an sich. Irgendwo muss
man nmal anfangen. Das ist schon in Ordnung. Ich mockiere
mich nur über die Kommentierung ala

  int i;    // Dies ist die Variable i

Der Kommentar erzählt mir und auch einem Anfänger
nichts, was er nicht auch im Code sehen würde

    while(i != 0)          // Schlaufe, solange i nicht gleich null ist

Wenn ein Schüler nach der 2. Lektion den Programmtext
nicht versteht, dann versteht er auch den Kommentar nicht.
Im Kommentar steht genau dasselbe wie im Quelltext.
Solche Kommentare haben nur einen Sinn: Bei Programmänderungen
falsch zu sein und damit den geneigten Leser in ein Dilemma
zu stürzen: Was stimmt den jetzt? Ist der Kommentar richtig
und der Programmierer hat sich vertippt. Oder ist das
Programm richtig und der Kommentar ganz einfach falsch.

Solche Kommentierungen gehören in die Tonne!
Ein Kommentar muss mir Dinge erzählen, die ich nicht durch
2 Sekunden betrachten des Quelltextes sehen kann. Für einen
Anfänger ist es doch besser, wenn ich ihm das Prinzip
erkläre, wie diese Funktion eine Wartezeit von x ms
zustande bringt. Ich kann ihm. zb erklären, dass dies
dadurch erreicht wird, dass der Prozessor in einer
Schleife eine Zahl runterzählt bis er am Ende 0 erreicht
hat. Diese Zahl muss natürlich in Relation zur Prozessor-
frequenz stehen. Also muss ich mal etwas darüber schreiben
wie lange der Prozessor braucht um eine Zahl um 1 zu erniedrigen.
Daraus ergibt sich dann um wieviel runtergezählt werden muss
um eine Zeit von 1 ms zu erhalten. Das sind Kommentare die
einen Neuling weiterbringen. Unterschätzt Neulinge nicht.
Diese einfachen Syntax Sachen haben die in Null Komma Nix drauf.
Wobei es happert, ist das Verbinden von Sprachelementen nach einem
Plan. Also muss ich ihnen den Plan vorkauen. Das
   i = i - 1;
oder
   i--;

eine Variable i um 1 verringert, hat noch jeder Neuling
in 20 Sekunden gelernt und kapiert (Sofern er kapiert hat
was es mit Variablen auf sich hat). Das brauch ich ihm
nicht kommentieren. Zumindest solange nicht, solange im
Kommentar steht, dass hier i um 1 verringert wird.
Was ich ihm kommentieren muss, ist warum ich i um 1
verringere. Weil eben das Ziel darin besteht, in einer
Schleifenkonstruktion i letztendlich auf den Wert 0 zu
bringen.

Mit einer Kommentierung

   // Durchlaufe eine Schleife, um den Prozessor
   // eine zeitlang zu beschäftigen.
   // Ein Durchlauf durch die Schleife dauert bei einer
   // bestimmten Quarzfrequenz soundsoviel µs. Um also eine
   // Zeit von 1 ms durch die Schleife zu verbrauchen
   // muss die Schleife soundso oft wiederholt werden.
   // Dies wird erreicht indem i mit der errechneten
   // Anzahl geladen wird und in jedem Schleifendurchlauf
   // i um 1 verringert wird, bis 0 erreicht ist. Die
   // Schleife wird dadurch i mal ausgeführt.

    i = .......;
    while( i != 0 )
      i = i - 1;

Hier erzählt mir der Kommentar die ganze Geschichte die
es mit der Schleife auf sich hat. Er erzählt mir nicht
was jedes einzelne Statement macht. Das soll er auch nicht.
Dazu sind die Statements nicht kompliziert genug. Aber er
erzählt mir, was der grundsätzliche Gedankengang in den
nöchsten 3 Zeilen Code ist und wie es implementiert ist.

Klar: Industriell würde man das nicht so ausführlich machen.
Für einen Anfänger ist diese ausführliche Kommentierung aber
durchaus angemessen.

Man muss Schüler auch dazu erziehen, sinnvoll zu kommentieren.
Und das fängt schon ganz klein an.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter S.
Ich programmiere schon seit 30 Jahren in C/C++.
Aber die Beitraege von  Karl Heinz Buchegger lese ich immer durch. Lohnt 
sich immer.

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

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi wrote:

> Aber die Beitraege von  Karl Heinz Buchegger lese ich immer durch. Lohnt
> sich immer.

Sehe ich auch so (auch wenn's bei mir erst 15 Jahre C sind :).

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg Wunsch
Ihre Beitraege natürlich auch :)

Autor: psavr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viele Leute geben wirklich gute und informative Beiträge, gegen 
konstruktive Kritik habe ich überhaupt nichts einzuwenden! Ich progge 
selber schon seit 25 Jahren, (in diversen Programmiersprachen) und mir 
ist ja auch klar, dass kein erfahrener Programmierer in der Praxis 
derartige Kommentare macht. Ich weiß auch, dass es auch eine delay_ms() 
Funktion in der avr_libc gibt!

Aber meine Azubis haben weder Hochschulausbildung noch Abi-Abschluss und 
haben oft keine Ahnung was ein uC ist. Viele haben noch nie eine Zeile 
Code selbst eingetipp, geschweige davon, je mit einer IDE gearbeitet. 
Die meisten werden sich wohl kaum zu SW-Cracks mustern, aber als 
Elektroniklaboranten sollten sie abschätzen können, welche Aufgaben 
sinnvollerweise mit einem uC realisiert werden sollten, sowie einfachere 
Aufgaben selbst lösen können.

Statt trockenes C-Syntax auf dem Papier zu büffeln, beginne ich sehr 
früh mit echten C-Programmen und erkläre die Befehle gleich anhand 
Beispielen. Daher deutsche ich im Kommentar den Befehl nochmals aus, bei 
i = i - 1; sieht dass natürlich recht läppisch aus, aber gerade bei C 
kann ein Statement für Einsteiger schon bald mal sehr kryptisch wirken. 
Ich sehe in diesem Forum zumindest immer wieder Fragen wie:

Was bedeutet  PORDC &= ~(1 << PINC2); ?

Die obige warte-Funktion braucht es, damit die Lauflicht Übungen etc. 
nicht nur im Debugger sondern auch in Realtime betrachtbar werden.

Sie lernen da zum Beispiel
- Was ist eine Funktion
- Einfache Parameterübergabe an Funktion
- Verschachtelte while Schleife
- Erste Erklärungen zum Optimizer
- Bedienung des Debuggers

--------------------------------------------------

Ich bin grundsätzlich für aussagekräftige Bezeichner, sie sollen aber 
auch kurz und einprägsam sein, sonst leidet die Übersicht und die Gefahr 
von Tippfehlern erhöht sich.

> for (schleifenzaehler=0;schleifenzaehler<wartezeit;schleifenzaehler++)

Dies ist in meinen Augen ein völliger Overkill, eine lokaler 
Schleifenindex, der über 2..10 Codezeilen hinweg benutzt wird, sollte 
nicht 10..20 Zeichen lang sein, da reichen 1..4 Zeichen! Falls eine 
weitere Erklärung erforderlich ist, kann man diese in den Kommentar 
stecken, dort spielen auch Tippfehler in der Regel keine Rolle! Manchmal 
ist eine gewisse Tippfaulheit beim proggen ganz okey.

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.