Anfänger mit C LED ein

Gast #663235
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?
Gast #663242
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.
Gast #672567
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??
#672636
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
#672692
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.
Gast #672710
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.
#672766
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
Gast #672780
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
Gast #672910
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.
Gast #674785
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));
Gast #674885
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));
Gast #675011
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));
#675092
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.
#675096
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.
#675105
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.
Gast #676794
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren