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
unsigned char bcd[5]; for (loop=0;loop<5;loop++) {bcd[loop]=temp%10; temp=temp/10; }
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
poste doch mal deinen Code, Dom! Dann können sich auch andere mit dem Thema befassen. Gruß Rahul
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.
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]; }
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
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).
"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?
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;
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.
"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
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
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.