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,
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.
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.
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
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.
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...
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.
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.
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?
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.
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
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?
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.
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.
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)
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?
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;
}
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.
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.
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?
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.
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.
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.
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