www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C - Frage ;-) (BIN2BCD)


Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

bin vorgestern mal angefangen AVR's mit C (Codevision) zu
programmieren. Die Syntax erinnert mich sehr an PHP.
Ich möchte einen 16 bit Integer zu 5 BCD Digits wandeln:

Müsste doch eigentlich so funktionieren, oder?


  bcd10000=temp / 10000 ;
  temp2=temp % 10000 ;
  bcd1000=temp / 1000;
  temp2=temp % 1000 ;
  bcd100=temp / 100;
  temp2=temp % 100 ;
  bcd10=temp / 10;
  temp2=temp % 10 ;
  bcd1=temp ;

temp ist int und enthält die zahl die umgewandelt werden soll,
die anderen unsigned char

Bin für jede Hilfe dankbar.

Dominik

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned char  bcd[5];
for (loop=0;loop<5;loop++)
    {bcd[loop]=temp%10;
     temp=temp/10;
     }

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
crazy horse:
Habe mal fünf 7-Segmentanzeigen angeschlossen und gemultiplext, aber
irgendwie funktionieren deine Routinen genauso wenig wie meine?!?!
Die Routinen zum Multiplexen sind 100%ig richtig, weil wenn ich dem
array bcd[n] irgendwelche Zahlen zuweise werden die korekt angezeigt.

Gruß, Dominik

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
poste doch mal deinen Code, Dom!
Dann können sich auch andere mit dem Thema befassen.
Gruß Rahul

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
doch, das funktioniert schon. Es gibt andere Lösungsmöglichkeiten, die
schneller arbeiten, aber das ist erstmal die übersichtlichste. Wenn es
bei dir nicht funktioniert, liegt es nicht an dieser Routine, sondern
an einem anderen Programmteil oder an der Hardware. Im Blindflug wird
dir keiner weiter helfen können.

Autor: Malte Marwedel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du 7-Segment Anzeigen direkt ansteuerst (ohne zusätzlichen IC)
musst du dann noch mit einer Tabelle ermitteln welche LEDs bei welcher
Ziffer leuchten müssen. Denke aber mal dass du daran gedacht hast.

Folgende Routine hab ich mal für eine 4 Stellige 7-Segment-Anzeige
verwendet(die Werte für segcodierung müssten entsprechend an deine
Schaltung angepasst werden):

void setsegments(void) {//berechnet die ziffern
const u08 segcodierung[10] =
{0x6f,0x28,0x5d,0x79,0x3a,0x73,0x77,0x29,0x7f,0x7b};
u16 ziffer,temp01;//zu zeigender Wert
ziffer = 0;
if (dispmode == 0) {
  ziffer = hours*100+minutes;
}
if (dispmode == 1) {
  ziffer = day*100+month;
}
if (dispmode == 2) {
  ziffer = showwhour*100+showwminute;
}
//umrechnen
temp01 = segcodierung[(ziffer/1000)%10];
if ((temp01 == 0x6f)&&(dispmode == 0)){ //vorstehende Null entfernen
  temp01 = 0;
}
segment[0] = temp01;
segment[1] = segcodierung[(ziffer/100)%10];
segment[2] = segcodierung[(ziffer/10)%10];
segment[3] = segcodierung[ziffer % 10];
}

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal: Danke für die bisherigen Antworten!

