Hallo Leute, komme mit folgendem Problem nicht weiter. Habe folgenden Charakter definiert: char cwert[5]; cwert[3]='7'; //Nachkommastelle cwert[2]='4'; //Einerstelle cwert[1]='5'; //Zehnerstelle cwert[0]='1'; //Hunderterstelle Diesen würde ich gerne an meine "Printnumberfunktion" übergeben: printnumber(cwert); void printnumber(char zahl){ int i; for (i=0; i<15; i++) { PORTC |=0x06; SevenSegment(zahl[3]); PORTC = (1<<PC0); ) _delay_ms(3); . . . } } ...um damit diese Werte auf meiner 7 Segmentanzeige darstellen zu können. Kann mir jemand weiterhelfen, was ich da falsch mache? Stehe gerade völlig auf dem Schlauch.
Erst mal würde ich den Richtigen Datentyp an "printnumber" übergeben. Grüsse
Kann es ja so mit einem Pointer machen, dann geht das schonmal. void printnumber(char* zahl) aber wie weiter?
Diese sieht so aus: void SevenSegment(n) { switch (n) case 0: SEVEN_SEGMENT_PORT=0b00111111; break; case 1: SEVEN_SEGMENT_PORT=0b00000110; break; case 2: SEVEN_SEGMENT_PORT=0b01011011; break; case 3: SEVEN_SEGMENT_PORT=0b01001111; break; case 4: SEVEN_SEGMENT_PORT=0b01100110; break; case 5: SEVEN_SEGMENT_PORT=0b01101101; break; case 6: SEVEN_SEGMENT_PORT=0b01111101; break; case 7: SEVEN_SEGMENT_PORT=0b00000111; break; case 8: SEVEN_SEGMENT_PORT=0b01111111; break; case 9: SEVEN_SEGMENT_PORT=0b01101111; break; case 10: SEVEN_SEGMENT_PORT=0b01000000; break; } }
Welcher Datentyp soll der Funktion "SevenSegment" übergeben werden? Ich weiss, es ist lästig sich an die Syntax der Programmiersprache zu halten. Es macht aber die Programmiererei weniger Frustrierend. Grüsse
Walter_P schrieb: > Diese sieht so aus: > > void SevenSegment(n) > { > switch (n) > case 0: SEVEN_SEGMENT_PORT=0b00111111; break; > case 1: SEVEN_SEGMENT_PORT=0b00000110; break; > ... > case 10: SEVEN_SEGMENT_PORT=0b01000000; break; Man könnte auch auf die Idee kommen, die Bitmuster aus einem Array zu holen, statt eine endlose case-Konstruktion abzuklappern.
Läuft jetzt ja soweit... Eine Frage wäre da aber noch. Angenommen ich habe eine Floatzahl wie bspw. 324.86 Diese würde ich gerne auf eine Nachkommastelle runden lassen und dann direkt in mein Array schreiben lassen und nicht wie bisher per Hand eintragen. Hatte das umwandeln mit sprintf versucht, aber dann gibt meine Segmentanzeige nur noch Quatsch aus. Kann mir dazu nochmal bitte jemand helfen?
Walter_P schrieb: > Hatte das umwandeln mit sprintf versucht, aber dann gibt meine > Segmentanzeige nur noch Quatsch aus. lass dazu bloß keinen quelltext sehen... das könnte ja bei der fehlersuche helfen.
Dann zeig doch mal was "sprintf" aus deiner Zahl generiert. Wie rufst Du "sprintf" auf. Beachtest du auch die Datentypen? Wie sieht dein Format-String aus? "sprintf" kann auch runden. Grüsse
Sieht so aus: Die Segmentanzeige gibt allerdings nur 0000 aus. void main() { int i; double number=324.86; char cwert[7]; sprintf (cwert, "%f", number); //cwert[3]=2; //Nachkommastelle //cwert[2]=3; //Einerstelle //cwert[1]=8; //Zehnerstelle //cwert[0]=4; //Hunderterstelle //Setup SEVEN_SEGMENT_DDR=0xFF; //Define PORTD as output SEVEN_SEGMENT_PORT=0xFF; //All segments off DDRC=0xFF; //Define PORTC as output PORTC=(1<<PC3) | (1<<PC2) | (1<<PC1) | (1<<PC0); //Digits für Port 0-3 setzen while(1) { { for(i=0; i<6; i++) printnumber(cwert,0); } } }
Wozu die for-Schleife? Du übergibst doch das cwert als Array nur einmal! Innerhalb von "printnumber" hast Du dann die Schleife über die einzelnen Array Elemente. Achte auf die Datentypen!!!!!!!!!!!!!!!!!!!!!!!! Zeig mal bitte deine "Neue" "printnumber" Funktion. Grüsse
void printnumber(char* zahl, uint8_t unter0){ int i; for (i=0; i<20; i++) { PORTC |=0x06; //SevenSegment(n%10,0); SevenSegment(zahl[3],0); PORTC = (1<<PC0); //Enable Nachkommadisplay (PC0) _delay_ms(3); PORTC |=0x06; //SevenSegment((n/10)%10,0); SevenSegment(zahl[2],0); PORTC = (1<<PC1); //Enable Einerdisplay (PC1) _delay_ms(3); . . . } }
Ich habe mal ein wenig aufgeräumt. Das Bit Gedöns hab ich mal weg gelassen und nur die Zahlenverarbeitung betrachtet. Das Code Beispiel hat keinen Anspruch auf Vollständigkeit.
1 | unsigned char ziffern[] = |
2 | {
|
3 | 0b00111111, // 0 |
4 | 0b00000110, // 1 |
5 | 0b01011011, // 2 |
6 | 0b01001111, // 3 |
7 | 0b01100110, // 4 |
8 | 0b01101101, // 5 |
9 | 0b01111101, // 6 |
10 | 0b00000111, // 7 |
11 | 0b01111111, // 8 |
12 | 0b01101111, // 9 |
13 | 0b01000000 // 10 |
14 | }
|
15 | |
16 | void SevenSegment(uint8_t n, uint8_t m) |
17 | {
|
18 | SEVEN_SEGMENT_PORT = ziffern[n - '0']; |
19 | }
|
20 | |
21 | void printnumber(char* zahl, uint8_t unter0) |
22 | {
|
23 | int i = 0; |
24 | |
25 | while (zahl[i] != 0) // Prüfung auf 0 da C-String |
26 | {
|
27 | SevenSegment(zahl[i], 0); |
28 | i++; |
29 | }
|
30 | }
|
31 | |
32 | void main() |
33 | {
|
34 | double number=324.86; |
35 | char cwert[7]; |
36 | sprintf (cwert, "%f", number); |
37 | |
38 | while(1) |
39 | {
|
40 | printnumber(cwert, 0); |
41 | }
|
42 | }
|
Grüsse
Geht leider doch nicht so wie es soll. Dein Code läuft zwar, allerdings nur wenn ich einen Integerwert benutze und entsprechend auch sprintf mit %i statt %f benutze. Also: int number=3243; char cwert[7]; sprintf (cwert, "%i", number); while(1) { printnumber(cwert, 0); } } Leider bekomme ich bei einem double Wert nur "Blankstriche" ausgegeben. Warum?
Und wie sieht deine Printnumber Funktion aus? Im übrigen: Es bringt nicht viel, wenn du den Code postest, der funktioniert. Der Fehler steckt im anderen Code - irgendwo. Daher sollte man den betrachten. Und zwar möglichst vollständig.
PS. Sehe ich das richtig, dass du nur eine einzelne 7_Segment Anzeige hast, an der du nacheinander die einzelnen 'Stellen' deiner Zahl ausgeben möchtest?
Nein, es sind 4 Anzeigen: Der Code für die Printnumerberfunktion:
1 | void printnumber(char* zahl, uint8_t unter0) |
2 | {
|
3 | |
4 | PORTC |=0x06; |
5 | SevenSegment(zahl[3], 0); |
6 | PORTC = (1<<PC0); |
7 | _delay_ms(3); |
8 | |
9 | PORTC |=0x06; |
10 | SevenSegment(zahl[2], 0); |
11 | PORTC = (1<<PC1); |
12 | _delay_ms(3); |
13 | |
14 | PORTC |=0x06; |
15 | SevenSegment(zahl[1], 0); |
16 | PORTC = (1<<PC2); |
17 | _delay_ms(3); |
18 | |
19 | PORTC |=0x06; |
20 | SevenSegment(zahl[0], 0); |
21 | PORTC = (1<<PC3); |
22 | _delay_ms(3); |
23 | }
|
Wart maö
> ... %i statt %f benutze.
Hast du die Flaoting Point Version der Standard-Librarys gelinkt. Denn
sonst liefert dein sprintf anstelle der 'Zahlen' nur ein einsames '?'
(Das deine printnumber keine wie auch immer geartete Form der
Fehlerbehandlung durchführt, stinkt mir eigentlich. Was passiert, wenn
ich
1 | printnumber( "abcdefg", 0 ); |
oder
1 | printnumber( "5", 0 ); |
aufrufe? ZUmindest eine rudimentäre Form der Fehlebehandlung indem die einzelnen Character im Bereich '0' bis '9' sein sollten, sollte es schon sein. Und wenn der String kürzer ist, dann sollte auch nicht einfach irgendwas ausgegeben werden, sondern die entsprechenden Stellen leer bleiben. Aber erst mal die Floating Point Version der Lib. FAQ - Punkt 3
Im übrigen denke ich, dass jetzt sowieso die Zeit gekommen ist, das alles mal auf ordentliche Füsse zu stellen und ein vernünftiges timergetriebenes Multiplexing aufzusetzen. Die Fragestellung 'Floating-Point' versus 'Integer' ist momentan ein Nebenschauplatz, der damit eigentlich nichts zu tun hat. Denn letzten Endes zeigt ein ordentlicher Multiplex einfach nur zeitlich gesteuert (mittels Timer), die Bitmuster an den Anzeigen an, die ihm vorgegeben werden. Wie dann diese Bitmuster zustandekommen, ist eine ganz andere Frage, die mit dem Mulitplexing erst mal überhaupt nichts zu tun hat und wo der 'Umweg' über einen String sowieso nicht vernünftig und auch nicht zielführend ist. Es ist zwar nicht uninteressant, wie das in so einem Fall gehen würde und da lässt sich sicherlich auch einiges dabei lernen. Aber im Endeffekt sieht das Ganze dann, wenn es vernünftig implementiert ist, sowieso ganz anders aus. Muss man so sagen, auch wenn das jetzt vielleicht ein wenig hart klingt.
Ich stehe ja noch ganz am Anfang. Aber dein Hinweis war Goldrichtig. Musste den Floating Point erst "aktivieren". Nun läufts so wie es soll. Und da hab ich jetzt so viele Stunden gegrübelt was an dem Code falsch sein kann... Danke!!!
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.