Forum: Mikrocontroller und Digitale Elektronik Fehler beim lesen aus Register


von Dieter (Gast)


Angehängte Dateien:

Lesenswert?

Guten Tag,

ich übe mich gerade daran Mikrocontroller zu rogrammieren.
Ich benutze das Atmel Evaluationsboard von Pollin und will nu mit dem 
Taster die beiden LEDs anschalten.
Sprich sobald ich den Taster drücke, bekommt PD4 ein High und die beiden 
LEDs (PD5 und PD6) bekommen dann ebenfalls ein High.

Leider tritt ein Fehler auf (Siehe Anhang), aus dem ich einfach nicht 
schlau werde.
Hat jemand einen kleinen Rat, was das AVR-Studio mir damit sagen will?

Liebe Grüße,

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

mach mal aus dem ersten ';' ein Komma und das zweite weg ...

von (prx) A. K. (prx)


Lesenswert?

Dieter schrieb:
> Hat jemand einen kleinen Rat, was das AVR-Studio mir damit sagen will?

Dass du versuchen solltest, C zu lernen.

Ein Funktionsaufruf mit 2 Statements drin geht nicht. Und um eine 
Funktion extern zu deklarieren, ohne die Parametertypen anzugeben, sind 
wir 2 Jahrzehnte zu spät dran.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

was willst du denn mit dem test1 machen? das extern sieht schon verdammt 
merkwürdig aus.

von Uwe (Gast)


Lesenswert?

extern test1();
sagt dem Compiler (bzw. Linker), daß die Funktion test1() extern zu 
finden ist (und nicht in dieser Datei) und keine Übergabeparameter hat. 
Dann
rufst du die Funktion mit Übergabeparametern auf die auch noch mit 
Semikola getrennt sind und nicht mit Kommata. Zudem sind es keine 
Übergabeparameter.
ich glaube du wolltest hier etwas ganz anderes machen. C Buch hilft.

von Dominik R. (vision)


Lesenswert?

Der angegebene Fehler sagt, dass das/die Semikolon im Funktionsaufruf 
test(...) da nicht hin gehören, aber das ist nicht das einzige Problem.

Es fängt schon bei den #defines an. Als erstes schreibt man dort, was 
vom PP ersetzt werden soll und als zweites dann wodurch. Also genau 
umgekehrt.

Das mit dem extern wurde ja gerade schon erwähnt.

Dann fragst du die Taster während der initialisierung ab - das gehört in 
die while(1)-Schleife

von (prx) A. K. (prx)


Lesenswert?

Uwe schrieb:
> extern test1();
> sagt dem Compiler (bzw. Linker), daß die Funktion test1() extern zu
> finden ist (und nicht in dieser Datei) und keine Übergabeparameter hat.

In C besagt es, dass über Anzahl und Typen der Parameter nichts bekannt 
ist. Uraltes K&R-Erbe. C++ hat den Zopf abgeschnitten, C nicht.

Keine Parameter wäre test1(void). Aber auch der fehlende Return-Typ ist 
heute unsauberer Stil anno 70er Jahre.

: Bearbeitet durch User
von Dominik R. (vision)


Lesenswert?

Dominik R. schrieb:
> Es fängt schon bei den #defines an. Als erstes schreibt man dort, was
> vom PP ersetzt werden soll und als zweites dann wodurch. Also genau
> umgekehrt.

Das ist natürlich quatsch, sorry. Ich wollte gerade meinen Beitrag auch 
noch einmal editieren, aber das scheint nicht zu funktionieren...

von Dieter (Gast)


Lesenswert?

So, ich habe jetzt den komletten externen Müll rausgenommen, das ";" 
durch ein "," ersetzt und alles in die while Schleife gesetzt, jetzt 
funktioniert es, vielen dank für die Ratschläge.

Aber was bringen bitte solche Kommentare wie

A. K. schrieb:
> Dass du versuchen solltest, C zu lernen.

Uwe schrieb:
> ich glaube du wolltest hier etwas ganz anderes machen. C Buch hilft.


Das mit dem externen Kram stand in dem Tutorial auf dieser Seite. Ich 
habe es lediglich kopiert und für meine Anwendung abgeändert, dort stand 
es nicht so beschrieben, wie ihr es mir jetzt erklärt habt.

