Rolf Degen schrieb:
> Ich denke da an ein
> Array oder so was ähnliches. Aber leider habe ich diesbezüglich keine
> Erfahrung und hoffe auf Euch und ein paar Tips für die Programmierung.
Arrays sind ja keine Hexerei.
Im Grunde geht es doch nur darum, dass du irgendwo her kriegen musst, ob
für ein bestimmte darzustellende Ziffer, das entsprechende Segment auf 0
oder auf 1 gesetzt werden muss.
Das kannst du dir zb Bitcodiert in einem uint8_t ablegen. Ein Array von
derartigen Werten beschreibt dann die notwendigen Kombinationen für alle
Ziffern.
Eine spezielle Funktion holt sich aus dem Array den entsprechenden Wert,
dröselt die Bits wieder auf und setzt die entsprechenden Registerwerte
dementsprechend.
Das ist der Plan. Fangen wir an.
Als erstes überlegen wir uns eine Zuordnung von Bits in einem uint8_t zu
den entsprechenden Segmenten. Die erfinden wir einfach. zb so
1 | 6
|
2 | *******
|
3 | * *
|
4 | 5 * * 0
|
5 | * 4 *
|
6 | *******
|
7 | * *
|
8 | 3 * * 1
|
9 | * *
|
10 | *******
|
11 | 2
|
D.h. für eine darzustellende '1' müssen die Bits 0 und 1 auf 1 gesetzt
werden, für eine '2' sind es die Bits 6, 0, 4, 3, 2 etc.
1 | uint8_t digitCodes[10] =
|
2 | { 0b01101111, // '0'
|
3 | 0b00000011, // '1'
|
4 | 0b01011100, // '2'
|
5 | 0b00000000, // '3'
|
6 | 0b00000000, // '4'
|
7 | 0b00000000, // '5'
|
8 | 0b00000000, // '6'
|
9 | 0b00000000, // '7'
|
10 | 0b11111111, // '8'
|
11 | 0b00000000, // '9'
|
12 | };
|
(die noch fehlenden musst du ergänzen)
Soweit so gut. Jetzt wissen wir, welche Elemente eingeschaltet und
welche ausgeschaltet werden müssen. Alles was noch fehlt, ist eine
Funktion, die sich für eine Ziffer das entsprechende Codebyte holt, die
einzelnen Bits rausholt und je nach Wert des Bits, das entsprechende
Digit ein oder aus schaltet
1 | void digit0( uint8_t value )
|
2 | {
|
3 | uint8_t digitCode;
|
4 |
|
5 | if( value > 9 ) // nur zur Sicherheit. Der Fall darf nie
|
6 | value = 0 // auftreten
|
7 |
|
8 | //
|
9 | // hole das Bitmuster der Segmente für diese Ziffer
|
10 | //
|
11 | digitCode = digitCodes[ value ];
|
12 |
|
13 | //
|
14 | // die einzelnen Bits betrachten
|
15 | // sind nur 8, daher erst mal wenig Aufwand
|
16 | //
|
17 | // um den Schreibaufwand gering zu halten, ein 'cleveres' Makro machen
|
18 | //
|
19 |
|
20 | #define TEST_DIGIT(digit_bit, port, port_bit ) \
|
21 | if( digitCode & digit_bit ) \
|
22 | port |= (1 << port_bit); \
|
23 | else \
|
24 | port &= ~(1 << port_bit);
|
25 |
|
26 | TEST_DIGIT( 0x01, LCDDR1, bit_0 ); // Bit 0
|
27 | TEST_DIGIT( 0x02, LCDDR1, bit_1 ); // Bit 1
|
28 | TEST_DIGIT( 0x04, LCDDR6, bit_0 ); // Bit 2
|
29 | TEST_DIGIT( 0x08, LCDDR6, bit_1 ); // Bit 3
|
30 | TEST_DIGIT( 0x10, LCDDR11, bit_0 ); // Bit 4
|
31 | TEST_DIGIT( 0x20, LCDDR11, bit_1 ); // Bit 5
|
32 | TEST_DIGIT( 0x40, LCDDR16, bit_0 ); // Bit 6
|
33 | TEST_DIGIT( 0x80, LCDDR16, bit_1 ); // Bit 7
|
34 |
|
35 | #undef TEST_DIGIT
|
36 | }
|
Und das wars dann auch schon. Ob die Zuordung und Umsetzung der
einzelnen 'Bits' laut obiger Zeichnung zu den µC Registern und Bits
stimmt, musst du kontrollieren.
Aber jetzt kannst du die Funktion mit einer Zahl von 0 bis 9 aufrufen,
und auf dem LCD müssten die richtigen Segmente dafür eingeschaltet
werden.
1 | void main()
|
2 | {
|
3 | ....
|
4 |
|
5 | while( 1 ) {
|
6 | for( i = 0; i < 9; ++i ) {
|
7 | digit0( i );
|
8 | _delay_ms( 500 );
|
9 | }
|
10 | }
|
11 | }
|