dezimal in 8-4-2-1 BCD

OP #1330558
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
Gast #1330574
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?
#1330596
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
OP #1331160
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
Gast #1331174
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;
Gast #1331179
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
#1331274
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
#1332694
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
#1332700
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.
OP #1332779
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?
Angehängte Dateien:
Gast #1332805
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.