von Dominik R. (vision)


Lesenswert?

Ich hoffe, du hast nicht alles, sondern nur die Abfrage der Taster in 
die while-Schleife gepackt. Sonst werden die Ports laufend neu 
initialisiert...

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:
> So, ich habe jetzt den komletten externen Müll rausgenommen, das ";"
> durch ein "," ersetzt und alles in die while Schleife gesetzt, jetzt
> funktioniert es, vielen dank für die Ratschläge.
>
> Aber was bringen bitte solche Kommentare wie
>
> A. K. schrieb:
>> Dass du versuchen solltest, C zu lernen.
>
> Uwe schrieb:
>> ich glaube du wolltest hier etwas ganz anderes machen. C Buch hilft.
>
>
> Das mit dem externen Kram stand in dem Tutorial auf dieser Seite. Ich
> habe es lediglich kopiert und für meine Anwendung abgeändert, dort stand
> es nicht so beschrieben, wie ihr es mir jetzt erklärt habt.

Das extern war auch gar nicht das eigentliche Problem. Jetzt mal 
abgesehen, dass im hiesigen Tutorial höchst wahrscheinlich keine 
Funktionsdeklaration zu finden ist, in der der Returntyp der Funktion 
auf Default-int lautet und keine Argument-Datentypen (oder void) 
angegeben sind.

Nur bitte, was soll ein
1
   test( PORTD |= ( 1<<LED1); PORTD |= ( 1<<LED2 ); );

für einen Sinn machen?
Bei dieser Anweisung hakt es auf mehreren Ebenen. Und der NOrmalfall 
dafür ist eben, dass der Programmierer kein C-Buch hat, wenn ihm nicht 
klar ist, was hier das Problem (wieder: das Problem auf mehreren Ebenen) 
ist. Denn mit BUch hätte er 15 Seiten Übungen zum Thema Funktionsaufruf 
hinter sich und zumindest dieses 'Problem' wäre keines.

Halte uns nicht für blöd. Wir können schon unterscheiden welche Fehler 
woraus resultieren. Und leider muss man auch sagen, dass ein guter Teil 
der in diesem Forum behandelten 'Fehler' ihre Ursache in eigentlich 
immer dem gleichen Fehler zu suchen haben: Der betreffende hat kein 
C-Buch. Oder er hat es, ist sich aber zu fein dazu, das mal (zumindest 
im ersten Drittel) durchzuarbeiten.
Ist so.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Dieter schrieb:
> Aber was bringen bitte solche Kommentare wie

Es adressierte dein eigentliches Problem.

von Dieter (Gast)


Lesenswert?

