Forum: Mikrocontroller und Digitale Elektronik dezimal in 8-4-2-1 BCD


von Michael A. (ammannm)


Lesenswert?

Hallo Profis!

Kenne die Programmiersprache C erst seit ca. 3 Tagen!
Suche nun einen Code der mir eine Zahl von 0-9 in einen BCD Code 
umwandelt.

Etwa so:
0 = 0000
1 = 0001
2 = 0010
Usw.

Den BCD Code möchte ich auf z.B. PortB ausgeben.

Wie funktioniert die Umwandlung und wie die Ausgabe?

Vielen Dank für eure Hilfe!

Ps: Kann gut sein das diese Frage schon einmal behandelt wurde, habe 
aber mit der Suchfunktion keine Antwort darauf gefunden. Wenn es dies 
trotzdem gibt, bitte Beitrag löschen vorher aber Link mitteilen. Danke

: Verschoben durch User
von Gast (Gast)


Lesenswert?

Wenn es nur von 0-9 geht kannst du den Wert direkt an einen Port 
ausgeben (evtl. die oberen 4 Bit wegmaskieren)
Die Zahlen sind im Controller schon Binär vorhanden, da gibts kein 
Dezimal.

Wo kommen die 0-9 her?

von Gast (Gast)


Lesenswert?

Ach und:
> Forum: Codesammlung
> Wenn ihr eigene Programme oder Anleitungen geschrieben habt könnt ihr sie
> hier posten. Fragen werden gelöscht!

von Peter D. (peda)


Lesenswert?

Michael Ammann schrieb:
> Suche nun einen Code der mir eine Zahl von 0-9 in einen BCD Code
> umwandelt.

???

Nimm einen Taschenrechner (z.B. Windows), tippe die Ziffer 9 ein, 
schalte um auf Binärdarstellung, was siehst Du?

Tip:
Alle Zahlen werden CPU-intern binär dargestellt.


Peter

von Michael A. (ammannm)


Lesenswert?

@Peter
Ich habe geschriben ich suche einen Code der mir die Zahlen umwandelt 
nicht wie ICH ihn umwandeln kann.
1
#include <stdio.h>
2
#include <avr/io.h>         
3
 
4
main () { 
5
          
6
int einer;
7
int zehner;
8
9
einer = 0; 
10
zehner = 0;
11
12
13
  DDRB  = 0b11111111;    /*PortB als Ausgang setzen*/
14
15
  while(zehner != 12) {  /* wird nie erreicht*/
16
17
    if ( PIND & 0b00000001 ) {  /*Bit 0 an Port A = 1 ?*/
18
19
        einer = einer + 1;  
20
  
21
      if (einer > 9)  
22
      {
23
        einer = 0;  /* einer auf null stellen wenn 10 erreicht */
24
        zehner = zehner + 1;
25
      }
26
      
27
      if (zehner > 9)
28
      {
29
        zehner = 0;
30
      }      
31
    }
32
33
    if ( PIND & 0b00000010 ) {  /*Bit 0 an Port A = 1 ?*/
34
35
        einer = einer - 1;  
36
  
37
      if (einer < 0)  
38
      {
39
        einer = 9;  /* einer auf neun stellen wenn -0 erreicht */
40
        zehner = zehner - 1;
41
      }
42
      
43
      if (zehner < 0)
44
      {
45
        zehner = 0;
46
      }      
47
    }
48
        
49
  }
50
51
}

Nun möchte ich am PortB den BCD Code ausgeben: also Bit 0-3 = Einer Bit 
4-7 = Zehner

Gast schrieb:
> Wenn es nur von 0-9 geht kannst du den Wert direkt an einen Port
> ausgeben (evtl. die oberen 4 Bit wegmaskieren)
> Die Zahlen sind im Controller schon Binär vorhanden, da gibts kein
> Dezimal.

Könnte man dann schreiben
1
PORTB = einer + zehner;
oder ähnlich?

MfG AmmannM

von Bjojon (Gast)


Lesenswert?

Nicht ganz, du muß die Zehnerstellen auf die oberen 4 Bit schieben, 
sonst addierst du nur die beiden Stellen.

Sollte so aussehen:

Bit    7654 3210
Stelle ZZZZ EEEE

Also im Quelltext:

PORTB = (zehner<<4)|einer;

von willi (Gast)


Lesenswert?

[c]

PORTB = (einer & 0b00001111) | (zehner<<4)

[c\]

der code "löscht" die ersten 4 bit von EINER, packt die in die unteren 4 
bit von PORTB, und packt dann die unteren 4 bit von ZEHNER in die oberen 
4 bit von PORTB

von Michael A. (ammannm)


Lesenswert?

