Forum: Compiler & IDEs Warum geht das nicht?


von MrPink (Gast)


Lesenswert?

sorry bin blutiger anfänger und werde aus dem toturial einfach nciht 
schlau, bzw die foren suche hilft mir auch nciht weiter.


ich habe das programmier board STK500 und nen ATMEGA8

ich möchte zwei eingangspins vergleichen und je nach ergebniss etwas auf 
nem ausgangs pin rausschmeissen.



#include <avr/io.h>

int main (void)
{

   DDRD = 0x00;
   DDRB = 0xff;

   while(1)
   {
    if (PIND1 == PIND2)
    {
      PORTB1 = 1;
    }
   }

   return 0;
}

ich stelle mir jetzt vor das ich SW1 oder SW2 drücke und dann sollte 
doch LED1 aus gehen oder nicht?

ich habe schon so viel rumprobiert aber ich bekomme das nicht hin.

von (prx) A. K. (prx)


Lesenswert?

Weil da effektiv steht:
   if (1 == 2)

von Mr P. (mrpink)


Lesenswert?

habs auch schon mit = versucht dem gefällt das

PORTB1 = 1;

nicht.

main.c:11: error: lvalue required as left operand of assignment
main.c:13: error: lvalue required as left operand of assignment


Kann ich Überhaupt mit PORTB1 die einzelnen beinchen ansprechen? bzw dei 
auf 1 oder 0 setzen?

von Skua (Gast)


Lesenswert?

Wenn beide Tasten gleich sind geht die LED an.
Aus geht sie nie da gibts keine Anweisung für.

von Chris L. (kingkernel)


Lesenswert?

Schau dir mal das AVR-GCC-Tutorial hier auf der Seite an. Speziell das 
Ansprechen und Setzen von Ausgangsregistern!
Du musst so arbeiten PORTB |= 1 << PB1; für die ausgabe und PINB & (1 << 
PB0) für die eingabe.

Auf anhieb würde ich es so machen (ungetestet):
1
#include <avr/io.h>
2
3
int main (void)
4
{
5
6
   DDRD = 0x00;
7
   DDRB = 0xff;
8
9
   while(1)
10
   {
11
    if ((PIND & (1 << PD1)) == (PIND & (1 << PD2)))
12
    {
13
      PORTB |= 1 << PB1;
14
    }
15
   }
16
17
   return 0;
18
}
ausschalten kannst du die LED damit aber nicht mehr, dafür fehlt noch 
der entsprechende Code. Ausserdem geht die LED dann auch an, wenn beide 
Tasten NICHT gedrückt sind, es wird ja nur geprüft, ob beide Tasten die 
selbe Stellung haben!

von Helmut L. (helmi1)


Lesenswert?

>PORTB1 = 1;


PORTB |= 0x01;     sollte die LED anmachen
PORTB &= ~0x01;    sollte die LED ausmachen

Gruss Helmi

von Mr P. (mrpink)


Lesenswert?

Ja ok stimmt

allerdings bekomme ich den fehler was die ausgangs port zuweisung an 
geht nicht weg.


in C würde ich das so schreiben aber die PORTB1 zuweisung gibt immer den 
fehler:



#include <avr/io.h>

int main (void)
{

   DDRD = 0x00;
   DDRB = 0xff;

   while(1)
   {
    if (PIND1 == PIND2)
    {
      PORTB1 = 1;   //main.c:13: error: lvalue required as left operand 
of assignment
    }

    if (PIND1 != PIND2)
    {
      PORTB1 = 0;   //main.c:18: error: lvalue required as left operand 
of assignment
    }
   }

   return 0;
}

von Chris L. (kingkernel)


Lesenswert?

Oder das Direkte setzen des entsprechenden Bytes. In GCC ist es nicht 
möglich einzellne Pins eines Ports direkt anzusprechen!

von (prx) A. K. (prx)


Lesenswert?

PIND1 ist die Nummer des Portpins (und damit ziemlich blödsinnig). Nicht 
der Portpin selbst. Bei
  PORTB1 = 1;
steht also
  1 = 1;
da.

Was funktioniert:
  if (((PINB >> PINB1) ^ (PINB >> PINB2)) & 1)
    ...verschieden...
aber schön sieht es nicht aus.

Elegant wird das nur wenn die Portpins als Bitfeld definiert sind.

von gerd (Gast)


Lesenswert?

Hallo,
das ist quatsch:

if (PIND1 == PIND2)
    {
      PORTB1 = 1;
    }


Du kannst "Einzelpins" so nicht ansprechen.