while(1) {

    if ( PIND & ( 1 << TASTER1 ) ) {

    PORTD |= (1 << LED1);
    PORTD |= (1 << LED2);

          }

Diesen Ausdruck habe ich in die while-schleife geschrieben. Ist das 
richtig so?

von (prx) A. K. (prx)


Lesenswert?

Syntaktisch ja, aber viel Sinn ergibt es nicht. Denn wenn die LEDs mal 
leuchten, dann passiert nichts mehr.

von Dieter (Gast)


Lesenswert?

Karl Heinz schrieb:
> Halte uns nicht für blöd. Wir können schon unterscheiden welche Fehler
> woraus resultieren.

Ich habe wohl übersehen, dass ich euch für blöd abgestempelt habe...
Leg mir bitte nicht sowas in den Mund, ich würde hier niemals jemanden 
als blöd bezeichnen, weil vermutlich 98% aller Mitglieder mehr drauf 
haben als ich.

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:
> while(1) {
>
>     if ( PIND & ( 1 << TASTER1 ) ) {
>
>     PORTD |= (1 << LED1);
>     PORTD |= (1 << LED2);
>
>           }
>
> Diesen Ausdruck habe ich in die while-schleife geschrieben. Ist das
> richtig so?

Ja, ist ok. (wenn deine LED mit einer 1 am Portpin eingeschaltet werden)
So, jetzt sollen die LED auch wieder ausgehen, wenn der Taster 
losgelassen wird

von Dominik R. (vision)


Lesenswert?

Das ist korrekt (auch wenn in dem von dir kopierten Code jetzt die 
schließende while-Schleifen-Klammer fehlt, aber da du sagst, das es 
jetzt funktioniert, wird die Klammer in deinem Code wohl drin sein.

Ich frage mich aber noch, was

uint8_t i;
i = PIND;
i = i & 0x10;

machen soll?

Liege ich da falsch, oder ist das überflüssig?

von (prx) A. K. (prx)


Lesenswert?

Dieter schrieb:
> Ich habe wohl übersehen, dass ich euch für blöd abgestempelt habe...

Wenn du eauf ernst und realistisch gemeinte Antworten nur
> Aber was bringen bitte solche Kommentare wie
übrig hast, dann wird schon eine gewisse Geringschätzung erkennbar. Denn 
damit masst du dir an, trotz erklärtermassen geringer Kenntnis behaupten 
zu können, dass diese Antworten keinen Wert hätten.

: Bearbeitet durch User
von Dieter (Gast)


Lesenswert?

Karl Heinz schrieb:
> So, jetzt sollen die LED auch wieder ausgehen, wenn der Taster
> losgelassen wird

    while(1) {

    if ( PIND & ( 1 << TASTER1 ) ) {

    PORTD |= (1 << LED1);
    PORTD |= (1 << LED2);

    PORTD &= ~(1 <<LED1);
    PORTD &= ~(1 <<LED2);
  }


Technisch funktioniert es zumindest. Ob ich etwas überflüssiges bzw. 
umständliches geschrieben habe, das wirst du mir bestimmt erzählen.

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:

> Technisch funktioniert es zumindest.

Aber nur wenn du Superman bist.
Selbst für Chuck Norris ist dieses aufleuchten schon ein wenig kurz

Ausserdem entspricht es nicht der Spezifikation.
Welche war: die LED sollen wieder ausgehen, wenn der Taster losgelassen 
wird (oder: nicht gedrückt ist. Was in diesem Fall dasselbe ist)

: Bearbeitet durch User
von Dieter (Gast)


Lesenswert?

Karl Heinz schrieb:
> Selbst für Chuck Norris ist dieses aufleuchten schon ein wenig kurz

Solange ich den Taster drücke, leuchten die LEDs. Sobald ich ihn 
loslasse gehen sie aus, meintest du etwas anderes?

von Dominik R. (vision)


Lesenswert?

Das mit dem LED an und ausschalten ist richtig, allerdings wundert es 
mich, dass die LED an geht, wenn du den Taster drückst und aus, wenn du 
den Taster los lässt, denn du schaltest in deiner 
Ist-Taster-Gedrückt-Abfrage die LEDs an und gleich wieder aus. 
Normalerweise müsstest du zu deinem if-Block ein else-Block machen (wenn 
der Taster nicht mehr gedrückt ist), und dort die LEDs aus schalten.

if(Taster gedrückt){
   LEDs an;
}
else{
   LEDs aus;
}

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:
> Karl Heinz schrieb:
>> Selbst für Chuck Norris ist dieses aufleuchten schon ein wenig kurz
>
> Solange ich den Taster drücke, leuchten die LEDs. Sobald ich ihn
> loslasse gehen sie aus, meintest du etwas anderes?

Ah, ok.
Das ist in der Tat trickreich.
Denn deine LED leuchten ja wirklich.
Das heisst: genau genommen leuchten sie nicht durch, sondern sie 
blinken. Allerdings so schnell, dass man das Blinken nicht sieht, 
sondern die LED optisch nur noch mit halber Kraft leuchten

Muss mich entschuldigen.
Da war die Spez zu vage, Das hab ich nicht ausgeschlossen.

von Karl H. (kbuchegg)


Lesenswert?

Dominik R. schrieb:
> Das mit dem LED an und ausschalten ist richtig, allerdings wundert es
> mich, dass die LED an geht, wenn du den Taster drückst und aus, wenn du
> den Taster los lässt, denn du schaltest in deiner
> Ist-Taster-Gedrückt-Abfrage die LEDs an und gleich wieder aus.

Der Trick besteht darin, dass das ein kompletter Zyklus ist. D.h. 
ausserhalb des if sind die LEDs abgeschaltet. Wird der Taster nicht mehr 
gedrückt, findet auch der LED-Toggle Zyklus nicht mehr statt und die LED 
bleiben ausgeschaltet. Während sie bei gedrückter Taste eigentlich vor 
sich hin blinken.

> if(Taster gedrückt){
>    LEDs an;
> }
> else{
>    LEDs aus;
> }

Darauf wollte ich eigentlich hin.
Seine Lösung erfüllt formal die Vorgabe, auch wenn ich mir nicht sicher 
bin, ob das Absicht oder Zufall war.

: Bearbeitet durch User
von Dieter (Gast)


Lesenswert?

Karl Heinz schrieb:
> Seine Lösung erfüllt formal die Vorgabe, auch wenn ich mir nicht sicher
> bin, ob das Absicht oder Zufall war.

10% Absicht, 90% Zufall würde ich sagen. :D

if ( PIND & ( 1 << TASTER1 ) ) {

    PORTD |= (1 << LED1);
    PORTD |= (1 << LED2);

  }

    else {


    PORTD &= ~(1 <<LED1);
    PORTD &= ~(1 <<LED2);


  }

So würde ich den Ausdruck wählen, ist es das, was du eigentlich erwartet 
hast?

von Karl H. (kbuchegg)


Lesenswert?

Dieter schrieb:

> So würde ich den Ausdruck wählen, ist es das, was du eigentlich erwartet
> hast?


Yep.

von TomToll (Gast)


Lesenswert?

Lern die Abläufe lieber in Assembler,
geht schneller, ist logischer, weil die ganzen C-Regeln nur verwirren.

Ohne dass du C beherrschst, nützt dir das GCC-Tutorial hier garnichts.

Mit dem ASM Tutorial kannst du sofort loslegen.

von Karl H. (kbuchegg)


Lesenswert?

Oh bitte. Tom Tom.
Das ist hier nicht zielführend. Ausserdem kann ich dir genügend Fallen 
zeigen, in die man auch in Assembler reinfällt.
Hier im Forum wurden auch schon Stunden damit verbraten, einem Schüler 
banale Assembler-Grundlagen beizubringen.

: Bearbeitet durch User
von Dominik R. (vision)


Lesenswert?

Ich bin auch noch nicht lange auf Mikrocontrollern unterwegs, aber ich 
habe vorher schon am PC mit Java, C# etc. zu tun gehabt. Das erleichtert 
es wirklich ungemein.

Wenn ich auf dem uC angefangen hätte, Programmieren zu lernen, hätte ich 
die Klotten warscheinlich nach einer Woche in die Ecke geschmissen.
Was man da erst mal alles initialisieren muss, damit überhaupt irgend 
etwas läuft. Dann muss man ständig in Datenblättern wegen 
Registerbezeichnungen usw nachschauen. Da hätte ich echt zuviel 
bekommen.

Vielleicht solltest du die ersten C-Versuche auch auf dem PC machen. Da 
gibt es viel weniger Stolpersteine und somit viel weniger Frust. Wenn 
man dann das Spaghettiende mit Methoden und deren Aufrufen usw. erst 
einmal in der Hand hat, kann man sich da wunderbar dran lang hangeln und 
der Umstiegt auf uC ist dann echt nicht mehr schwer.

von TomToll (Gast)


Lesenswert?

Ok, kann sein, nur wären die dann anderer Natur.

Mal noch ne Frage,die auch dem TO interessieren dürfte:
Kannst du uns ein C -LEHRBuch empfehlen, das auch die für µC benötigten 
C -Grundlagen anschaulich und für Nicht-INGs nachvollziehbar VERMITTELT?

Also kein Nachschlagewerk für Profis, das der Anfänger nach 10 min in 
die Ecke wirft (oder gleich in den Müll)?

Lieben Dank,
Tom

von Svenska (Gast)


Lesenswert?

TomToll, dir fehlt ein r im Nick.
Aber das weißt du ja selbst.

von TomToll (Gast)


Lesenswert?

Keiner einen Vorschlag?

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.