Vielen Dank für die Hilfe! Werde den Code austesten.

von Peter D. (peda)


Lesenswert?

Michael Ammann schrieb:
> @Peter
> Ich habe geschriben ich suche einen Code der mir die Zahlen umwandelt
> nicht wie ICH ihn umwandeln kann.

Wie gesagt, da gibt es nichts umzuwandeln!
Intern ist alles binär, es gibt ja nur 0- und 1-Bits.
1
> int einer;
2
> int zehner;
Das ist Verschwendung, Du brauchst keine 16 Bit, um einen 4Bit-Wert 
darzustellen.
Das kleinste Format in C ist 8 Bit, nimm es:
1
uint8_t einer;
2
uint8_t zehner;

> Nun möchte ich am PortB den BCD Code ausgeben: also Bit 0-3 = Einer Bit
> 4-7 = Zehner

Das hattest Du aber vorher nicht erwähnt.

Einfach beide nicht gewandelten Werte verodern, vorher den Zehner um 4 
Bit nach links schieben.


Peter

von Michael A. (ammannm)


Lesenswert?

Vielen Dank, wieder was neues gelernt! habe es abgeändert und Simuliert. 
funktioniert alles wunderbar!
MfG AmmannM

von Michael A. (ammannm)


Lesenswert?

Nun habe ich aber warscheinlich noch ein anderes Problem. Wen die 
Befehle mit dem internen oszilator ablaufen also mit cg. 20Mhz (mal 
angenomen) und ich mit einem Taster den Eingang schalte, dan zählt es ja 
zu schnell auf und ab. Oder mache ich einen Überlegungsfehler?

von Karl H. (kbuchegg)


Lesenswert?

Michael Ammann schrieb:
> und ich mit einem Taster den Eingang schalte, dan zählt es ja
> zu schnell auf und ab.


> Oder mache ich einen Überlegungsfehler?

Das kann sein.
Kommt immer darauf an, was du willst.

Willst du, dass dein µC zählt solange eine Taste gedrückt ist

Oder willst du haben, dass dein µC nur dann zählt, wenn eine Taste 
gedrückt wurde. Sprich: wenn sich der Zustand der Taster von 'nicht 
gedrückt' in 'gedrückt' verändert.

Bei ersterem, reicht es aus, wenn du nur den aktuellen Zustand der Taste 
betrachtest. Bei letzterem musst du den jetztigen Tastenzustand mit dem 
Tastenzustand kurz davor vergleichen. Nur wenn der sich ändert, hat der 
Benutzer eine Taste gedrückt.

Wenns denn dann nur so einfach wäre. In der Praxis kommt dann auch noch 
das Problem der prellenden Taster dazu.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

von Karl H. (kbuchegg)


Lesenswert?

> Ich habe geschriben ich suche einen Code der mir die Zahlen
> umwandelt nicht wie ICH ihn umwandeln kann.

Voraussetzung um überhaupt ein Programm schreiben zu können ist es 
immer, dass der Programmierer ein Problem mit Papier und Bleistift lösen 
kann. Wenn man ein Problem, zumindest im Prinzip, nicht selbst lösen 
kann, kann man auch kein Programm dafür schreiben.

von Michael A. (ammannm)


Angehängte Dateien:

Lesenswert?

Ziel dieses Projektes ist es zwei 7Segment anzeigen anzusteuern via BCD.
Dabei möchte ich mit einem Taster höchzählen (0-99) mit dem zweiten 
runterzählen und beim Drücken beider Taster = Lampentest (88).

Ich weis das diese Aufgabe für einen mc eigentlich zu klein ist aber 
irgeneinmal kommt noch mehr dazu und ich bin somit flexibel. Um Pins zu 
sparen kommt die BCD ausgabe zum zuge. Habe ein ATTiny 461-20PU.
(Zum üben habe ich noch ein AVR Butterfly Demoboard)

Tasten entprellen:
Würde auch ein Kondensator reichen?

von Sumynona (Gast)


Lesenswert?

> Tasten entprellen:
> Würde auch ein Kondensator reichen?

Der bringt sicher Besserung, darauf verlassen kann man sich aber auf 
keinen Fall.

http://www.mikrocontroller.net/articles/Entprellung
(weiter unten im Artikel steht Softwareentprellung)

die Zahlen dann auf 7seg darstellen ist trivial
1
uint8_t wert = 95; //Wert der angezeigt werden soll
2
3
uint8_t zehner = (wert / 10);
4
uint8_t einer = (wert % 10);
5
6
//Ausgabe
7
PORTB = (zehner << 4) | einer;

Gut, das ganze geht auch ein stück effizienter, aber dein Controller 
langweilt sich ja noch.

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.