www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zur Programmierung.


Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab mir hier schon viele Infos aus dem Forum gesammelt und 
erfolgreich umgesetzt. Jetzt wollte ich mal wieder anfangen (nach ein 
paar Jahren) in C zu programmieren. Genaugenommen einem Atmega 16 ein 
wenig Leben einzuhauchen.

Da stellt sich mir gleich folgendes Problem.

Ich habe ein kleines Programm geschrieben, wo ich einen Teil in einen 
"Funktionsblock" auslagern wollte damit die main Funktion übersichtlich 
bleibt.

Leider funkt. das nicht wie erhofft.

Ich habe folgendes gemacht:
void machwas(int ms) {
   for(int i=0; i<8;i++){
   ....
}
int main(void)
{
    while(1){   
        machwas(100);
    }
}

So weit so gut... leider wird "machwas" nicht ausgeführt. Im Debugger 
sehe  ich das er beim Aufruf von "machwas" in die Funktion springt, aber 
direkt wieder raus...
Schreibe ich die Anweisungen aus "machwas" in die main Funktion geht 
es...
Wo liegt mein Fehler?

Danke im Voraus... Tobias

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solange "Machwas" selbst wegoptimiert werden kann... Schreib dort doch 
mal ein Register.

Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da steht ja Code drin... wegoptimieren kann er die nicht... ich hab nur 
am Programmierrechner kein Internet, deswegen nur der Auszug...

Die Schleife mit ihrem Inhalt funkt. ja direkt im Main...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal in die h-Files Deines (uns unbekannten) Compilers.
Oftmals gibts da eine delay.h, die man dann nimmt.
Oder schau ins Manual.

Zeitvernichtungsfunktionen schreibt man nicht selber, das können die 
Compilerbauer besser als Du.


Peter

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Jenatschke schrieb:
> Da steht ja Code drin... wegoptimieren kann er die nicht...

Woher weißt du das?
Comopilier das mal ohne Optimierung (-O0), das sollte helfen.

Oliver

Tobias Jenatschke schrieb:
> ich hab nur
> am Programmierrechner kein Internet, deswegen nur der Auszug...
Das ist ganz schlecht. Für Code, der "so so der so ähnlich" abgetippt 
wurde, dazu mit "..." drin, wirst du keine Hilfe bekommen.

Oliver

Autor: Imon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Jenatschke schrieb:
> void machwas(int ms) {
>    for(int i=0; i<8;i++){
         ^^^ das ist reinen ISO C nicht gestattet soweit ich weiß.
             in reinen C muss i vor der Schleife deklariert sein.
>    ....
> }
> int main(void)
> {
>     while(1){
>         machwas(100);
>     }
> }

Ansonsten sieht der Code Schnipsel  gut aus, wenn du uns nicht mit mehr 
Informationen versorgen kannst, welcher Compiler, welche Compile 
Optionen, was wird in "...."  gemacht. wird es schwer dir zu sagen wo 
dein Fehler liegt.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Imon schrieb:
> Tobias Jenatschke schrieb:
>> void machwas(int ms) {
>>    for(int i=0; i<8;i++){
>          ^^^ das ist reinen ISO C nicht gestattet soweit ich weiß.
>              in reinen C muss i vor der Schleife deklariert sein.
Das geht in Ordnung ab ISO/IEC 9899:1999.

Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal...

Ich arbeite mit AVR-Studio + GCC

Habe leider nur Java und PHP gelernt, C basiert nur auf Selbststudium.

>Tobias Jenatschke schrieb:
> Da steht ja Code drin... wegoptimieren kann er die nicht...

>Woher weißt du das?
>Comopilier das mal ohne Optimierung (-O0), das sollte helfen.

Ich vermute das nur, da es ja direkt im Main funktioniert....


Ich versuch heute abend mal den gesamten Code hier zu rein zu posten...

Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void machwas(uint16_t ms)
{
//Die variablen sind im headerfile definiert... 
 LED_BB_DDR = (1<<LED_BB_0) | (1<<LED_BB_1) | (1<<LED_BB_2) | (1<<LED_BB_3) | (1<<LED_BB_4) | (1<<LED_BB_5)
  | (1<<LED_BB_6) | (1<<LED_BB_7);
  for(int i=0; i<8; i++){
      LED_BB_PORT |= (1<<i);
      _delay_ms(ms);
           LED_BB_PORT &= ~(1<<i);
  }
}
 
int main(void)
{
  while(1){   //Die Bedingungen folgen später
            machwas(50);
        }
        return 0;
}

Das funktioniert nicht... schreib ich jedoch einfach den Code in die 
Main, dann gehts...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vermutlich schreibst du dann nicht

_delay_ms(ms);

sondern

_delay_ms(50);

Letzteres ist die richtige Variante: Nur Konstanten sind bei _delay_ms 
und _delay_us erlaubt. Steht auch so in der avr-libc Doku und 1001*mal 
hier im Forum :-)

Du kannst ein variables _delay_ms so erreichen:

{
  uint16_t i;
  for (i=0; i<ms; i++)
    _delay_ms(1);
}

Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, sorry, Ich bin wirklich wie ein Schnitzel...(bekloppt von allen 
Seiten)

Das hab ich echt überlesen!

Jetzt dachte ich mir, ich könnte mir eine Funktion basteln, ala...
void langes_warten(uint16_t ms)
{
  uint16_t i;
  for (i=0; i<ms; i++)
    _delay_ms(1);
}

Allerdings funktioniert das auch nicht....

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ungewöhnlich.

Aber zu "funktioniert nicht" fällt mir leider nicht viel ein.

Eine buggy _delay_ms() kann man ausschliessen, weil die direkte Variante 
ja schon funktioniert hat. Bei F_CPU und Optimierung hast du hoffentlich 
auch nichts geändert.

Bleiben also die doofen Fragen:

1. Rufst du langes_warten() auch irgendwo auf?

Nicht an die Wand springen. Hat man schon gesehen!

2. Überträgst du das richtige HEX-File?

Das AVR Studio kann da beim ISP Programmieren etwas eigen sein.

3. Hast du den richtigen AVR eingestellt?

Wenn Unterprogramme insgesamt nicht funktionieren, kann ein 
Initialisierungsproblem beim Stack vorliegen. Das kann ein Zeichen für 
einen falschen µC (TARGET) sein. Auch die M103 Fuse beim Atmega128 fällt 
in diese Kategorie (Übersetzt für Atmega128, Werkseinstellung des 
Atmega128 ist aber Atmega103...).

_delay_ms() ist keine statische Funktion, sondern eine inline Funktion. 
Da fällt ein Stackproblem nicht auf.

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

Bewertung
0 lesenswert
nicht lesenswert
Nicht zu vergessen, dass _delay_ms im Simulator zu, na ja sagen wir mal, 
längeren Wartezeiten führen kann, wenn man mit F10 drüberzusteppen 
versucht. Selbst wenn man alles richtig gemacht hat.

Autor: ekke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Letzteres ist die richtige Variante: Nur Konstanten sind bei _delay_ms
> und _delay_us erlaubt. Steht auch so in der avr-libc Doku und 1001*mal
> hier im Forum :-)
Ich dachte, es wäre erlaubt, erzeugt aber sehr großen Code und sollte 
deshalb vermieden werden?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erlaubt im Sinn von funktioniert im Sinn von Verzögert die angegebene 
Anzahl Millisekunden.

Autor: ekke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Erlaubt im Sinn von funktioniert im Sinn von Verzögert die angegebene
> Anzahl Millisekunden.
Ja, das meinte ich... ;-)

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

Bewertung
0 lesenswert
nicht lesenswert
ekke schrieb:
> Stefan B. schrieb:
>> Erlaubt im Sinn von funktioniert im Sinn von Verzögert die angegebene
>> Anzahl Millisekunden.
> Ja, das meinte ich... ;-)

Eben.
Mit einer Variablen stimmen die Zeiten ganz einfach nicht mehr.

_delay_ms ist davon abhängig, dass der Optimizer eine komplexe 
Berechnung rausoptimiert. Das geht aber nur dann, wenn er die 
Verzögerungszeit kennt.
Die kennt er wiederrum nur dann, wenn es eine Konstante ist.

Autor: Tobias Jenatschke (masterofdisaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab gestern abend erstmal hingeworfen. Manchmal sieht man einige 
Stunden später den Fehler. Heute bin ich leider lange unterwegs. Werde 
mich wohl morgen wieder damit befassen.

Es wird etwas einfaches sein... mal schauen.

Wenn ich den Fehler gefunden habe, melde ich mich natürlich wieder...

Danke für die viele Hilfe.

void langes_warten(uint16_t ms){
  uint16_t i;
  for (i=0; i<ms; i++)
    _delay_ms(1);
}

Bringt ja eh etwas Ungenauigkeit in die Pause, für meinen Zweck reicht 
es jedoch.

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.