Forum: Compiler & IDEs Anfänger mit C LED ein


von Jens (Gast)


Lesenswert?

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;

von Karl H. (kbuchegg)


Lesenswert?


von Jens (Gast)


Lesenswert?

Danke für den Link

|=
&= ~

was bedeuten diese Zeichen?

von interessent (Gast)


Lesenswert?

~ 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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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 (~).

von Jens (Gast)


Lesenswert?

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?

von Johannes M. (johnny-m)


Lesenswert?

Kauf Dir ein C-Buch! Da steht alles drin. Das Forum ist kein Platz, an 
dem man  sich die absoluten C-Grundlagen von anderen herunterbeten 
lassen kann.

von Thomas (Gast)


Lesenswert?

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.

von Jens (Gast)


Lesenswert?

Sorry für die dummen Fragen aber jeder hat mal klein angefangen.

Danke für die Hilfe

von Stefan (Gast)


Lesenswert?

zum Thema klein anfangen:

lies dir das mal durch, da stehen alle C-Grundlagen drinn:

http://www.c-plusplus.de/cms/modules.php?op=modload&name=Downloads&file=index&req=viewsdownload&sid=3

"C Kurs AOL Programmierforum"

Es ist sehr einfach und verständlich geschrieben, finde ich.

Gruss

von Gast (Gast)


Lesenswert?

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
int main (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
   return 0;
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??

von Falk B. (falk)


Lesenswert?

@  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.
1
#include <avr/io.h>
2
#define F_CPU 1000000L
3
#include <util/delay.h>
4
5
int main (void) {
6
   DDRC = 0xff;
7
   while (1) {  
8
       PORTC |= (1 << 2);    /* setzt Bit 2 an PortC auf 1 */
9
       _delay_ms(20);
10
       PORTC &= ~(1 << 2);   /* loescht Bit 2 an PortC */
11
       _delay_ms(20);
12
   }
13
   return 0;
14
}

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

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.

von Gast (Gast)


Lesenswert?

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
int main (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
   return 0;
20
}
Hat jemand hier einen Hinweis??? Ich weiß es sind echt Grundlagen, sorry 
aber Hardwareprogrammierung fange ich gerade erst an.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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?

von Falk B. (falk)


Lesenswert?

@ 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
int main (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
   return 0;
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-Tutorial
AVR-Tutorial: IO-Grundlagen

MfG
Falk

von Es (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Jens (Gast)


Lesenswert?

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));

von Johannes M. (johnny-m)


Lesenswert?

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
1
while((PINC & (1 << PINC0)) && (PINC & (1 << PINC7)));

von Jens (Gast)


Lesenswert?

Ich habe es gerade so gemacht (DANKE) es ist aber leider ein ODER 
Verhalten

while((PINC & (1<<PINC0)) && (PINC & (1<<PINC1)));
   {
   .
   .
   .
   }

von Jens (Gast)


Lesenswert?

Es ist sehr seltsam diese Zeile weist ein UND Verhalten auf.
while((PINC & (1<<PINC0)) || (PINC & (1<<PINC1)));

Woran liegt es???

von Johannes M. (johnny-m)


Lesenswert?

Jens wrote:
> Woran liegt es???
Vielleicht daran, dass Deine Eingangssignale invertiert sind? Taster 
gegen Masse angeschlossen -> gedrückt ist 0...

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens (Gast)


Lesenswert?

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));

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens (Gast)


Lesenswert?

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));

von Jörg X. (Gast)


Lesenswert?

> while(~(PINC & (1<<PINC7)) ||  (schleife==7));
eher doch
>> while( ! (PINC & (1<<PINC7)) ||  (schleife==7));
oder?

...

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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:
1
  while( ( PINC & ( 1<<PINC7) ) == 0 || schleife == 7 ) )
2
  {
3
    // tu was immer es zu tun gibt
4
  }

Damit kann dann nicht allzuviel schief gehen.

von Jens (Gast)


Lesenswert?

Ich danke euch allen, besonders dem Karl Heinz für die Konstruktive 
Hilfe auch
in anderen Themen.

von Gast (Gast)


Lesenswert?

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)) SCHALTER GEDRÜCKT
13
** --> (PINC & (1 << PINC5)) SCHALTER OFFEN
14
**
15
**
16
** PINC2 -o-----o-R-o-|<--o-Vcc
17
**                    LED
18
**
19
** SCHREIBEN:
20
** --> PORTC &= ~(1 << 2) LED EIN
21
** --> PORTC |= (1 << 3) LED AUS
22
**
23
**
24
**
Vielleicht kann ich irgendwann auch mal helfen... später. Jetzt lese ich 
erstmal weiter das schöne AVR-GCC Tutorial!

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.