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
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?
Ach und: > Forum: Codesammlung > Wenn ihr eigene Programme oder Anleitungen geschrieben habt könnt ihr sie > hier posten. Fragen werden gelöscht!
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
@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
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;
[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
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
Vielen Dank, wieder was neues gelernt! habe es abgeändert und Simuliert. funktioniert alles wunderbar! MfG AmmannM
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?
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
> 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.
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?
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.