Hallo Zusammen,
Ich hab vor kurzem angefangen, auf dem Arduino UNO reines C zu
programmieren.
Ein einfaches Blinky/Lauflicht habe ich zusammen bekommen, es scheitert
aber am Taster Beispiel (Taster AN, LED8 leuchtet, Taster AUS, LED7
leuchtet).
Compilieren funktioniert, Programm auf den ATMega328p drauf laden
ebenso.
Es leuchtet lediglich die LED7, auch wenn ich den Taster betätige.
Leider verstehe ich nicht, woran das Problem liegt bei folgendem
Programmcode:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<stdio.h>
4
#include<stdint.h>
5
#include<avr/interrupt.h>
6
#include<inttypes.h>
7
8
uint8_ta;
9
10
intmain(void)
11
{
12
DDRD|=(1<<7)|(1<<6);// 7. und 8. PIN vom Port D als Ausgang
13
DDRC&=~(1<<0);// 1. PIN vom Port C als Eingang
14
PORTC|=(1<<0);// internen Pull-up einschalten
15
a=PINC&~(1<<0);
16
17
if(a!=0)// wenn Taster gedrückt
18
{
19
PORTD|=(1<<7);// LED8 geht an
20
}
21
else// wenn Taster nicht gedrückt
22
{
23
PORTD|=(1<<6);// LED geht an
24
}
25
}
Bitte um eine kleine Hilfe.
PS: Bin Anfänger, daher bitte nicht allzu viel von mir erwarten :)
Es fehlt eine Hauptschleife, siehe [1]. In der Arduino Welt macht das
die "loop()" Funktion für dich. In reinem C musst du etwas wie
"while(1);" notieren. Vermutlich startet dein Programm deshalb einfach
immer wieder von vorne.
Außerdem schaltest du die LEDs nicht wieder ab, d.h. sie würden ohnehin
immer leuchten.
Weiterhin bietet das Forum rudimentäre Formatierungsmöglichkeiten für
Quellcode. Diese solltest du nutzen, um das ganze ansehlicher zu
gestalten.
Mit freundlichen Grüßen,
Karol Babioch
[1]:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Grunds.C3.A4tzlicher_Programmaufbau_eines_.C2.B5C-Programms
Karol Babioch schrieb:> Es fehlt eine Hauptschleife, siehe [1]. In der Arduino Welt macht> das> die "loop()" Funktion für dich. In reinem C musst du etwas wie> "while(1);" notieren. Vermutlich startet dein Programm deshalb einfach> immer wieder von vorne.>> Außerdem schaltest du die LEDs nicht wieder ab, d.h. sie würden ohnehin> immer leuchten.>> Weiterhin bietet das Forum rudimentäre Formatierungsmöglichkeiten für> Quellcode. Diese solltest du nutzen, um das ganze ansehlicher zu> gestalten.>> Mit freundlichen Grüßen,> Karol Babioch>> [1]:> https://www.mikrocontroller.net/articles/AVR-GCC-T...
Stimmt, die Endlosschleife hab ich aus versehen weg gelassen.
Funktioniert aber trotzdem nicht. Jetzt leuchtet die LED8
ununterbrochen.
Die Definition des Tasters passt?
1
uint8_ta;
2
3
intmain(void)
4
{
5
DDRD|=(1<<7)|(1<<6);// 7. und 8. PIN vom Port D als Ausgang
>Stimmt, die Endlosschleife hab ich aus versehen weg gelassen.
Dann wäre es wohl noch sinnvoll die Tasterabfrage auch
in diese Endlosschleife zu legen.
holger schrieb:>>Stimmt, die Endlosschleife hab ich aus versehen weg gelassen.>> Dann wäre es wohl noch sinnvoll die Tasterabfrage auch> in diese Endlosschleife zu legen.
Hab's versucht, geht trotzdem nicht.
Wie müsste ich den Code ändern? Glaub das wäre am schnellsten, bevor ich
noch 100 mal rum probiere :)
Darko Jen schrieb:> Hab's versucht, geht trotzdem nicht.
Das ist keine brauchbare Fehlerbeschreibung.
Darko Jen schrieb:> Wie müsste ich den Code ändern? Glaub das wäre am schnellsten, bevor ich> noch 100 mal rum probiere :)
Lernen tust du es aber nur, wenn du es noch 100 mal probierst. Konkret
geht es um die Zeile "a = PINC & ~(1<<0);". Diesen willst du ja
kontinuierlich in der Schleife einlesen, nicht einmalig während der
Initialisierung.
Übrigens: Wo kommst du Verneinung von (1<<0) her? Du möchtest du PC0
abfragen, und nicht PC1:7? Durch deine Verundung jedenfalls wird das Bit
0 immer als 0 eingelesen werden.
Mit freundlichen Grüßen,
Karol Babioch
Karol Babioch schrieb:> Darko Jen schrieb:>> Hab's versucht, geht trotzdem nicht.>> Das ist keine brauchbare Fehlerbeschreibung.>> Darko Jen schrieb:>> Wie müsste ich den Code ändern? Glaub das wäre am schnellsten, bevor ich>> noch 100 mal rum probiere :)>> Lernen tust du es aber nur, wenn du es noch 100 mal probierst. Konkret> geht es um die Zeile "a = PINC & ~(1<<0);". Diesen willst du ja> kontinuierlich in der Schleife einlesen, nicht einmalig während der> Initialisierung.>> Übrigens: Wo kommst du Verneinung von (1<<0) her? Du möchtest du PC0> abfragen, und nicht PC1:7? Durch deine Verundung jedenfalls wird das Bit> 0 immer als 0 eingelesen werden.>> Mit freundlichen Grüßen,> Karol Babioch
Soweit ich weiß wird die ODER-Verknüpfung verwendet, wenn es um einen
Ausgang geht, eine UND-Verknüpfung mit einer Negierung des Pins, wenn es
um einen Eingang geht. Daher habe ich mir gedacht, ich lass das "~"
drinnen.
Hab nun die Zeile in der Schleife eingefügt und die Verneinung
weggelassen und es funktioniert noch immer nicht, ich gebe schon langsam
auf.
PS: gerade merke ich, dass die Abfrage am Taster garnicht funktioniert,
da ich dasselbe Ergebnis erhalte, wenn ich den Taster raus nehme. (LED8
leuchtet permanent).
Was genau muss ich noch ändern/hinzufügen? Das AVR GCC Tutorial hab ich
schon gelesen und das beantwortet nicht meine frage. Sitze schon seit 2
Abenden daneben
1
intmain(void)
2
{
3
DDRD|=(1<<7)|(1<<6);// 7. und 8. PIN vom Port D als Ausgang
Darko Jen schrieb:> Soweit ich weiß wird die ODER-Verknüpfung verwendet, wenn es um einen> Ausgang geht, eine UND-Verknüpfung mit einer Negierung des Pins, wenn es> um einen Eingang geht. Daher habe ich mir gedacht, ich lass das "~"> drinnen.
Du kannst das doch kurz mit Zettel und Stift durchgehen. Mit lustig
herum raten, bzw. der blinden Übernahme von Tutorials ohne es
durchzuspielen, wird dich kaum zum Erfolg bringen.
Die Negierung mit Verundung setzt man typischerweise dann ein, wenn man
ein Bit "löschen" will, ohne die anderen Bits des Ports zu ändern.
Du willst aber Bit 0 von PINC auswerten, d.h. du musst alle anderen Bits
ignorieren. Das geschieht mit einer Verundung einer Bitmaske, die nur an
Bit 0 eine 1 stehen hat.
Das Ergebnis dieser Verundung kannst du dann auswerten. Ist das Ergebnis
0, so war das Bit nicht gesetzt, ist das Ergebnis ungleich 0 (bzw. in
dem Fall sogar 1, weil Bit 0), so war das Bit gesetzt.
Darko Jen schrieb:> und es funktioniert noch immer nicht
Nach wie vor eine schlechte Fehlerbeschreibung. Die halbe Miete des
Debuggings ist es, das Fehlverhalten ordentlich auszuformulieren. Dabei
wird einem selbst oft schon klar, was ggf. verkehrt läuft.
Darko Jen schrieb:> ich gebe schon langsam> auf.
Dann bist du aber nicht besonders geduldig ;). Manchmal dauern eben
selbst solche Trivialitäten etwas. Die Zeit muss man sich eben nehmen.
Glaub mir, dass es ein sehr befriedigendes Gefühl ist, wenn man so etwas
selbst gelöst bekommt, und nicht per Copy & Paste Code von anderen
übernimmt.
Übrigens: Wie ist denn dein Taster beschaltet? Da du den internen
Pull-Up aktivierst, nehme ich an, dass das Ganze auf Active Low hinaus
läuft? Dann wäre der Button aber aktiv, wenn a gleich 0 ist, d.h.
zumindest die Kommentare der einzelnen Verzweigungen sind falsch.
Und wo wird in deiner aktuellsten Version a definiert? Gibt es
Fehlermeldungen des Compilers, die du stillschweigend ignorierst?
Mit freundlichen Grüßen,
Karol Babioch
>PS: gerade merke ich, dass die Abfrage am Taster garnicht funktioniert,>da ich dasselbe Ergebnis erhalte, wenn ich den Taster raus nehme. (LED8>leuchtet permanent).
Dann schaltest du mit dem Taster vermutlich gegen VCC.
er muss aber gegen GND schalten damit der Code funktioniert.
>Schaltet der Taster gegen Masse?
Da ist noch jemand meiner Meinung;)
> Dann bist du aber nicht besonders geduldig ;). Manchmal dauern eben> selbst solche Trivialitäten etwas. Die Zeit muss man sich eben nehmen.> Glaub mir, dass es ein sehr befriedigendes Gefühl ist, wenn man so etwas> selbst gelöst bekommt, und nicht per Copy & Paste Code von anderen> übernimmt.
Ich kann es kaum glauben, dass es so schwer ist, kein einfaches
Tasterbeispiel zu schaffen, daher der Verlust der Geduld :) werde aber
natürlich nicht aufgeben, ehe ich es nicht fertig habe. Hätte ich ein
Beispiel vor mir liegen, würde ich dieses im Kopf durchsteppen, bis ich
jede Zeile kapiere.
> Übrigens: Wie ist denn dein Taster beschaltet? Da du den internen> Pull-Up aktivierst, nehme ich an, dass das Ganze auf Active Low hinaus> läuft? Dann wäre der Button aber aktiv, wenn a gleich 0 ist, d.h.> zumindest die Kommentare der einzelnen Verzweigungen sind falsch.
Den Taster habe ich folgendermaßen beschaltet: siehe Bild
> Du willst aber Bit 0 von PINC auswerten, d.h. du musst alle anderen Bits> ignorieren. Das geschieht mit einer Verundung einer Bitmaske, die nur an> Bit 0 eine 1 stehen hat.>> Das Ergebnis dieser Verundung kannst du dann auswerten. Ist das Ergebnis> 0, so war das Bit nicht gesetzt, ist das Ergebnis ungleich 0 (bzw. in> dem Fall sogar 1, weil Bit 0), so war das Bit gesetzt.
Nun gut, jetzt verstehe ich, warum ich die Verneinung nicht brauche -
logisch.
1
a=PINC&(1<<0)
sagt ja aus, dass sich a entsprechend der Änderung des PINC0 ändert
Durch
1
if(a!=0)
erfolgt eine Abfrage, ob der PORTC (0-6) ungleich 0 ist. Da die Pins
PINC1 - PINC5 nirgends definiert sind, bleiben diese doch 0, oder? Bzw.
da diese weder als Eingang, noch als Ausgang definiert sind, bleiben die
auf Low?
Daher hängt es nur vom PINC0 ab, ob hier der Taster High oder Low ist.
Bei High leuchtet die LED8, bei Low leuchtet die LED7.
-> das wäre mein logischer Gedanke gewesen. Anscheinend irre ich mich
aber
> Und wo wird in deiner aktuellsten Version a definiert? Gibt es> Fehlermeldungen des Compilers, die du stillschweigend ignorierst?
ganz oben, vor der while-Schleife wird a gleich 0 gesetzt.
PS: mit der IDE vom Arduino klappt das Button-Beispiel beim selben
Aufbau perfekt!
Der ganze Code, wodurch LED8 permanent leuchtet
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<stdio.h>
4
#include<stdint.h>
5
#include<avr/interrupt.h>
6
#include<inttypes.h>
7
8
uint8_ta=0;
9
10
intmain(void)
11
{
12
DDRD|=(1<<7)|(1<<6);// 7. und 8. PIN vom Port D als Ausgang
13
DDRC&=~(1<<0);// 1. PIN vom Port C als Eingang
14
PORTC|=(1<<0);// internen Pull-up einschalten
15
16
while(1)
17
{
18
a=PINC&(1<<0);// a entweder HIGH oder LOW, je nach PINC0
19
if(a!=0)// wenn Taster gedrückt
20
{
21
PORTD|=(1<<7);// LED8 geht an
22
PORTD&=~(1<<6);// LED7 geht aus
23
}
24
25
else// wenn Taster nicht gedrückt
26
{
27
PORTD|=(1<<6);// LED7 geht an
28
PORTD&=~(1<<7);// LED8 geht aus
29
}
30
}
31
}
sollte ich mich bei meinen Sätzen irren, bitte bescheid geben - wie
gesagt, bin ziemlich neu in der µC-Welt :)
>Den Taster habe ich folgendermaßen beschaltet: siehe Bild
Ja, scheisse baust du da. Dein Taster schaltet nicht gegen GND.
Nimm den Widerstand da weg. Die rote Leitung zum Taster weg und
eine schwarze Leitung zum Taster. Das sollte es dann gewesen sein.
Darko Jen schrieb:> Da die Pins> PINC1 - PINC5 nirgends definiert sind, bleiben diese doch 0, oder? Bzw.> da diese weder als Eingang, noch als Ausgang definiert sind, bleiben die> auf Low?
Nein. Dein Arduino hat interne Pullups, die die Eingänge auf High
ziehen.
Darko Jen schrieb:> Den Taster habe ich folgendermaßen beschaltet: siehe Bild
In dem Fall hast du einen Pulldown. Da der µC jedoch einen internen
Pullup hat, dürfte das recht wackelig sein(Der Pullup lieht im Bereich
von 10-25k, genaueres im Datenblatt). Tausch am Taster/Widerstand mal
VCC und GND. Dann solltest du noch die Tasterabfrage umdrehen(wenn der
Taster gedrückt ist, liefert er logisch 0).
holger schrieb:>>Den Taster habe ich folgendermaßen beschaltet: siehe Bild>> Ja, scheisse baust du da. Dein Taster schaltet nicht gegen GND.> Nimm den Widerstand da weg. Die rote Leitung zum Taster weg und> eine schwarze Leitung zum Taster. Das sollte es dann gewesen sein.
Leider nein, ich erhalte dasselbe Ergebnis
PS: Den Plan hab ich von arduino.cc, wobei das mit der IDE klappt.
123 schrieb:> Darko Jen schrieb:>> Da die Pins>> PINC1 - PINC5 nirgends definiert sind, bleiben diese doch 0, oder? Bzw.>> da diese weder als Eingang, noch als Ausgang definiert sind, bleiben die>> auf Low?>> Nein. Dein Arduino hat interne Pullups, die die Eingänge auf High> ziehen.>> Darko Jen schrieb:>> Den Taster habe ich folgendermaßen beschaltet: siehe Bild>> In dem Fall hast du einen Pulldown. Da der µC jedoch einen internen> Pullup hat, dürfte das recht wackelig sein(Der Pullup lieht im Bereich> von 10-25k, genaueres im Datenblatt). Tausch am Taster/Widerstand mal> VCC und GND. Dann solltest du noch die Tasterabfrage umdrehen(wenn der> Taster gedrückt ist, liefert er logisch 0).
Getan! Nun liefert er logisch 0 und die LED7 leuchtet (sollte auch so
sein, da der Taster nicht gedrückt ist)
Wenn ich den Taster nun drücke, merke ich keinen unterschied. Es
leuchtet permanent die LED7 (Ergebins also konstant logisch 0)
>Leider nein, ich erhalte dasselbe Ergebnis
Tut mir leid, aber ich bin jetzt raus.
Du bist nicht dazu in der Lage einen simplen Taster
vom Portpin gegen GND zu schalten. Nimm dein
Multimeter und pieps mal durch ob der überhaupt
so schaltet wie du es dir vorstellst. Spannung
am Portpin messen. Das wars dann von mir.
Liebe Leute,
Ich bedanke mich bei jedem einzelnen von Euch!! Es funktioniert
Zum einen hat der Code nicht gestimmt. danke @karol
Zum anderen habe ich aus versehen PORTC und PORTB vertauscht!! Danke
@chris
Den Widerstand vor dem Taster habe ich komplett raus gemacht, da der
Pull-up Widerstand ohnehin aktiviert ist.
Der Taster war ebenso nicht auf GND. habe nun links oben am Taster GND
angeschlossen und rechts unten PINC0 (bei einer verbindung rechts oben
mit PINC0 bleibt LED8 konstant auf HIGH). Wenn zusätzlich noch Vcc am
Taster dran kommt, dann leuchtet zwar die LED7, wenn der Taster aus ist,
jedoch GARNICHTS, wenn der Taster betätigt wird. hierbei danke @holger,
hattest Recht
usw...
Die restlichen Infos waren ebenso hilfreich (Schaltplan, etc.)
Hier der endgültige Code, der endlich passt, jedoch bin ich gerade
dabei, es zu verstehen, warum es umgekehrt funktioniert als gewollt
(Taster gedrückt, LED8 aus, Taster aus, LED8 an)... es steht doch
"if(a!=0)" da, sprich: wenn das Bit von PINC0 gesetzt ist, soll die LED8
leuchten..komisch, wahrscheinlich zu spät für mich :)
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<stdio.h>
4
#include<stdint.h>
5
#include<avr/interrupt.h>
6
#include<inttypes.h>
7
8
uint8_ta=0;
9
10
intmain(void)
11
{
12
DDRD|=(1<<7)|(1<<6);// 7. und 8. PIN vom Port D als Ausgang
13
DDRB&=~(1<<0);// 1. PIN vom Port C als Eingang
14
PORTB|=(1<<0);// internen Pull-up einschalten
15
16
while(1)
17
{
18
a=PINB&(1<<0);// a entweder HIGH oder LOW, je nach PINC0
Darko Jen schrieb:> Hier der endgültige Code, der endlich passt, jedoch bin ich gerade> dabei, es zu verstehen, warum es umgekehrt funktioniert als gewollt> (Taster gedrückt, LED8 aus, Taster aus, LED8 an)...
Weil dein Taster gegen GND schaltet. Per Pull-Up ziehst du die Spannung
im Ausgangszustand gegen Vcc, d.h. logisch 1. Wennn du den Taster
drückst, dann fällt die Spannung auf 0 Volt ab (logisch 0). Deine
if-Abfrage ist also genau verkehrt herum.
Mit freundlichen Grüßen,
Karol Babioch