PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 7 segment anzeige Platine



shedepe
15.11.2009, 13:36
Hallo

Ich habe mir für meinen geplanten Roboter mal eine Art Anzeigeboard zusammengelötet. Zuerst mal nur 2-7Segementanzeigen, desweiteren wird noch ein Anschluss für ein Display dazu kommen.
Das ganze funktioniert auch schon so weit ganz gut. Das heißt, ich kann
Kommazahlen von 0.0 bis 9.9 schreiben und ganze zahlen von 0 bis 99.

Das ganze lässt sich auch über die serielle Schnittstelle steuern und genau hier liegt mein Problem.
Wenn ich folgenden Code verwende, muss ich die gewünschte Zahl bis zu 4 mal senden damit sie korrekt angezeigt wird.


char buffer[3];
while(1)
{


uart_gets(buffer, 4);
Write(buffer);
uart_puts(buffer);
}


Write ist die Anzeige routine für die 7segmentanzeigen
Der UART funktioniert soweit auch, bis auf das ich die gewünschte Zahl 4 mal senden muss.

Hat jemand eine Idee woran das liegen könnte ?

Jaecko
15.11.2009, 13:44
Der Code hilft eigentlich garnicht, da z.B. nirgendwo der Inhalt von Write() zu finden ist.
Mit dem Code könnte man dann auch rausfinden, warum in "char buffer[3];" 4 Zeichen reingeschrieben werden (uart_gets(buffer, 4);) .
Oder ob der 2. Parameter immer 1 grösser sein muss.

Und ohne Schaltplan isses auch nur Raterei, da man auf dem Bild nicht erkennt, welche Teile wie verbunden sind. Aber da ja was angezeigt wird, geh ich mal davon aus, dass die Hardware stimmt.

shedepe
15.11.2009, 13:53
ich denke das der Write() teil auch nicht weiter helfen wird, da man dem Write() quasi nur einen String übergibt der dann verarbeitet wird.
Wenn man z.B direkt Write("5.5") schreibt wird dieses auch angezeigt.

Hier ist mal der Teil wie der UART initialisiert wird und wie ausgelesen wird




//Empfangsteil

uint8_t uart_getc(void)
{
while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar
;
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
}

void uart_gets( char* Buffer, uint8_t MaxLen )
{
uint8_t NextChar;
uint8_t StringLen = 0;

NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen

// Sammle solange Zeichen, bis:
// * entweder das String Ende Zeichen kam
// * oder das aufnehmende Array voll ist
while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
*Buffer++ = NextChar;
StringLen++;
NextChar = uart_getc();
}

// Noch ein '\0' anhängen um einen Standard
// C-String daraus zu machen
*Buffer = '\0';
}


//Initialisierungsteil

UCSRB = (1<<TXEN) | (1<<RXEN) | (1<<RXCIE);
UCSRC = (1<<UCSZ1) | (1<<UCSZ0);
UBRRH = ((F_CPU +BAUD*8 )/ (BAUD * 16L) - 1) >>8;
UBRRL = ((F_CPU +BAUD*8 )/ (BAUD * 16L) - 1) & 0xFF;



Der Empfangsteil ist direkt so aus dem UART Tutorial von Mikrocontroller.net übernommen

Jaecko
15.11.2009, 13:55
Tja, trotzdem wäre es interessant, WIE das angezeigt wird. Also wie wird das ganze durchgearbeitet. Mich würde nämlich interessieren, wie das Problem gelöst wird, dass in einen 3-Byte-Array 4 Bytes reingeschrieben werden...

shedepe
15.11.2009, 14:04
ich hatte es davor mit nur 3 Bytes versucht um dann festzustellen dass der Dezimalpunkt weg war.

meine Anzeige Routine ist hier: (vielleicht nicht die beste aber sie funktioniert)



#define DATENRICHTUNG DDRD
#define ANZEIGEPORT PORTD


#define SER PD2
#define SCK PD3
#define SCL PD4
#define RCK PD5



void InitAnzeige(void)
{

DATENRICHTUNG |= ((1<<SER) | (1<<SCK) | (1<<SCL) | (1<<RCK) );

ANZEIGEPORT |= (1<<SCL);

}
void Impuls(void)
{
ANZEIGEPORT &= ~(1<<SCK);
//_delay_us(10);
ANZEIGEPORT |= (1<<SCK);
// _delay_us(10);
ANZEIGEPORT &= ~(1<<SCK);
}
void Clear(void)
{
ANZEIGEPORT &= ~(SCL<<1);
ANZEIGEPORT |= (SCL<<1);
}
void Ausgeben(void)
{
ANZEIGEPORT &= ~(1<<RCK);

ANZEIGEPORT |= (1<<RCK);

ANZEIGEPORT &= ~(1<<RCK);

}


