Forum: Mikrocontroller und Digitale Elektronik codier schalter


von Johannes A. (kleinerkeiler96)


Lesenswert?

hallo. ich bin noch in der Lernphase und hab folgendes problem.

ich möchte durch einen codier schalter mein lcd zählen lassen.


zum beispiel: codier schalter auf 1 => lcd zeigt 1
                                  2 => lcd zeigt 2
                                  3 => lcd zeigt 3
                                          ...

der codier schalter ist BCD "fähig"
code 0 1 2 3 4 5 6 7 8 9
 1     1   1   1   1   1
 2       1 1     1 1
 4           1 1 1 1
 8                   1 1

die 0 hab ich jetzt weggelassen

logischer text für euch:

if (PINC & (1<<PINC0))
{
lcd_setcursor( 0 , 1 );
lcd_string("1");
lcd_setcursor( 0 , 2 );
lcd_string("Eins");
_delay_ms(100);

(schreibe 1)

}

else if (PINC & (1<<PINC1))
{
schreibe 2
}

else if (PINC & (1<<PINC0) | (1<<PINC1))
{
schreibe 3
}

mein problem ist, wenn ich auf 3 bin schreibt es eine 1...
was mach ich falsch.?

von Tom (Gast)


Lesenswert?

Johannes Adler schrieb:
> der codier schalter ist BCD "fähig"

Was ist da dran "BCD fähig?" Für Zahlen zwischen 0 und 9 sind Binär- und 
BCD-Zahlen identisch.

Die erforderliche Kodierung für deine LCD-Anzeige hängt davon ab, wie 
die angesteuert werden muß. Vermutlich mußt du die Binärzahl in eine 
ASCII-Zeichencode umsetzen.

von Johannes A. (kleinerkeiler96)


Lesenswert?

ja sorry wegen bcd fähig...
wusste nicht recht, wie ich es beschreiben soll...


wieso muss ich das in ascii umschreiben.?

ich habe die 4 pins vom codier schalter einfach als eingang gesetzt...

die 1 und 2 zeigt es ja an, das geht schon, jedoch wenn ich 2 eingänge 
auf einmal verwenden will
(PINC & (1<<PC0) | (1<<PC1))

funktioniert es nicht.

von Dieter W. (dds5)


Lesenswert?

Johannes Adler schrieb:
> die 1 und 2 zeigt es ja an, das geht schon, jedoch wenn ich 2 eingänge
> auf einmal verwenden will
>
> (PINC & (1<<PC0) | (1<<PC1))
>
> funktioniert es nicht.

Ich würde es mal mit einer UND Verknüpfung versuchen, denn bei "3" sind 
ja die Bits 0 UND 1 high.

(PINC & (1<<PC0) & (1<<PC1))

von Tom (Gast)


Lesenswert?

Johannes Adler schrieb:
> ... jedoch wenn ich 2 eingänge auf einmal verwenden will
> (PINC & (1<<PC0) | (1<<PC1))

Vermutlich meinst du
(PINC & 0x0f) == ((1<<PC0) | (1<<PC1))

Die Lösung mit den vielen IFs ist allerdings sehr aufwendig.

Einfacher wäre
  lcd_string((PINC & 0x0f) | 0x30 );
oder so ähnlich, d.h. eine direkte algorithmische Umsetzung vom 
Binärcode in den zugehörigen ASCII-Code

von Johannes A. (kleinerkeiler96)


Lesenswert?

dachte ich auch schon...es zeigt aber immer noch 1 an

von hilfe (Gast)


Lesenswert?

Mit 'PINC & (1<<PINC0)' möchtest du die Stellung 1 abfragen, aber bei 3 
ist sie eben auch gesetzt.
Versuche es doch mit (PINC & (PC0|PC1)) == 1

von Johannes A. (kleinerkeiler96)


Lesenswert?

Tom schrieb:
> lcd_string((PINC & 0x0f) | 0x30 );

was schreibe ich dann in die if schleife.? bzw. else if

von Johannes A. (kleinerkeiler96)


Lesenswert?

hilfe schrieb:
> Versuche es doch mit (PINC & (PC0|PC1)) == 1

die ideen sind schon richtig...es zeigt aber immer noch eins an

von STK500-Besitzer (Gast)


Lesenswert?

Johannes Adler schrieb:
> dachte ich auch schon...es zeigt aber immer noch 1 an

Mit etwas (funktionsfähigem) Code könnte man dir besser helfen...

von hilfe (Gast)


Lesenswert?

Dieter Werner schrieb:
> Ich würde es mal mit einer UND Verknüpfung versuchen, denn bei "3" sind
> ja die Bits 0 UND 1 high.
>
> (PINC & (1<<PC0) & (1<<PC1))

das geht natürlich nicht, weil der Wert von PINC zuerst mit PC0 maskiert 
wird, und damit die Position von PC1 gleich gelöscht wird.

von Johannes A. (kleinerkeiler96)


Lesenswert?

#include <avr/io.h>
#include "lcd-routines.h"
#include <util/delay.h>

