Hallo,
wie kann ich in C ein Taster einlesen und damit die LED einschalten und
mit einem anderem Schalter wieder ausschalten.
Also: Taster LED ein==> PINC=0b11111110;
Taster LED aus==> PINC=0b11011111;
LED ==> PORTB0b00000001;
~ logische Invertierung
|= Oder-Vernüpfung mit Ablegen des Ergebnisses in linke Variable
&= selbiges, jedoch Und-Verknüpfung
Wenn dir davon etwas nichts sagt:
http://de.wikipedia.org/wiki/Logischer_Operator
Außer, dass sie eben gerade nicht logisch, sondern bitweise arbeiten.
Logisch gibt es UND (&&) und ODER (||) in C, sowie die Negation (!).
Bitweise gibt es UND (&), ODER (|), XOR (^) und das Komplement (~).
Im Tutorial steht dieses Beispiel:
#include <avr/io.h>
...
#define MEINBIT 2
...
PORTA |= (1 << MEINBIT); /* setzt Bit 2 an PortA auf 1 */
PORTA &= ~(1 << MEINBIT); /* loescht Bit 2 an PortA */
Was hat dieses #define MEINBIT 2 zu bedeuten?
Warum kann mann nicht sagen MEINBIT=2? MEINBIT ist doch die Variable die
den Wert 2 hat oder?
Was sagt mir dieses #define aus?
Das ist ein Marko und dient der Leserlichkeit. Du könntest natürlich
auch eine Variable mit dem selben Wert anlegen. Außerdem kannst du so
Code universelleren Code schreiben, sollte Meinbit das nächstemal an
anderer Stelle sein änderst du nur den zugewiesenen Wert im define.
Hi ich bin auch ein Anfänger bei yC. Ich habe mir eine Reihe Tutorials
durchgelesen und das mega-simple BSP abgetippt:
1
#include<avr/io.h>
2
intmain(void){
3
DDRC=0xff;
4
//PORTC |= (1 << 2); /* setzt Bit 2 an PortC auf 1 */
5
PORTC&=~(1<<2);/* loescht Bit 2 an PortC */
6
while(1){
7
}
8
return0;
9
}
Was an meinem ATmega32 passiert ist folgendes: In der obigen Version
"PORTC &=" leuchten die LEDS an PINC2 und PINC3. Wenn ich das Quote und
die andere Zeile aktiviere dann leuchtet PINC3??????????
Ich hab die LEDS an Vcc liegen und zwar tatsächlich an PINC2 und PINC3.
Hat jemand einen Tip??
@ Gast (Gast)
>Hi ich bin auch ein Anfänger bei yC. Ich habe mir eine Reihe Tutorials>durchgelesen
Aber nicht ansatzweise verastanden.
> und das mega-simple BSP abgetippt:
Woher?
>Hat jemand einen Tip??
Versuchs mal damit.
Gast wrote:
> Ich hab die LEDS an Vcc liegen und zwar tatsächlich an PINC2 und PINC3.> Hat jemand einen Tip??
Sieht doch alles richtig aus.
Dein Denkfehler dürfte sein:
So wie du deine LED verschaltet hast (also nach Vcc) leuchten sie
genau dann, wenn du den entsprechenden Outputpin auf 0 legst.
Durch
PORTC |= (1 << 2); /* setzt Bit 2 an PortC auf 1 */
wird zwar PC2 auf 1 gesetzt, aber PC3 ist nachwievor auf 0.
Ergo leuchtet die LED an PC2 nicht, wohingegen die LED auf
PC3 leuchtet.
Dein Aufbau macht also genau das, was man erwarten würde.
NB: Das JTAG Interface am Mega32 hast du abgeschaltet?
Das liegt ebenfalls am PORTC und ist per default ein.
Hallo,
zunächst mal danke!
@falk:
>Woher?
Na aus dem AVR-GCC Tutorial von wwww.mikrokontroller.net
zusammengedampft
>Aber nicht ansatzweise verastanden.
Ich dachte schon, war wohl nix. Dein Code ist nur an zwei Stellen
anders. 1. setzt er die "PORTC &=" in die Hauptschleife. Und zweitens
kommt vorher ein "Port |=". Ich gehe also davon aus, dass jeder Pin der
verwendet wird zunächst über "Port |=" aktiviert wird und erst danach
über "Port &=" ausgeschaltet wird.
>Versuchs mal damit.
Siehe da, es läuft!!! Led1 an Pin2 blink. Danke! Aber wo denke ich
falsch?
@kbuchegg:
>NB: Das JTAG Interface am Mega32 hast du abgeschaltet?
Ja
>Dein Denkfehler dürfte sein:
Das unterstützt also dass was ich jetzt bei falk versucht habe zu
verstehen, dass eine Aktivierung als Ausgang über die Initialisierung
auf High erfolgt?? Und da die LED's an +5V liegen erst durch Low
eingeschaltet werden?? Sonst hätte ja Pin 3 nicht leuchten dürfen??
Und jetzt neu. Ich habe 1. meine Taster eingebaut und 2. Port C als ein
und Ausgang definiert. Port C Pin 2 flackert sehr schnell (dank @falk)
aber der Taster an Port C Pin 5 erzeugt nicht, dass die Led 2 auf Low
gesetzt wird:
1
#include<avr/io.h>
2
#define F_CPU 8000000L
3
#include<util/delay.h>
4
5
intmain(void){
6
DDRC|=(1<<DDC2)|(1<<DDC3);
7
DDRC&=~((1<<DDC5)|(1<<DDC6)|(1<<DDC7));
8
9
while(1){
10
PORTC|=(1<<2);/* setzt Bit 2 an PortC auf 1 */
11
PORTC|=(1<<3);/* setzt Bit 3 an PortC auf 1 */
12
_delay_ms(500);
13
PORTC&=~(1<<2);/* loescht Bit 2 an PortC */
14
_delay_ms(500);
15
if(!(PINC&(1<<PINC5))){
16
PORTC&=~(1<<3);/* loescht Bit 3 an PortC */
17
}
18
}
19
return0;
20
}
Hat jemand hier einen Hinweis??? Ich weiß es sind echt Grundlagen, sorry
aber Hardwareprogrammierung fange ich gerade erst an.
1/ Wie hast du den Taster eingebaut? Deine Programmlogik verlangt einen
Taster in Active-low Beschaltung. Hast du die in Hardware realisiert?
2/ Wenn dein Taster funktioniert, wie lange schätzt du vom
Programmablauf her, bleibt deine LED an Pin 3 von PortC tatsächlich aus?
@ Gast (Gast)
>Na aus dem AVR-GCC Tutorial von wwww.mikrokontroller.net>zusammengedampft
Naja, eher planlos zusamengerührt. Nimm erstmal die Beispiele 1:1 aus
den Tutorials, die sind getestet. Wen du dann ein wenig Durchblick hast,
dann kanst du anfangen selber was zusammenzurühren.
>kommt vorher ein "Port |=". Ich gehe also davon aus, dass jeder Pin der>verwendet wird zunächst über "Port |=" aktiviert wird und erst danach>über "Port &=" ausgeschaltet wird.
Grundlagen Grundlagen, Grundlagen.
Bitmanipulation>Siehe da, es läuft!!! Led1 an Pin2 blink. Danke! Aber wo denke ich>falsch?
So ziemlich überall.
1
#include<avr/io.h>
2
intmain(void){
3
DDRC=0xff;// alle Pins von Port C auf Ausgang schalten
4
//PORTC |= (1 << 2); /* setzt Bit 2 an PortC auf 1 */
5
PORTC&=~(1<<2);/* loescht Bit 2 an PortC, ein paar Take später (bei 1MHz sind das ein paar Mikrosekunden */
6
while(1){// Endlosschleife ohne Inhalt, die CPU macht genau GAR NICHTS!
7
}
8
return0;
9
}
>Und jetzt neu. Ich habe 1. meine Taster eingebaut und 2. Port C als ein>und Ausgang definiert. Port C Pin 2 flackert sehr schnell (dank @falk)>aber der Taster an Port C Pin 5 erzeugt nicht, dass die Led 2 auf Low>gesetzt wird:
1
_delay_ms(500);// Das geht so nicht, da die Funktion max. bis 270ms/F_CPU in MHz verzögern kann, bei 8 Mhz also bis ca. 33ms
>Hat jemand hier einen Hinweis??? Ich weiß es sind echt Grundlagen, sorry>aber Hardwareprogrammierung fange ich gerade erst an.
Eben, deshalb solltest du mal ALLE Tutorials lesen und ggf. darin nach
Lösungen suchen. Und ei Grundlagenbuch über C ist Pflicht!
AVR-TutorialAVR-Tutorial: IO-Grundlagen
MfG
Falk
So nicht:
>Das geht so nicht, da die Funktion max. bis 270ms/F_CPU in MHz verzögern >kann
Richtig:
The maximal possible delay is 262.14 ms / F_CPU in MHz
und
The maximal possible delay is 768 us / F_CPU in MHz
Gast wrote:
> Hat jemand hier einen Hinweis???
Welche Aussenbeschaltung weisen deine Taster auf?
Wie sind sie angeschlossen? Schalten sie nach Vcc oder
schalten sie nach Gnd? Gibt es einen externen Pullup / Pulldown
Widerstand?
> Ich gehe also davon aus, dass jeder Pin der verwendet wird zunächst> über "Port |=" aktiviert wird und erst danach über "Port &="> ausgeschaltet wird.
Er wird nicht "aktiviert" oder "ausgeschaltet", sondern zwischen high
(also mit +5V verbunden) und low (also mit Masse verbunden)
umgeschaltet, sofern er als Ausgang konfiguriert ist.
Hallo,
wenn ich das programiere, dann wird ja wenn PinC 0 betätigt wurde die
Anweisung ausgeführt.
Wie ist es wenn ich eine UND Verknüpfung haben will also zB PinC0 und
PinC7??
while(PINC & (1<<PINC0));
so was habe ich probiert geht aber nicht.
while(PINC & (1<<PINC0)|(<<PINC7));
Jens wrote:
> so was habe ich probiert geht aber nicht.> while(PINC & (1<<PINC0)|(<<PINC7));
Nö, wenn Du eine UND-Verknüpfung willst, musst Du die auch
programmieren. Also
Jens wrote:
> Es ist sehr seltsam diese Zeile weist ein UND Verhalten auf.> while((PINC & (1<<PINC0)) || (PINC & (1<<PINC1)));>> Woran liegt es???
An der negativen Logik.
Du kriegst eine 0, wenn dein Taster gedrückt ist.
OK Danke
jetzt will ich dass irgendwas ausgeführt wird wenn PINC7 gedrückt wird
ODER die Variable schleife=7 ist.
muss ich den PINC7 jetzt invertieren?
while(~(PINC & (1<<PINC7)) || (schleife==7));
Jens wrote:
> OK Danke>> jetzt will ich dass irgendwas ausgeführt wird wenn PINC7 gedrückt wird> ODER die Variable schleife=7 ist.> muss ich den PINC7 jetzt invertieren?>>> while(~(PINC & (1<<PINC7)) || (schleife==7));
Ja.
Es funktioniert leider nicht, ich habe schon alles probiert
(na ja anscheint nicht)
So funktioniert es nicht
Also wenn der PINC7 betätigt wurde (also Null) ODER Variable schleife=7
ist
soll irgendwas pasieren.
while(~(PINC & (1<<PINC7)) || (schleife==7));
Jens wrote:
> Es funktioniert leider nicht, ich habe schon alles probiert
Mit einem winzig kleinen Codeausschnitt ist es immer
schwierig irgendeinen Fehler zu disgnostizieren, aber ...
> Also wenn der PINC7 betätigt wurde (also Null) ODER Variable schleife=7> ist> soll irgendwas pasieren.>> while(~(PINC & (1<<PINC7)) || (schleife==7));
... solange der Strichpunkt da am Ende steht, wird aber nichts
passieren.
Du hast dadurch geschrieben:
Solange die Taste gedrückt ist oder schleife den Wert 7 hat,
tue nichts.
Ich würde dir empfehlen, deine ersten Schritte in C
mit einem normalen C-Buch deiner Wahl und einem
entsprechenden Compiler auf einem PC zu machen. Die
Debug-Möglichkeiten bzw. Ausgabemöglichkeiten und
damit auch deine Möglichkeiten zu verfolgen, was dein
Programm wirklich macht (im Gegensatz zu dem was du glaubst
das es machen sollte) sind einfach um Größenordnungen besser
als auf einem µC. Wenn du dort nicht über JTAG-Debugging
verfügst, bist du immer auf Raten und einen scharfen Blick
angewiesen um Probleme zu lokalisieren. Gerade am Anfang
fehlt dir aber massenweise Erfahrung um wirklich dumme
Tippfehler zu erkennen und du suchst stundenlang im Kreis
nach Dingen herum, die du auf einem PC im Debugger sehr schnell
sehen kannst. Nicht zu vergessen die zusätzlichen Möglichkeiten
die du hast, wenn du Variableninhalte 'live' während der
Programmausführung begutachten kannst.
Die dadurch vermeintlich verlorene Zeit, holst du sehr schnell
wieder herein.
Jörg X. wrote:
>> while(~(PINC & (1<<PINC7)) || (schleife==7));> eher doch>>> while( ! (PINC & (1<<PINC7)) || (schleife==7));> oder?>> ...
Yep. Das kommt auch noch dazu. Da hab ich am Abend nicht
aufgepasst.
Wenn PC7 auf 0 geht, dann ergibt
PINC & (1<<PINC7)
den Wert 0. Alle Bits umgedreht ergibt dann eine Zahl
ungleich 0 und damit logisch wahr.
Aber: Wenn PC7 auf 1 ist, dann ergibt
PINC & (1<<PINC7)
den Wert 1<<PINC7. Alle Bits umgedreht ergibt aber nicht
0 und damit auch nicht logisch falsch, sondern immer
noch logisch wahr.
Also: ! anstelle von ~
In meinen Augen ist es allerdings noch
besser hier, zumindest am Anfang, explizit zu sein:
Danke auch von mir an alle für die Hilfe, mit folgender Schaltung und
den dazugehörigen Befehlen habe ich endlich verstanden was ich mache und
kann den yC 'beobachten'.
1
/***AUFBAU
2
**
3
**Vcc
4
**|
5
**o
6
**|
7
**R
8
**|
9
**PINC5-o-----o--T--o-GND
10
**
11
**LESEN:
12
**-->!(PINC&(1<<PINC5))SCHALTERGEDRÜCKT
13
**-->(PINC&(1<<PINC5))SCHALTEROFFEN
14
**
15
**
16
**PINC2-o-----o-R-o-|<--o-Vcc
17
**LED
18
**
19
**SCHREIBEN:
20
**-->PORTC&=~(1<<2)LEDEIN
21
**-->PORTC|=(1<<3)LEDAUS
22
**
23
**
24
**
Vielleicht kann ich irgendwann auch mal helfen... später. Jetzt lese ich
erstmal weiter das schöne AVR-GCC Tutorial!