Myslím že ideš na to zle. Ako prvé by som začal tým že tie poznámky čo v tom kóde máš môžeš rovno vymazať. Nepriniesli mi žiadnu informáciu.
Za druhé, ako sa dá 16znakový LED riadiť 3 portami a ešte ti zostanú 3 bity. Ja potrebujem všetkých 24.
8 - segmenty A,B,C,D,E,F,G,H(bodka)
16 - spínanie báz tranzistorov.
Ale toto je detail.
A teraz to podstatné. Nie je vôbec vhodné stavať to pole čo tam ideš posielať tak aby to bol obraz tých portov. Práve naopak. Sprav si pole o 16 bytoch a tam daj buď priamo kód znaku sedem segmentovky, alebo len index do generátora znakov.
Na vyslatie údajov na porty si urob funkciu ktorá tie bity pre-ore ako treba a pošle na porty.
Kód: Vybrať všetko
#define SEG_A 0x01
#define SEG_B 0x02
#define SEG_C 0x80
#define SEG_D 0x20
#define SEG_E 0x10
#define SEG_F 0x04
#define SEG_G 0x08
#define SEG_H 0x40
/**
* A
* -----
* | |
* F | | B
* | G |
* -----
* | |
* E | | C
* | |
* -----
* D o H
*
*
*/
#define ZNAK_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)
#define ZNAK_1 (SEG_B | SEG_C)
#define ZNAK_2 (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G)
#define ZNAK_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)
#define ZNAK_4 (SEG_B | SEG_C | SEG_F | SEG_G)
#define ZNAK_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)
#define ZNAK_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define ZNAK_7 (SEG_A | SEG_B | SEG_C)
#define ZNAK_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define ZNAK_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)
#define ZNAK_A (SEG_A | SEG_B | SEG_C | SEG_G | SEG_E | SEG_F)
#define ZNAK_B (SEG_F | SEG_G| SEG_E| SEG_C| SEG_D)
#define ZNAK_C (SEG_A | SEG_F | SEG_E | SEG_D)
#define ZNAK_D (SEG_G | SEG_E | SEG_C | SEG_D | SEG_B)
#define ZNAK_E (SEG_A | SEG_F | SEG_G | SEG_E| SEG_D)
#define ZNAK_F (SEG_A | SEG_F | SEG_G | SEG_E)
#define ZNAK_TMA (0)
//vytvor pole ktore obsahuje obrazovu reprezentáciu jednotlivych cislic
unsigned char generatorCislic[]={ZNAK_0,ZNAK_1,ZNAK_2,ZNAK_3,ZNAK_4,ZNAK_5,ZNAK_6,ZNAK_7,ZNAK_8,ZNAK_9,ZNAK_A,ZNAK_B,ZNAK_C,ZNAK_D,ZNAK_E,ZNAK_F};
/**
* Funkcia ktora pre cislo v rozsahu 0 az 15 vrati obrazovu reprezentaciu cislice na sedemsegmentovke
* vstup cislo - cislo od 0 po 15
* vystup 8bitova hodnota ktora zobrazi cislicu na sedemsegmentovke
* ak vstupna hodnota bude viac ako 15 tak sa zobrazi prazdny znak
*/
unsigned char dajCislicu(unsigned char cislo){
if (cislo<=15){ //ak je cislo od 0 do 15
return generatorCislic[cislo]; //vytiahni z pola obrazovu podobu cislice
}
return ZNAK_TMA; //inak zobraz prazdny znak (zhasnute všetky segmenty)
}
unsigned char displej[16];
char pozicia = 0;
unsigned int bazy = 0xFFFE;
void zobrazZnak(){
//napr tie segmenty budú 7 - 3 PORTD a 7 - 5 PORTB
unsigned char znak=displej[pozicia];
PORTD=(znak & 0xF8) | 0x07; //necham hornych 5 bitov a dole doplnim 111
PORTB=(bazy & 0x1F) | (znak & 0x07) << 5); // bázam odrežem horné 3bity a pridám tam dolné tri zo znaku
// pričom zo znaku najprv odrežem horných 5 bitov a potom to 5x posuniem doľava
PORTC=(bazy >> 8) & 0xFF; //tuto len vezmem horný byte a naposuniem ho do dolného;
}
main(){
//vypisovanie znakov do pola
displej[0]=ZNAK_0; //na tvrdo
displej[1]=ZNAK_1;
displej[2]=dajCislicu(2); //podľa indexu v tabuľke znakov
zobrazZnak();
}
Výhodu to má takú že kedykopľvek čokolvek na dps zmeníš tak len upravíš pár konštant a ten šrotovací výpočet a všetok ostatný kód zostáva rovnaký. Vystačís si len s operáciami logický sučin, súčet a rotácie.
Samozrejme ešte tam chýba kód čo po nejakej chvíli zmení premennú bázy a pozicia a potom znova zavolá zobrazZnak() aby sa zobrazil nový znak na novej pozícii.
Polovica toho kódu bola písaná priamo do príspevku, takže neručím za prípadné preklepy. Išlo mi len o to nahodiť princíp ako jednoducho a univerzálne napísať obsluhu multiplexneho LED displeja.
Samozrejme miesto hexa konštant môžeš použiť binárne ak je to pre teba prehladnejšie. Ja som stará škola čo odrástla na hexa sústave.
A je tam ešte miesto pre optimalizáciu, nakoľko ten generátor znakov obsahuje iba konštanty takže sa dá presunúť do programovej pamäte a ušetiť si tak zopár byte SRAM.
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.