AVR - wyświetlanie liczby na 3-cyfrowym LED

Nov 04, 2004 14 Replies

Potrzebuję jakiegoś ogólnego pomysłu jak wyświetlić liczbę z rejestru (czyli



0-255) na 3-cyfrowym wyświetlaczu LED. Chodzi o wyświetlacz tego typu:

formatting link
i chodzi mi głównie o sposób zamiany liczby binarnej na odpowiednie kombinacje segmentów, a nie o samo sterowanie wyświetlaczem. Może są jakieś dobrze znane sposoby albo nawet gotowe procedury w asemblerze i nie trzeba tego wymyślać od nowa? Byłby użyty taki procesor, który ma odpowiednią liczbę nóżek do sterowania segmentami, np. tiny26, bez żadnych dodatkowych układów logicznych.



Paweł


rozbij to na dwa etapy: bin2bcd a potem chocby tablicowo bcd->7seg.

Użytkownik "Paweł Paroń" snipped-for-privacy@freeland.lublin.pl> napisał:

Po jednym tranzystorze na segment do sterowania anodami plus ULN2803 żeby prądu nie brakło. Do wyświetlania cyfr robisz sobie lookup-table zamieniającą cyfrę dziesiętną na odpowiednią kombinację bitów zależną od tego jak sobie płytkę zaprojektujesz.

Darek Żołna

Nie da sie tego zrobic w prosty sposob (np. jakas sprytna grupa pieciu instrukcji). Musisz przeksztalcic liczbe na grupe trzech liczb ze zbioru {0,..,9}, a nastepnie uzyc uzyskanych wartosci do indeksowania tablicy 10 komorek, z ktorych kazda zawiera uklad bitow odpowiadajacych wyswietlanej cyfrze. Konwersji mozna dokonac albo za pomoca korekcji binarnej (BIN->BCD), albo dwukrotnie dzielac wejsciowa liczbe przez 10. Reszta z dzielenia to bedzie kolejna cyfra, liczac od najmniej znaczacej. Dzielenie nie musi zostac wykonane doslownie, np. mozesz odejmowac w petli od danej liczby najpierw 100, pozniej 10, a na koncu 1 i zliczac ile razy odejmowana liczba miesci sie w danej -- to jest sposob ogolny (dziala dla dowolnych liczb), w najgorszym przypadku wymaga ~20 cykli na cyfre. Jesli masz jakies "wolne" 50 cykli, to bedzie to najprostszy sposob. W asemblerze napisz to sobie sam, w koncu beda to tylko 2 petle (100 moze sie miescic w bajcie co najwyzej 2 razy, wiec ten przypadek nalezy zalatwic osobnym testem).

Wlasnie tak to nalezy zrobic.

Pozdrawiam Piotr Wyderski

^^^^^^^^^^ Zapomniales dac tutaj smileya ;))))

Krzysiek Rudnik

Przede wszystkim rozważ zmianę wyświetlacza na taki ze wspólną katodą - odpadną drivery.

Zobacz taki kawałek:

const unsigned int LEWA[12] = {

0x73fe,0x43f8,0x73dd,0x63fd,0x43fb,0x63f7,0x73f7,0x43fc,0x73ff,0x63ff,0x43c1 ,0x73ff }, SROD[12] = { 0x7cee,0x4ce8,0x7ccd,0x6ced,0x4ceb,0x6ce7,0x7ce7,0x4cec,0x7cef,0x6cef,0x4cc1 ,0x7cff }, PRAW[12] = { 0x7f2e,0x4f28,0x7f0d,0x6f2d,0x4f2b,0x6f27,0x7f27,0x4f2c,0x7f2f,0x6f2f,0x4f01 ,0x7f3f };

void tim_ovf0(void) { TCNT0 = TBASE; /* przeladuj timer */

if( cyfra == 0 ) cyfra = 2; else cyfra--; if( cyfra == 0 ) { PORTD = HIGH( LEWA[setki] ); /* setki */ PORTB = LOW( LEWA[setki] ); } if( cyfra == 1 ) { PORTD = HIGH( SROD[dzies] ); /* dziesiec */ PORTB = LOW( SROD[dzies] ); } if( cyfra == 2 ) { PORTD = HIGH( PRAW[jedno] ); /* jednosci */ PORTB = LOW( PRAW[jedno] ); }

if( pauza == 0 ) { pauza = LPOM; time = czas / 100; if( (time < TMIN) || (time > TMAX) ) { jedno = KRESKA; dzies = KRESKA; setki = KRESKA; } else { jedno = time % 10; time /= 10; dzies = time % 10; time /= 10; setki = time % 10; } } else pauza--; }

Wiem, wiem - zero finezji... Podłączenie wyświetlaczy jest na stronie:

formatting link

^^^^^^^^^^

a dlaczego? :P A dokladnie: dlaczego nie? Kazdy sposob dobry, nie wszystkie procki maja uklad dzielenia...

Użytkownik "Marek Lewandowski" snipped-for-privacy@onet.pl napisał:

Hmm... a po co zliczać jednostki? Żeby w innej zmiennej zapisać? :-)

Darek Żołna

Tak, brakuje smileya. Przemysl _ostatni_ przypadek. :-))) No to trzeba ~25 cykli, czyli konwersje robi sie juz blyskawicznie.

Pozdrawiam Piotr Wyderski

Użytkownik "Paweł Paroń" snipped-for-privacy@freeland.lublin.pl> napisał w wiadomości news: snipped-for-privacy@154-moo-7.acn.waw.pl...

A moze prosciej wyswietlac liczbe jako hex ? wystarcza wtedy 2 cyfry i nie trzeba zadnego dzielenia, bo każda połówka bajta to jedna cyfra hex .

pozdr. jfk

Rotfl, ślepy chyba jestem :PPPP Masz rację i Darek też... Trza mi było spać iść :))))))))))))))

Dlaczego? Nie pamiętam jaka jest obciążalność wyjść AVR-a, ale chyba za mała, żeby pociągnąć wszystkie segmenty, niezależnie czy to będzie katoda czy anoda?

Dzięki za ten programik.

Paweł

Wystarczajaca, o czym mowi:

a) dokumentacja, ktorej widac nie przeczytales; b) empiryczne potwierdzenie powyzszego zapisu w kilku moich ukladach z wyswietlaczem LED.

Pozdrawiam Piotr Wyderski

W stanie wysokim prądu wystarczy spokojnie na segment. W stanie niskim wyjście przyjmie całkiem spory prąd, a zawsze można połączyć kilka wyjść równolegle... TG

Nowsze układy AVR mają już wyjścia symetryczne - w obie strony 20mA przy 5V zasilania powoduje zmianę o maksymalnie 0,7V. Każą nie przekraczać 40 mA / pin.

Raf.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required