Forum: Mikrocontroller und Digitale Elektronik C Programm funktioniert nicht


von Stefan A. (aige)


Angehängte Dateien:

Lesenswert?

Hallo,


ich hab ein...naja schon fast peinliches Problem mit C und dem AVR 
Studio:

Ich bin dabei ein Programm zu schreiben, ich hatte schon ziemlich viel 
geschrieben, doch irgendwann trat dieser Fehler auf und hab nach und 
nach alles wieder entfernt bis nur noch diese mini Testprogramm da war 
....und der Fehler wo ich net kapier war ebenfalls noch da...

Wenn ich bei dem Programm "Build an Run" mach, also simulieren will, 
dann passiert nicht viel...der Programcounter (das ist doch der gelbe 
Pfeil am linken Rand??) bleibt einfach bei der 1. geschweiften Klammer 
nach "main" hängen (siehe Anhang). Ich kann so oft auf "Step Into" oder 
"Step Over" drückn wie ich möchte, er bleibt immer da. Das ist ein 
Szenario.
Wenn ich noch ins "main" den rießigen Befehl "PORTD |= 0x01" zB. rein 
schreib passiert folgendes: nach "Build" ist der Programmcounter wieder 
auf der geschweiften Klammer, aber verschwindet wenn ich auf "Step Into" 
oder so klick. Irgendwas wird simuliert aber kommt nix dabei raus. Wenn 
ich auf "Pause" drück ist der CycleCounter bei einigen 100.000..

Irgendwas scheint da an den Einstellungen nicht zu stimmen...
Hab das AVRStudio 4.18
Ich hab es mit SP2 und ohne SP2 probiert, ich hab es mit der neuesten 
WINAVR und mit einer etwas älteren probiert, nix haut hin.

PS: ich hab ausversehen zwei bilder angehängt

#include <avr/io.h>
#include "stdlib.h"
#include "stdio.h"
#include <avr/interrupt.h>



int ausgabe();


void main()
{
  int test;
  test = 2;
//  PORTD = 0x01;

    if(test == 1)
    {
      ausgabe();
    };

  for(;;);

};



int ausgabe()
{
int i = 3;
return i;
};

von avr (Gast)


Lesenswert?

Besser wäre der kpl. Bildschirm.
Es scheint was zu fehlen.

Der Aufruf ohne Rückgabewert:

      ausgabe();

Funktion mit Rückgabe:

int ausgabe()
{
return i;
};

Sollte eine Fehlermeldung bringen.


Auserdem würde er nur einmal durchlaufen und dann hier
hängen bleiben:  for(;;);

avr

von Stefan A. (aige)


Angehängte Dateien:

Lesenswert?

>Der Aufruf ohne Rückgabewert:

>      ausgabe();


Aber das "int ausgabe();" ist doch nur ein Prototyp (heist das so?) 
damit ist eine Warnung weniger

Das Programm müsste dann dohc wenigstens in der Endlosschleife hengen 
bleiben meiner Meinung nach