int main(void)
{

  lcd_init();
  DDRC  = 0x00;

  while(1)
  {
   if (PINC & (1<<PC0))
    {


      lcd_setcursor( 0 , 1 );
      lcd_string("1");
      lcd_setcursor( 0 , 2 );
      lcd_string("Eins");
      _delay_ms(100);


    }
   else if (PINC & (1<<PC1))
    {

      lcd_setcursor( 0 , 1 );
      lcd_string("2");
      lcd_setcursor( 0 , 2 );
      lcd_string("Zwei");
      _delay_ms(100);
    }


  else if((PINC & (PC0|PC1)) == 1)
      {

      lcd_setcursor( 0 , 1 );
      lcd_string("3");
      lcd_setcursor( 0 , 2 );
      lcd_string("Drei");
      _delay_ms(100);

    }

  else
    {
      lcd_clear();
      lcd_setcursor( 0 , 1 );
      lcd_string("nix...");
      _delay_ms(100);
      lcd_clear();

    }
  }


  return 0;
}

von Johannes A. (kleinerkeiler96)


Lesenswert?

der code funktioniert so weit, außer bei 3

von hilfe (Gast)


Lesenswert?

Sorry, mit 'PINC & (PC0|PC1)'
dachte ich an (PINC & ((1<<PC0) | (1<<PC0))).

Wie sieht es wie folgt aus:
  switch (PINC & 0x03)
   case 1: ...
   case 2: ...
   case 3: ...
   default: ...

oder halt
  if ((PIN & 0x03) == 1)
  ...
  else if ((PIN & 0x03) == 2)
  ...
  else if ((PIN & 0x03) == 3)
  else
  ....

von gaast (Gast)


Lesenswert?

Vollkommen logisch. Im Fall 3 ist PC0 high, womit die erste Abfrage 
erfüllt wird.

von Johannes A. (kleinerkeiler96)


Lesenswert?

und wie kann ich das ändern.?

von Johannes A. (kleinerkeiler96)


Lesenswert?

hilfe schrieb:
> Sorry, mit 'PINC & (PC0|PC1)'
> dachte ich an (PINC & ((1<<PC0) | (1<<PC0))).
>
> Wie sieht es wie folgt aus:
>   switch (PINC & 0x03)
>    case 1: ...
>    case 2: ...
>    case 3: ...
>    default: ...
>
> oder halt
>   if ((PIN & 0x03) == 1)
>   ...
>   else if ((PIN & 0x03) == 2)
>   ...
>   else if ((PIN & 0x03) == 3)
>   else
>   ....



passiert immer noch nichts sinnvolles :(

von STK500-Besitzer (Gast)


Lesenswert?

Johannes Adler schrieb:
> passiert immer noch nichts sinnvolles :(

Dass da ein Fehler drin ist, hast du gemerkt, oder?

von Johannes A. (kleinerkeiler96)


Lesenswert?

wo drin

von Tom (Gast)


Lesenswert?

Johannes Adler schrieb:
> was schreibe ich dann in die if schleife.? bzw. else if

Welche IF-Schleife?
Irgendwie ist nicht ganz klar, wann du die Ausgabeposition im Display 
erhöhen möchtest? Immer wenn sich die Schalterstellung ändert?

von Johannes A. (kleinerkeiler96)


Lesenswert?

ja...

if(eingang)
{
lcd ausgang (text)
}

von STK500-Besitzer (Gast)


Lesenswert?

da drin:
>   else if ((PIN & 0x03) == 3)
>   else
>   ....

von Johannes A. (kleinerkeiler96)


Lesenswert?

else if ((PIN & 0x03) == 3)
else if (((PIN & 0x03) == 3))

das waah.?

hab ich schon bedacht.

von Lukas K. (carrotindustries)


Lesenswert?

Du solltest die Lösung von Tom weiterverfolgen und ausfindig machen, 
warum diese nicht geht. Die Lösung mit den vielen IFs ist sehr 
unelegant.

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Tom schrieb:
> Einfacher wäre
>   lcd_string((PINC & 0x0f) | 0x30 );
> oder so ähnlich, d.h. eine direkte algorithmische Umsetzung vom
> Binärcode in den zugehörigen ASCII-Code

Johannes Adler schrieb:
> Tom schrieb:
>> lcd_string((PINC & 0x0f) | 0x30 );
>
> was schreibe ich dann in die if schleife.? bzw. else if
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
5
int main(void)
6
{
7
8
  lcd_init();
9
10
  /* Warum der ganze Port? Für den Schalter reicht das erste Nibble. */
11
  DDRC  = 0x00;
12
13
  while(1)
14
  {
15
    lcd_setcursor( 0 , 1 );
16
17
    /* Vorraussetzung für folgende Zeile ist, das der
18
       Codierschalter an PC0 bis PC3 angeschlossen ist. */
19
      lcd_string((PINC & 0x0f) | 0x30 );
20
21
    /* Hier musst du dir noch was überlegen,
22
       mein Vorschlag wäre eine Array mit allen Strings. */
23
//  lcd_setcursor( 0 , 2 );
24
//  lcd_string("Eins");
25
    _delay_ms(100);
26
  }
27
28
  return 0;
29
}

von STK500-Besitzer (Gast)


Lesenswert?

Das einzge Problem am obigen Programm wäre die Beschaltung des 
Codierschalters: Werden die Digits gegen Vcc oder gegen GND geschaltet?
Das eine wäre eine Invertierung, die man mit einer "~" aus der Welt 
schaffen könnte...

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.