Forum: Mikrocontroller und Digitale Elektronik Array an 7 Segmentanzeige ausgeben


von Walter_P (Gast)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

Schaltplan? Netiquette?

von Markus M. (mark_m)


Lesenswert?

Erst mal würde ich den Richtigen Datentyp an "printnumber" übergeben.

Grüsse

von Walter_P (Gast)


Lesenswert?

Kann es ja so mit einem Pointer machen, dann geht das schonmal.

void printnumber(char* zahl)

aber wie weiter?

von Brathähnchen (Gast)


Lesenswert?

Der Fehler ist bestimmt in der Funktion SevenSegment.

von Walter_P (Gast)


Lesenswert?

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;
                }

}

von Walter_P (Gast)


Lesenswert?

hab den fehler gefunden, die '' striche waren schuld

von Markus M. (mark_m)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

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.

von Walter_P (Gast)


Lesenswert?

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?

von mh (Gast)


Lesenswert?

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.

von Markus M. (mark_m)


Lesenswert?

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

von Walter_P (Gast)


Lesenswert?

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);

                }
        }
}

von Markus M. (mark_m)


Lesenswert?

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

von Walter_P (Gast)


Lesenswert?

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);

.
.
.
         }
}

von Markus M. (mark_m)


Lesenswert?

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

von Walter_P (Gast)


Lesenswert?

Dankeschön!!

von Walter P (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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?

von Walter P (Gast)


Lesenswert?

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
}

von Karl H. (kbuchegg)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Walter P (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.