Edit: Ohne "int ausgabe();" gehts auch nicht :-(

von Schniefnase (Gast)


Lesenswert?

Stefan A. schrieb:
> Das Programm müsste dann dohc wenigstens in der Endlosschleife hengen
> bleiben meiner Meinung nach


for (;;); ist aber keine Endlosschleife, es handelt sich um eine 
virtuelle Prozedur, die so nicht richtig ist.

von Stefan A. (aige)


Lesenswert?

>for (;;); ist aber keine Endlosschleife, es handelt sich um eine
>virtuelle Prozedur, die so nicht richtig ist.


while(1){};

geht ebensowenig, ich hab das Gefühl, dass es das nicht ist, weil das 
Programmcounter gar nicht bis dahin kommt

von R. F. (rfr)


Lesenswert?

Ich ändere das Programm mal (also, das ist jetzt VHIT (vom Hirn ins 
terminal, also ohne Compilerlauf)

#include <avr/io.h>
#include "stdlib.h"
#include "stdio.h"
#include <avr/interrupt.h>

void main()
{
  int test;
  test = 2;

    if(test == 1)
    {
      fprintf( "%s Test ist jetzt, \t ", test);
    };

  for(;;);

};

Die fprintanweisung stimmt vermutlich nicht, ich habe das momentan nicht 
genau im Kopf.

Das Programm sollte den Wert von test ausgeben.
Führe in das programm Ausgabeanweisungen ein, die einen Wert ausgeben, 
und checke die Richtigkeit dieses Wertes.

Gruss

Robert

von Stefan A. (aige)


Lesenswert?

>fprintf( "%s Test ist jetzt, \t ", test);
>Die fprintanweisung stimmt vermutlich nicht, ich habe das momentan nicht
>genau im Kopf.

ich möcht ein Programm für nen ATmega8 schreiben, ich kenn die fprintf 
Anweisung noch aus dem 2. Semester da haben wir aber für Windows 
programmiert. Da ging dann glaub ich ein DOS Fenster auf

aber selbst wenn ich das einfüge kommen zwar nur 3 Warnings, aber der 
gelbe Pfeil hängt trotzden auch noch nach 1000 mal "Step Into" drücken 
noch immer an der 1. geschweiften Klammer. Ich hab überhaupt keine 
Ahnung was das sein könnte

von Peter (Gast)


Lesenswert?

Die Bedingung if(test == 1) wird nie wahr sein, und auch sonst macht das 
Programm nichts sinvolles (aus der Sicht des Optimizers) also optimiert 
der Compiler ganz einfach alles überflüssige (quasi das ganze Programm) 
weg!

Desswegen bleibt der Debuger auch am Programmanfang stehen, es sit alles 
erledigt und gibt nichts mehr zu tun das irgend einen Einfluss hat...

von Lowtzow .. (lowtzow)


Lesenswert?

ich weiß nicht was dein programm machen sollte deshalb habe ich es so 
umgeschriebn, dass du zumindesten beim simulieren etwas sehen solltes am 
portd.
bei deinem programm, waren einige
klammern falsch gesetzt, wenn du
"int main" schreibst musst du einen rückgabewert schreiben "return 0"
zuviele strichpunkte
wenn du ausgänge setzten willst musst du im directionport auch den port 
als ausgang setzen.

1
int main(void){
2
  int test;
3
  test = 2;
4
  DDRD=0xFF;
5
  
6
7
    if(test == 1){
8
      ausgabe();
9
    }
10
11
  while (1){
12
    PORTD = 0x01;
13
  }
14
  
15
  return 0;
16
}

von Stefan A. (aige)


Lesenswert?

hmm

ich hab jetzt das Programm etwas umgestalltet, nun macht der Simulator 
wieder ganz komische sachen:

"Build" ,
dann Simulation startetn,
dann ist der gelbe Pfeil bei der 1. geschweiften Klammer
klick auf "Step Into"
gelber Pfeil ist auf der } vom main-Programm (!)
noch ein klick auf "Step Into"
gelber Pfeil ist auf der } vom ausgabe-Programm (!!)
noch ein klick auf "Step Into"
Pfeil weg, endlosschleife




#include <avr/io.h>
#include "stdlib.h"
#include "stdio.h"
#include <avr/interrupt.h>


int main(void)
{
  int test;


  test = ausgabe(4);
  PORTD |= test;
  return (0);

  while(1);
};


int ausgabe(int bin)
{
  int i;
  i = 2 + bin;
  return i;

};

von weißgradnich (Gast)


Lesenswert?

Auf 'nem AVR ist's recht unsinnig, main zu verlassen, deshalb wäre die 
Endlosschleife vor dem "return 0" besser aufgehoben.
1
#include <avr/io.h>
2
#include "stdlib.h"
3
#include "stdio.h"
4
#include <avr/interrupt.h>
5
6
7
int main(void)
8
{
9
  int test;
10
11
  test = ausgabe(4);
12
  PORTD |= test;
13
14
  while(1);
15
16
  return (0);
17
};
18
19
20
int ausgabe(int bin)
21
{
22
  int i;
23
  i = 2 + bin;
24
  return i;
25
};
Tip! Wenn Du was simulieren willst, schalte vorher die Optimierung aus.

von Andreas F. (aferber)


Lesenswert?

Schniefnase schrieb:
> for (;;); ist aber keine Endlosschleife,

Schwachsinn. Was ist denn eine Schleife ohne Abbruchbedingung? Eine 
Endlosschleife. In diesem Fall zusätzlich noch mit leerem Body.

> es handelt sich um eine
> virtuelle Prozedur, die so nicht richtig ist.

Was soll denn eine "virtuelle Prozedur" sein? Auch C++ kennt "virtuell" 
nur im Zusammenhang mit Methoden. Bloss weil es auf den ersten Blick ein 
wenig wie ein Funktionsaufruf aussehen mag, ist es noch lange keiner.

Andreas

von Andreas F. (aferber)


Lesenswert?

weißgradnich schrieb:
> Auf 'nem AVR ist's recht unsinnig, main zu verlassen, deshalb wäre die
> Endlosschleife vor dem "return 0" besser aufgehoben.

Und das "return 0" kann man auch gleich noch weglassen. Selbst ohne die 
Endlosschleife, denn main() gibt implizit immer 0 zurück, wenn nichts 
anderes zurückgegeben wird. Letzteres gilt allerdings nur für main(), 
jede andere Funktion, die nicht "void" zurückgibt, braucht ein 
explizites return.

Andreas

von Sven P. (Gast)