Also wie gesagt, die Routinen zum multiplexen sind 100%ig okay. Ich
verwende nen BCD zu 7-Segment-Decoder der an PORTB[0..3] angeschlossen
ist. Die einzelnen Anzeigen werden über NPN-Transistoren eingeschaltet,
deren Basen an PORTD[0,1,4,5,6] (Ich brauche PD2 und PD3 für externe
INT's) angeschlossen sind.
Wie gesagt, bin Anfänger in C und habe µC's bisher nur in ASM
programmiert (Leider habe ich noch keinen Delphi, bzw. Pascal -
Compiler für AVR gefunden). Ich weiß, dass man den Teil für die Wahl
der Anzeige noch verkürzen kann, aber darum geht es mir erstmal nicht.
Achja, ich verwende nen AT90S2313 und CodeVisonAVR, hier die
Hauptschleife:

while (1)
      {

   temp2=12345;


for (loop=0;loop<5;loop++)
    {bcd[loop]=temp2%10;
     temp2=temp2/10;
     }

    ++anzeige ;
    if (anzeige == 6) anzeige=1;

    switch (anzeige) {
    case 0: temp1=0;
    break;
    case 1: temp1=1;
    PORTB=bcd[4];
    break;
    case 2: temp1=2;
    PORTB=bcd[3];
    break;
    case 3: temp1=16;
    PORTB=bcd[2];
    break;
    case 4: temp1=32;
    PORTB=bcd[1] ;
    break;
    case 5: temp1=64;
    PORTB=bcd[0];
    break;
    };
    PORTD=temp1;
    delay_ms(3);
    };


}


Wenn temp2 = 12345 wird auf den Anzeigen 55385 angezeigt.

Gruß, Dom

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

temp2=12345 wird korekt angezeigt, aber z.B. bei 33333 wird nur bei der
Zehnerstelle eine Null angezeigt und die restlichen Anzeigen sind aus
(sind wohl Pseudotetraden).

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Wenn temp2 = 12345 wird auf den Anzeigen 55385 angezeigt.
Nachtrag:
temp2=12345 wird korekt angezeigt"
Was denn nun?
Programm sieht richtig aus, wenn auch etwas umständlich.
Pseudotetraden können nicht auftreten, und wenn nur eine Ziffer
angezeigt wird, wird das wohl heissen, dass der Prozessor steht. Noch
irgendwelche (fehlerhafte) Interrupts laufen? Variablen richtig
deklariert?

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich bei "Nachtrag" schreibe, dass die 12345 doch richtig
angezeigt werden, dann wird das wohl auch gemeint sein?!?!!?

Natürlich können Pseudotetraden auftreten, a bis f sind beim BCD Code
Pseudotetraden. Ist das angelegte Datenwort am BCD zu 7Segm. Decoder
eine Pseudotetrade, dann werden alle Segmente dunkeln geschaltet.
Wenn der Prozessor stehen würde, dann würde wenn überhaupt nur eine
Anzeige leuchten. Da aber mehrere bzw. alle Ziffern etwas anzeigen ist
das nicht der Fall.

Interrups sind deaktiviert, Variablen sind so deklariert:

int temp2;
unsigned char temp1;
unsigned char  bcd[6];
unsigned char loop;

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bleib mal ruhig, du hast doch geschrieben, dass 55385 angezeigt wird.
Wenn die BCD-Variablen nur mit xxx=x%10 beschrieben werden, können
keine Pseudotetraden entstehen.

"wird nur bei der Zehnerstelle eine Null angezeigt und die restlichen
Anzeigen sind aus"
Deswegen dachte ich an die Möglichkeit, dass der Prozessor stehen
bleibt. Und dann kommt das nach:
"Wenn der Prozessor stehen würde, dann würde wenn überhaupt nur eine
Anzeige leuchten. Da aber mehrere bzw. alle Ziffern etwas anzeigen ist
das nicht der Fall."

Hast du noch Restalkohol? Stellst hier was in den Raum, behauptest im
nächsten posting das Gegenteil.
Ich mach jetzt einen auf Feiertag, und du solltest dir deine Sachen mal
ins AVR-Studio laden, dann wirst du sehen, wo der Hase im Pfeffer liegt,
ich habe keine Lust mehr zum Rätselraten.

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Hast du noch Restalkohol? Stellst hier was in den Raum, behauptest im
nächsten posting das Gegenteil."

Mir scheint eher, dass du den Restalkohl hast. Ich habe mich nur direkt
korrigiert, wenn du damit nicht klar kommst...

Einen schönen Feiertag noch!

Gruß, Dominik

Autor: Dom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab den Fehler gefunden ;-)

temp2 war vom typ int. int geht ja von -32768 bis 32767, dann ist es
klar, das Zahlen ab 32768 nicht gehen. mit unsigned int funktioniert es
tadellos.

Gruß, Dominik

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.