www.mikrocontroller.net

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


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Link

|=
&= ~

was bedeuten diese Zeichen?

Autor: interessent (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 (~).

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry für die dummen Fragen aber jeder hat mal klein angefangen.

Danke für die Hilfe

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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=modloa...

"C Kurs AOL Programmierforum"

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

Gruss

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi ich bin auch ein Anfänger bei yC. Ich habe mir eine Reihe Tutorials 
durchgelesen und das mega-simple BSP abgetippt:
#include <avr/io.h>
int main (void) {
   DDRC = 0xff;
   //PORTC |= (1 << 2);    /* setzt Bit 2 an PortC auf 1 */
   PORTC &= ~(1 << 2);   /* loescht Bit 2 an PortC */
   while(1) {
   }
   return 0;
}
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??

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#define F_CPU 1000000L
#include <util/delay.h>

int main (void) {
   DDRC = 0xff;
   while (1) {  
       PORTC |= (1 << 2);    /* setzt Bit 2 an PortC auf 1 */
       _delay_ms(20);
       PORTC &= ~(1 << 2);   /* loescht Bit 2 an PortC */
       _delay_ms(20);
   }
   return 0;
}

MFG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#define F_CPU 8000000L
#include <util/delay.h>

int main (void) {
   DDRC |= (1 << DDC2) | (1 << DDC3);
   DDRC &= ~( (1 << DDC5) | (1 << DDC6) | (1 << DDC7));
   
   while (1) {
       PORTC |= (1 << 2);    /* setzt Bit 2 an PortC auf 1 */
       PORTC |= (1 << 3);    /* setzt Bit 3 an PortC auf 1 */
       _delay_ms(500);
       PORTC &= ~(1 << 2);   /* loescht Bit 2 an PortC */
       _delay_ms(500);
       if ( !(PINC & (1 << PINC5)) ) {
          PORTC &= ~(1 << 3);   /* loescht Bit 3 an PortC */
       }
   }
   return 0;
}
Hat jemand hier einen Hinweis??? Ich weiß es sind echt Grundlagen, sorry 
aber Hardwareprogrammierung fange ich gerade erst an.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
int main (void) {
   DDRC = 0xff;        // alle Pins von Port C auf Ausgang schalten
   //PORTC |= (1 << 2);     /* setzt Bit 2 an PortC auf 1 */
   PORTC &= ~(1 << 2);      /* loescht Bit 2 an PortC, ein paar Take später (bei 1MHz sind das ein paar Mikrosekunden */
   while(1) {               // Endlosschleife ohne Inhalt, die CPU macht genau GAR NICHTS!
   }
   return 0;
}


>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:
       _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

Autor: Es (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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));

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es gerade so gemacht (DANKE) es ist aber leider ein ODER 
Verhalten

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

Autor: Jens (Gast)
Datum:

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

Woran liegt es???

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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));

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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));

Autor: Jörg X. (Gast)
Datum:

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

...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Damit kann dann nicht allzuviel schief gehen.

Autor: Jens (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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'.
/*** AUFBAU
**
**             Vcc
**              |
**              o
**              |
**              R
**              |
** PINC5 -o-----o--T--o-GND
**
** LESEN:
** --> !(PINC & (1 << PINC5)) SCHALTER GEDRÜCKT
** --> (PINC & (1 << PINC5)) SCHALTER OFFEN
**
**
** PINC2 -o-----o-R-o-|<--o-Vcc
**                    LED
**
** SCHREIBEN:
** --> PORTC &= ~(1 << 2) LED EIN
** --> PORTC |= (1 << 3) LED AUS
**
**
**
Vielleicht kann ich irgendwann auch mal helfen... später. Jetzt lese ich 
erstmal weiter das schöne AVR-GCC Tutorial!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.