void Write(char *number)
{
Clear();

static uint8_t zahl1 = 0;
static uint8_t zahl2 = 0;
uint8_t i = 0;
char dotpoint =' ';

while (*number)
{
if(i == 0)
{
zahl1 = (uint8_t) *number;
}
if(i == 1)
{

dotpoint = *number;
}
if(i == 2)
{

zahl2 = (uint8_t) *number;
}

number++;
i++;
}



struct
{
unsigned A1:1;
unsigned B1:1;
unsigned C1:1;
unsigned D1:1;
unsigned E1:1;
unsigned F1:1;
unsigned G1:1;
unsigned DP1:1;

unsigned A2:1;
unsigned B2:1;
unsigned C2:1;
unsigned D2:1;
unsigned E2:1;
unsigned F2:1;
unsigned G2:1;
unsigned DP2:1;
}Segmente;

if(dotpoint == '.')
{
Segmente.DP1 = 1;

}

switch(zahl1)
{
case '0':
Segmente.A1 = 1;
Segmente.B1 = 1;
Segmente.C1 = 1;
Segmente.E1 = 1;
Segmente.D1 = 1;
Segmente.F1 = 1;

break;
case '1':
Segmente.B1 = 1;
Segmente.C1 = 1;

break;

case '2':
Segmente.A1 = 1;
Segmente.B1 = 1;
Segmente.G1 = 1;
Segmente.E1 = 1;
Segmente.D1 = 1;
break;

case '3':
Segmente.A1 = 1;
Segmente.B1 = 1;
Segmente.G1 = 1;
Segmente.C1 = 1;
Segmente.D1 = 1;
break;

case '4':

Segmente.B1 = 1;
Segmente.G1 = 1;

Segmente.C1 = 1;
Segmente.F1 = 1;
break;

case '5':

Segmente.A1 = 1;
Segmente.F1 = 1;
Segmente.G1 = 1;
Segmente.C1 = 1;
Segmente.D1 = 1;
break;
case '6':
Segmente.A1 = 1;
Segmente.F1 = 1;
Segmente.E1 = 1;
Segmente.G1 = 1;
Segmente.C1 = 1;
Segmente.D1 = 1;
break;
case '7':
Segmente.A1 = 1;
Segmente.B1 = 1;
Segmente.C1 = 1;
break;
case '8':
Segmente.A1 = 1;
Segmente.F1 = 1;
Segmente.E1 = 1;
Segmente.G1 = 1;
Segmente.C1 = 1;
Segmente.D1 = 1;
Segmente.B1 = 1;

break;
case '9':
Segmente.A1 = 1;
Segmente.F1 = 1;
Segmente.B1 = 1;
Segmente.G1 = 1;
Segmente.C1 = 1;
Segmente.D1 = 1;
break;

}
switch(zahl2)
{

case '0':
Segmente.A2 = 1;
Segmente.B2 = 1;
Segmente.C2 = 1;
Segmente.E2 = 1;
Segmente.D2 = 1;
Segmente.F2 = 1;

break;
case '1':
Segmente.B2 = 1;
Segmente.C2 = 1;

break;

case '2':
Segmente.A2 = 1;
Segmente.B2 = 1;
Segmente.G2 = 1;
Segmente.E2 = 1;
Segmente.D2 = 1;
break;

case '3':
Segmente.A2 = 1;
Segmente.B2 = 1;
Segmente.G2 = 1;
Segmente.C2 = 1;
Segmente.D2 = 1;
break;

case '4':

Segmente.B2 = 1;
Segmente.G2 = 1;

Segmente.C2 = 1;
Segmente.F2 = 1;
break;

case '5':
Segmente.A2 = 1;
Segmente.F2 = 1;
Segmente.G2 = 1;
Segmente.C2 = 1;
Segmente.D2 = 1;
break;
case '6':
Segmente.A2 = 1;
Segmente.F2 = 1;
Segmente.E2 = 1;
Segmente.G2 = 1;
Segmente.C2 = 1;
Segmente.D2 = 1;
break;
case '7':
Segmente.A2 = 1;
Segmente.B2 = 1;
Segmente.C2 = 1;
break;
case '8':
Segmente.A2 = 1;
Segmente.F2 = 1;
Segmente.E2 = 1;
Segmente.G2 = 1;
Segmente.C2 = 1;
Segmente.D2 = 1;
Segmente.B2 = 1;

break;
case '9':
Segmente.A2 = 1;
Segmente.F2 = 1;
Segmente.B2 = 1;
Segmente.G2 = 1;
Segmente.C2 = 1;
Segmente.D2 = 1;
break;
}
//Nummer 1

//Nummer 9
if(Segmente.A2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 10
if(Segmente.B2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 11
if(Segmente.C2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 12
if(Segmente.D2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 13
if(Segmente.E2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 14
if(Segmente.F2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 15
if(Segmente.G2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 16
if(Segmente.DP2 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
if(Segmente.A1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 2
if(Segmente.B1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 3
if(Segmente.C1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 4
if(Segmente.D1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 5
if(Segmente.E1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 6
if(Segmente.F1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 7
if(Segmente.G1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();
//Nummer 8
if(Segmente.DP1 == 1)
{
ANZEIGEPORT |= (1<<SER);

}
else
{
ANZEIGEPORT &= ~(1<<SER);
}
Impuls();

Ausgeben();



}

Jaecko
15.11.2009, 14:18
Problem ist eher andersrum... es werden 4 Zeichen geholt, aber nur 3 gespeichert. Das 4. Zeichen landet irgendwo, wo es nicht hinsoll.

Den Teil hier


while (*number)
{
if(i == 0)
{
zahl1 = (uint8_t) *number;
}
if(i == 1)
{

dotpoint = *number;
}
if(i == 2)
{

zahl2 = (uint8_t) *number;
}

number++;
i++;
}


würd ich eher abkürzen:



zahl1 = number[0];
dotpoint = number[1];
zahl2 = number[2];


Beseitigt auch die Gefahr, dass die While-Schleife mal hängen bleibt.

Die gesamte Bit-Zusammenbauerei könnte man natürlich noch weiter zusammenkürzen. Ich mach das z.B. nicht über einzelne Bits, sondern verwende pro Segment ein Byte. Sind ja 7 Segmente + 1 Punkt = 8 Bits.
Die Bitfolge sieht dann pro Byte so aus [DP][G][F][E][D][C][B][A].
Und dieses Byte schieb ich dann normal raus.
Könnte dann z.B. so aussehen:
case 1: daten = 0x06; // Bits: 0000 0110
case 2: daten = 0x5B; // Bits: 0101 1011
...
Soll der Punkt der jeweiligen Ziffer gesetzt werden:
data |= 0x80.