Versuche mal:

if ( (PIND&(1<<PD1)) & (PIND&(1<<PD2)) )
{
   PORTB|=(1<<PB1);
}

so wird abgefragt ob beide Pins PD1 & PD2 true sind.

Ich glaube beim STK500 schalten die Taster auf Masse und die LED´s 
leuchten wenn der PORT Low ist.
Also hier:


//vorher
PORTB|=(1<<PB1); //PIN 5V => LED aus


if ( (!(PIND&(1<<PD1)) & (!(PIND&(1<<PD2)) )
{
   PORTB&=~(1<<PB1);
}


Hier ist alles ganz genau erklärt: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Hier hilft als Anfänger nur lesen, lesen, probieren, lesen ;-)

gerd

von Mr P. (mrpink)


Lesenswert?

Erstmal danke für die hilfe (obwohl ich das auch im toturial hätte 
finden müssen)

denke auch ich habe es soweit verstanden

allerdings muss irgendwo noch ein logikfehler sein

SW1=0 SW2=1 LED0=0 (an)   ok
SW1=1 SW2=0 LED0=0 (an)   ok
SW1=1 SW2=1 LED0=1 (aus)  ok
SW1=0 SW2=0 LED0=0 (an)   nicht ok


#include <avr/io.h>

int main (void)
{

   DDRD = 0x00;
   DDRB = 0xff;

   while(1)
   {
    if ( ~((PIND&(1<<PD1)) ^ (PIND&(1<<PD2))) )
    {
      PORTB |= (1<<PB0);
    }

    if ( (PIND&(1<<PD1)) ^ (PIND&(1<<PD2)) )
    {
      PORTB &= ~(1<<PB0);
    }
   }
   return 0;

}

von (prx) A. K. (prx)


Lesenswert?

PIND&(1<<PD1) => Wert 0x00 oder 0x02
PIND&(1<<PD2) => Wert 0x00 oder 0x04

if ( ~((PIND&(1<<PD1)) ^ (PIND&(1<<PD2))) )
  läuft also auf
if ( ~(0x02 ^ 0x04) )
  raus. Wieder nix, weil dabei ~0x06 rauskommt. Wenn schon so, dann
if (((PIND&(1<<PD1)) != 0) == ((PIND&(1<<PD2)) != 0))

von Mr P. (mrpink)


Lesenswert?

das ist doch nur die abfrage für (sw1=1 und sw2=1)  also "AND"       ... 
oder?

ich suche ein XNOR

X  Y  |  Q
 ----------
0  0  |  1
0  1  |  0
1  0  |  0
1  1  |  1

von (prx) A. K. (prx)


Lesenswert?

Wenn das eine Antwort auf mein Posting war: falsch.
  (PIND&(1<<PD1)) != 0) => 0 oder 1
  (PIND&(1<<PD2)) != 0) => 0 oder 1

von Mr P. (mrpink)


Lesenswert?

Ok danke

irgendwie ist das board komisch ...

die LED leuchtet zwar die ganzezeit .... aber wenn ich SW1 oder SW2 
drücke leuchtet sie etwas heller, bzw geht aus wenn ich beide drücke 
..... der code muss aber richtig sein.

bei invertierter ausgabe funktioniert die schaltung

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> die LED leuchtet zwar die ganzezeit .... aber wenn ich SW1 oder SW2
> drücke leuchtet sie etwas heller, bzw geht aus wenn ich beide drücke

Dann wird sie ohne Tastendruck sehr schnell ein- und wieder 
ausgeschaltet. Mit 1 Taste dann ganz ein, mit beiden Tasten ganz aus. 
Warum, das kann man ohne den zugehörigen Code (der übrigens mit [/c] und 
[c] schön formatiert wird) nicht sagen.

> ..... der code muss aber richtig sein.
Ja, wie sagte der Programmierer selbstbewusst: "Mein Code läuft."

von Peter D. (peda)


Lesenswert?

Christian L. wrote:
> Oder das Direkte setzen des entsprechenden Bytes. In GCC ist es nicht
> möglich einzellne Pins eines Ports direkt anzusprechen!

Das ist Quatsch.

Natürlich kann man in GCC Bitvariablen definieren und damit einzelne 
Portpins ansprechen. Ich mache das schon lange so.
Dadurch sehen die Programme gleich viel übersichtlicher aus.

Die ultimative Lösung wurde 2006 von Volker gepostet:

Beitrag "Re: #define in C"


Sie wurde kürzlich erst in das AVR-Tutorial aufgenommen:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=67368


Peter

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.