Warum geht das nicht?

Gast #1018544
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.
#1018560
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?
#1018578
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!
#1018581
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;
}
#1018590
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.
Gast #1018595
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
#1018651
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;

}
#1018656
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))
#1018691
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
Moderator (Firma: Titel) Persönliche Seite #1019435
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."
#1019452
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

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