Forum: Mikrocontroller und Digitale Elektronik DIP-Schalter an ATmega8515


von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Guten Morgen liebe Community,

Ich habe heute schon lange versucht herauszufinden wie es den möglich 
sei, einen Schalter der mit GND und einem Pin des ATmegas verbunden ist, 
auf seinen Zustand hin "abzufragen"
(geschlossen, also Pin ist Low, oder offen, Pin ist High).

Schaltplan im Anhang:)

Hierzu kam mir folgende Idee:
1
DDRC  = 0x00; // Gesamter PORTC als Ausgang.
2
PORTC = 0xff; // Interne Pull up's an.
Nun noch eine Methode die für den Anfang mal nur PC0 auswerten soll.
1
int DMXStartadresse() 
2
{
3
4
volatile uint8_t y;
5
6
   if( PD0 == 1 )
7
   {
8
      y=1;
9
   }  
10
   if( PD0 == 0  )
11
   {
12
      y=2; 
13
   }
14
15
retourn y;
16
}
Diese Methode wird nun bei jedem neuen Schleifendurchlauf des 
Hauptprogrammes aufgerufen. Leider funktioniert das Ganze nicht richtig.


Ich währe für eine kleine Erklärung sehr dankbar :)

: Verschoben durch User
von asd (Gast)


Lesenswert?


von Christian K. (christiankarle)


Lesenswert?

Bedeutet das ich mein PD0 in PIND0 abändern muss oder?

von Karl H. (kbuchegg)


Lesenswert?

PD0 ist einfach nur ein anderer Name für 0.

Da
1
if( PD0 == 1 )
steht also einfach nur
1
if( 0 == 1 )

Bitte, tu dir selbst einen Gefallen und fang mit dem AVR-GCC-Tutorial 
an.
Pins auf 0 oder 1 setzen (also Output), Pins die auf Eingang geschaltet 
sind abzufragen ... das alles sind Standard-Aufgaben.
Da darf es keinerlei Probleme geben, das musst du im Schlaf beherrschen.
Wie es geht, steht alles im Tutorial. Das ist das allererste, was man 
auf einem µC lernen muss.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Und nachdem du das Tutorial durch hast:


In deinem Fall gibt es eine viel einfachere Möglichkeit, da du alle 8 
Schalter (mit denen du eine binäre Adresse von 0 bis 255 einstellst) 
schön alle an einem Port versammelt hast. Du brauchst daher da nicht wie 
wild mit den Bits einzeln rumfummeln, sondern du liest einfach alle 8 
Bits der Switches in einem Rutsch ein. Voila: du hast die Binärzahl, die 
ein Benutzer eingestellt hat, direkt in der Zielvariablen vorliegen.
1
uint8_t Address;
2
3
...
4
5
6
int main()
7
{
8
  DDRC = 0x00;   // alles auf Eingang
9
  PORTC = 0xFF;  // alle Pullups an
10
11
  // Adresse von den Switches einlesen
12
  Address = PINC;
13
...

Nichts desto trotz: Pins einzeln abfragen ist Basisfertigkeit. Das muss 
sitzen (mit einem großen MUSS)

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Christian Karle schrieb:

> Ich habe heute schon lange versucht herauszufinden wie es den möglich
> sei, einen Schalter der mit GND und einem Pin des ATmegas verbunden ist,
> auf seinen Zustand hin "abzufragen"
> (geschlossen, also Pin ist Low, oder offen, Pin ist High).

Aha. Also Urschleim.

> Hierzu kam mir folgende Idee:
>
> DDRC  = 0x00; // Gesamter PORTC als Ausgang.

Kommentar und Code stimmen nicht überein. Bzgl. Eingang oder Ausgang.

> Nun noch eine Methode die für den Anfang mal nur PC0 auswerten soll.
...
>    if( PD0 == 1 )

So so. PC0 oder PD0? Und wie kommst du auf die merkwürdige Idee, PD0 
wäre eine Variable? Um den Zustand der Pins an Port C abzufragen, 
liest man das PINC Register. Und schaut dann, ob in diesem 8-Bit Wert 
(aka unsigned char) das Bit mit der Nummer PC0 gesetzt ist:

1
if (PINC & (1<<PC0)) {
2
    return 1;
3
} else {
4
    return 2;
5
}

Ach ja: arbeite das Tutorial durch!


XL

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Entschuldigung, war doof von mir... eigentlich weis ich das schon...
Auf jeden Fall habe ich es jetzt hinbekommen Danke :)

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Entschuldigung, war doof von mir... eigentlich weis ich das schon...
> Auf jeden Fall habe ich es jetzt hinbekommen Danke :)