Lesenswert?

Der Reihe nach:


Autor: avr (Gast)
Datum: 03.04.2010 20:20
> Der Aufruf ohne Rückgabewert: [...]
> Sollte eine Fehlermeldung bringen.
Nein, der Rückgabewert wird implizit verworfen, ist vollkommen in 
Ordnung so.


Autor: Schniefnase (Gast)
Datum: 03.04.2010 20:31
> for (;;); ist aber keine Endlosschleife, es handelt sich um eine
> virtuelle Prozedur, die so nicht richtig ist.
for (;;); ist eine Endlosschleife und syntaktisch und semantisch 
vollkommen korrekt. Virtuelle Prozeduren gibt es in C nicht, du 
verwechselst da irgendwas.



Autor: R. Freitag (rfr)
Datum: 03.04.2010 20:37
> fprintf( "%s Test ist jetzt, \t ", test);
> Die fprintanweisung stimmt vermutlich nicht [...]
Stimmt, auch unter Windows verlangt fprintf() als erstes Argument nach 
einem Stream, in den geschrieben werden soll. Sinnvoll wäre auf dem AVR 
sprintf() in einen statischen Puffer, der dann per UART ausgegeben wird. 
Einschlägige Beispiele stehen im Wiki und in der Dokumentation zur 
AVR-LIBC.


Nach ISO-C99 darf in main() die return-Anweisung entfallen, was dann 
denselben Effekt wie exit(0) haben muss.



Ansonsten ist des Pudels Kern sicher die Optimierung; ein optimiertes 
C-Programm zu debuggen, ist meistens zwecklos. Wenn alle Stricke reißen, 
schau mal ins Assembly (beim gcc zu erzeugen mit 'gcc -S').

von R. F. (rfr)


Lesenswert?

Meine Überlegung ging dahin, durch das Einfügen von Ausgabeanweisungen 
Klarheit über den aktuellen Status des Programmes zu erhalten. Der OP 
wird (oder sollte eigentlich) selbst merken, daß die IF-Konstruktion 
niemals erfüllt wird.

Die Optimierung schlägt übrigens nicht zu, weil die fprintanweisung 
ausführbar ist und daher nicht wegoptimiert werden kann.

Gruss

Robert

von Sven P. (Gast)


Lesenswert?

Hier:
1
void main()
2
{
3
  int test;
4
  test = 2;
5
6
    if(test == 1)
7
    {
8
      fprintf( "%s Test ist jetzt, \t ", test);
9
    };
10
11
  for(;;);
12
13
};

Schlägt die Optimierung mit absoluter Sicherheit zu, da der Text im 
Körper der if-Anweisung niemals erreicht werden kann.

Mit meinem AVR-GCC ergibt das folgendes Assembly:
1
main:
2
/* prologue: frame size=0 */
3
        ldi r28,lo8(__stack - 0)
4
        ldi r29,hi8(__stack - 0)
5
        out __SP_H__,r29
6
        out __SP_L__,r28
7
/* prologue end (size=4) */
8
.L2:
9
        rjmp .L2

von Noname (Gast)


Lesenswert?

Kann mir einer erklären warum stehen hinter den "}" immer ";" stehen?

von R. F. (rfr)


Lesenswert?

Schlägt die Optimierung mit absoluter Sicherheit zu, da der Text im
Körper der if-Anweisung niemals erreicht werden kann.

Gans recht. Und der OP wird dann eine Phase des Nachdenkens einlegen, 
deren Ergebnis sein wird, zu erklären, warum die fprintanweisung nicht 
ausgeführt wird. Ich hoffe, das bringt den OP auf vernünftige Ideen.

Gruss

Robert

von Stefan A. (aige)


Lesenswert?

Noname schrieb:
> Kann mir einer erklären warum stehen hinter den "}" immer ";" stehen?

Ich glaub mich zu erinnern, dass wir das in der Info-Vorlesung so 
gelernt hatten.

zu meinem Hauptproblem:

gestern Nacht bin ich doch tatsächlich noch duch verzweifeltes 
umherklicken im AVRStudio in ein Menü gekommen wo man den 
Optimierungsgrad einstellen kann. Da ich erst gestern das erste mal mit 
C nen AVR programmieren wollte und mich nicht auskenn hab ich einfach 
mal die Optimierung auf Stufe0 gesetzt. :-) Das wars! Meine Programme 
sind zwar jetzt 3 mal so groß aber ich kann nahezu alles Simulieren!

Dann hab ich noch kurz versucht die Disassambly mit eingeschalteter 
Optimierung nachzuvollziehen....naja das hab ich dann schnell wieder 
aufgegeben, das ist ja voll krank^^


Vielen Dank für die Hilfe an alle!

von besucher (Gast)


Lesenswert?

theorie & praxis ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.