Wie hast du es gemacht?

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Christian Karle schrieb:
>> Entschuldigung, war doof von mir... eigentlich weis ich das schon...
>> Auf jeden Fall habe ich es jetzt hinbekommen Danke :)
>
> Wie hast du es gemacht?

Die einfachste Variante sieht so aus
1
...
2
3
int main(void)
4
{
5
  uint8_t dmxAddress;
6
7
  // Port mit den Switches auf Eingang und Pullups ein
8
  DDRC = 0x00;
9
  PORTC = 0xFF;
10
11
  // Kontrollled und RS485
12
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
13
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
14
15
  UART_Initialisieren();
16
17
  sei();
18
  while( 1 ) {
19
20
    dmxAddress = PINC;
21
22
    if( dmxData[dmxAddress] < 128 )
23
      PORTD |= ( 1 << LED );
24
    else
25
      PORTD &= ~( 1 << LED );
26
  }
27
}

von Christian K. (christiankarle)


Lesenswert?

Man kann die DMX-Adresse nicht direkt einlesen, da die einzelnen Pins 
mit einschalten des Schalters, auf Low gezogen werden...
Wenn man ihn direkt einliest, kommt nur Schwachsinn raus :)

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Habe es so gelöst :

int DMXStartadresse()

{
  volatile uint8_t y=0;
  volatile uint8_t b=0;
  volatile uint8_t a=0;
  volatile uint8_t c=0;
  volatile uint8_t d=0;

  // DIP "1" wird in "a" eingelesen.
  if ( PINC & ( 1 << PINC0 ) )
  {
    a= a+0;
  }
  if ( !( PINC & ( 1 << PINC0 ) ) )
  {
    a= a+1;
  }

  // DIP "2" wird in "b" eingelesen.
  if ( PINC & (1<<PINC1) )
  {
    b= b+0;
  }
  if ( !( PINC & ( 1 << PINC1 ) ) )
  {
    b= b+2;
  }

  // DIP "3" wird in "c" eingelesen.
  if ( PINC & (1<<PINC2) )
  {
    c= c+0;
  }
  if ( !( PINC & ( 1 << PINC2 ) ) )
  {
    c= c+4;
  }

  // DIP "4" wird in "d" eingelesen.
  if ( PINC & (1<<PINC3) )
  {
    d= d+0;
  }
  if ( !( PINC & ( 1 << PINC3 ) ) )
  {
    d= d+8;
  }



  y=(y+b+a+c+d);
  return y;

}


Ich habe übrigens die Additionen nur so ausführlich geschrieben damit es 
ein wenig anschaulicher ist.
Ich weis natürlich dass, das kürzer geht :)

von Route_66 (Gast)


Lesenswert?

Christian Karle schrieb:
> Man kann die DMX-Adresse nicht direkt einlesen, da die einzelnen Pins
> mit einschalten des Schalters, auf Low gezogen werden...

Es gibt auch einen Operator zum invertieren!

von Christian K. (christiankarle)


Lesenswert?

Stimmt...daran habe ich gar nicht gedacht...
Habs jetzt umgeschrieben :)

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.