Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

obsługa 7 wysw 7 segmentowych szeregowo: jak oprogramować? C

Vein 12 Mar 2006 16:37 2028 16
  • #1 12 Mar 2006 16:37
    Vein
    Poziom 22  

    Witam !!! oto co napisałem w pewnym wątku:

    Vein napisał:

    chcialbym zastosować atmege8 albo atmege16 do wysterowania 2 wyświetlaczy LED, tzn jeden wyświetlacz składał by się z 3 segmentów (kazdy segment z 7 diód), a drugi z 4 segmentów, wiem że można to zrobić tylko przez multipleksowanie, ale nie mam żadnego pomysłu na hardware :/ aha, potrzebowałbym jeszcze 2 wejścia do zliczania impulsów i 1 przycisk. By nie marnować portów (w koncu do wysterowania 7 wyswietlaczy wasza metoda trzeba wykorzystać aż 15 portów Neutral ) można by było wykorzystać jakiś układzik, który sterowało by się tylko 3 bitami, na 3 bitach można by było wysterować już 27 wyświetlaczy (teoretycznie), ale niestety ja nie znam takiego układu Sad , może Wy coś mi podpowiecie ? może jest jakis scalaczek ktory by mogl wzmocnic sygnal by nie obciazac wyjść procesora zbytnim natężeniem prądu ?

    moze sie niejasno wyrazilem 3 bity + 7 bitow, 3 bity do przełączania wyswietlaczy a 7 do sterowania diodami w poszczegolnych segmentach :]


    Dostałem odpowiedź:

    jacobsek napisał:

    możesz np. wykorzystać 74ls164, na jego wejście podajesz dane w sposób szeregowy a na wyjściu masz dane w postaci równoległej gotowe do sterowania wyświetlaczem led 7 segment razem z kropką.
    Do sterowania potrzebny jest jeden port jako wyjście data i jeden do sterowania pinem zegarowym 74ls164 czyli używasz tylko 2 porty uc.

    Do wysłania najlepiej użyć instrukcji shiftout.
    Anodę każdego wyświetlacza łączysz przez tranzystorek więc dochodzi jeszcze 7 portów,jeśli chcesz ograniczyć do minimum liczbę portów to możesz sterować anody też poprzez taki rejestr szeregowo równoległy i dojdzie tylko 2 porty czyli "zmarnujesz" razem 4 porty do sterowania 7 wyświetlaczami.
    Wszystko to najlepiej zrobić na przerwaniu od tajmera aby wyświetlanie było robione "w tle" programu głównego i niezależnie od niego.



    No a teraz właściwy problem :] nie mam pojęcia jak oprogramować transmisję szeregową, ten problem wlecze się za mną od dobrych 2 lat i jakos sam nie znalazlem na to odpowiedzi (chyba za słabo szukałem ;) ), gdyby był ktoś łaskawy i podpowiedział mi chociaż kawałek kodu napisany w C, to byłbym dźwięczny

    0 16
  • #2 12 Mar 2006 16:42
    elektryk
    Poziom 42  

    Zastanów się jak działa ten rejestr i jaki wygenerować sygnał żeby mieć na jego wyjściach to co się chce.

    0
  • #3 12 Mar 2006 17:35
    Vein
    Poziom 22  

    elektryk akurat tym mi nie pomogles, nieweim jak dziala rejestr, znam podstawy języka c i podstawy mikrokontrolerów, ale to drugie no NAPRAWDE są podstawy.

    0
  • #4 12 Mar 2006 17:45
    jacur
    Poziom 32  

    mniej wiecej hula to tak :

    do
    {
    PORTD.4=0; // ustaw stan niski na wyjsciu zegarowym rejestru przesównego 4094
    //PORTD.2=wyjscie&0x01;
    //wyjscie=wyjscie>>1;
    PORTD.3=wyjscie&0x80; // ustaw watrosc najstarszego bitu w zmiennej na linie data rejestru przesównego
    wyjscie=wyjscie<<1; // przesón bity w zniennej o 1 w lewo
    PORTD.4=1; // ustaw stan wysoki na wyjsciu zegarowym rejestry przesównego
    }
    while (++j<8); // powtóz wszystko 8 razy

    0
  • #5 12 Mar 2006 17:46
    jacobsek
    Poziom 22  

    Witam.
    Transmisja szeregowo_równoległa polega w tym przypadku na tym :
    Do wejścia scalaka 74ls164 podajesz po kolei wysuwane bity z któregoś portu procka a na 8 wyprowadzeniach tegoż scalaka pojawia się po skończeniu tej transmisji to samo czyli te same bity tylko w postaci równiległej czyli jeśli np.podasz na jego wejście jakąś cyfrę to na wyjściach sterujących wyświetlaczem led otrzymasz jej kod w postaci zapisu dwójkowego czyli nap.jego wyjścia przyjmą stan:00101110 a teraz od tego jak podepniesz te wyjścia do segmentów zależy jaki kod trzeba podać.
    Najlepiej po określeniu jak są podłączone w konkretnym przypadku przeliczyć sobie to na kalkulatorku binarnym i dostosować do własnych połączen.

    0
  • #6 12 Mar 2006 18:11
    elektryk
    Poziom 42  

    Vein napisał:
    elektryk akurat tym mi nie pomogles, nieweim jak dziala rejestr, znam podstawy języka c i podstawy mikrokontrolerów, ale to drugie no NAPRAWDE są podstawy.
    To znaczy że jesteś śmierdzącym leniem
    i nawet nie próbujesz zrozumieć to co budujesz, tylko czekasz aż ktoś inny to za Ciebie zrobi.

    0
  • #7 12 Mar 2006 18:55
    Vein
    Poziom 22  

    tak elektryk jestem smierdzacym leniem ktory proboje cos zbudowac nie zaglebiajac sie od a do z w budowe elementow z ktorych sie to bedize skladac, jak zauwazylem niezabardzo pomagasz innym "Bezposrednio" np rada "cos nie tak z tranzystorami" (inny wątek) naprawde dla poczatkujacego nie mowi zbyt wiele

    Jacobsek - to akurat zrozumialem :] nawet obejzalem sobie datasheeta ;) .. nie chodizlo mi wlasciwie o kod, tlyko jak nadać bity zgodnie z timerem i jak wyprowadzic timer na ktorys port mikrokontrolera :], chyba ze zrobic tak jak zasugerował kolega powyzej... chociaz jak w tym samym momencie nadac sygnal na 2(3) porty ? 2 sygnału + 1 timer ?

    chyba że ktoś spotkał się już z jakims projektem opartym na 74LS164 i prosecorze z serii "atmega"

    0
  • Pomocny post
    #8 12 Mar 2006 22:25
    adamusx
    Poziom 27  

    Witam.

    Wiec postaram sie to wytlumaczyc : układ 74164 to jak juz wiesz rejestr przesuwny posiadajacy 2 wejscia : CLK (zegra) i DATA (dane) lub podobnie. Posiada on takze 8 wyjsc ktore moga być w stanie wysokim lub niskim. Za pomoca lini CLK wyslasz sygnal zegarowy , a na wejscia DATA podajesz poszczegolne bity tego co chcesz wyslac na wyjscia rejestru. Powiedzmy, ze ma to byc liczba 197 czyli binarnie to bedzie 11000101. Wiec nalezy doprowadzic do tego by na wyjsciach układu 74164 pojawily sie wlasnie takie stany.Ustawiasz CLK w stan niski. Potemna wejsciu DATA ustawiasz od konca : najpierw 1 , potem by przeslac ta dana do rejestru zmieniasz sygnal CLK z 0 na 1 i potem spowrotem na 0 . Pierwsze wyprowadzenie rejestru 74164 zmienia stan z 0 na 1. Przechodzic do kolejnego bitu w liczbie 197 czyli 0 ( caly czas patrzac od konca. Czyli ustawiasz 0 na wejscu DATA i znow zmieniasz stan CLK z 0 na 1 .Tym razem stan aktywny z pierwszego wyprowadzenia rejestru przenosi sie z wyjscia pierwszego na 2 , a na we pierwszym bedzie 0 ( bo drugi bit( od konca) liczby 197 to zero ) Operacje ta momentu wyslania wszystkich 8 bitow. Po ty na wyjsciach rejestru 74164 bedziemy mieli stany : 11000101 !!!!! Co odpowiada wyslanej liczbie 197.

    To fragment przykladowego kodu w C:

    /*************************************************************
    wysłanie informacji na 74164
    ***********************************************************/
    void Wyslij(unsigned char co)
    {
    unsigned char mask1=8;
    unsigned char co_dana=0;
    co_dana=co;
    do {
    if ( co_dana & 0x80 ) PORTD|=_BV(PD2); // DANA =1
    else PORTD&=~_BV(PD2); // DANA =0
    PORTD|=_BV(PD3); // // CLK=1;
    co_dana=co_dana << 1;
    PORTD&=~_BV(PD3); // CLK=0;
    mask1--;
    } while (mask1);
    PORTD&=~_BV(PD2);

    }

    /*************************************************************

    0
  • #9 12 Mar 2006 23:51
    Vein
    Poziom 22  

    Z tego co zauwazylem, to programowanie w "C" mikrokontrolerow jednak sie rozni od programowania "c++" pc... sa wyrazenia ktorych nie rozumiem, ale poszukam w necie tutorialkow n.t progrmaowani ukladow w c i sie poducze.

    Adamusx- pomogles mi BARDZO, dziekuje :]

    Dziękuje i pozdrawiam :]]

    ps. jezeli ktos posiada sensownego tutka o programowaniu w C dla mikrokontrolerow to bede dziweczny :]

    ps2. uczylem sie pascala, teraz zaczelem c++, narazie przerobilem podstawy skladni i petle, moze dlatego nei rozumiem niektorych wyrazen (np dlaczego ejst tlyko jedno "&" w ifie)

    ps3. a teraz jak ja rozumiem niektore fragmenty kodu:

    PORTD|=_BV(PD2) - tutaj rozumeim ze na porcie "D2" jest ust. stan wysoki
    PORTD&=~_BV(PD2) - tutaj stan niski

    nie rozumiem tylko znaczenia poszczegolnych czesci, tzn jakie jest powiazanie PORTD& i "~" przed _BV oraz PORTD| i brak "~" przed _BV

    co_dana - zmienna gdzie znajduje sie zapis danych wysylanych ( 8 bitow)
    mask1 - zmienna "pomocnicza" by 8 razy petla sobie przeleciala (8 bitow wyslanych)

    0
  • Pomocny post
    #10 13 Mar 2006 12:14
    adamusx
    Poziom 27  

    Ja tez nie kumalem tego kiedys .. poszukaj ,poczytaj i zrozumiesz:)

    ps1- http://galaxy.uci.agh.edu.pl/~chwastek/lectures/C/spis.html
    na tej stronce masz kurs samego C , tam sa wytlumaczone operatory itp rzeczy.

    ps2 . co_dana & 0x80 - jedno & oznacza iloczyn (AND) bitowy tzn:

    mamy np to zmienna co_dana ktora ma powiedzmy wartość 185 - binarnie :
    10111001 , druga liczba to 0x80 zapisana w hexa czyli binarnie 10000000 wiec mamy :

    10111001 & 10000000 - wykonujemy AND po kolei dla bitow od 0-7 = 10000000 .

    PS3:
    Ustawienie
    Dla „zapalenia” jednego wybranego bitu w zmiennej sumujemy ją bitowo z maską o zgodnym rozmiarze, w której tylko ten bit jest ustawiony,

    np. dla bitu nr 3:
    stan portu: 1100 0010
    maska z wlaczonym bitem 3 : 0000 1000
    1100 0010 or 0000 1000 = 1100 1010 - wlaczylismy bit 3 na porcie bez zmiany pozostalych.

    w zapisie w C wyglada to tak :

    PORTB|=(1<<3) a to jest równoznaczne PORTB=PORTB|(1<<3)

    _BV(3) to makro wprowadzone w bibliotece w GCC ktore oznacza to samo co (1<<3)

    a (1<<3) oznacza , że 1 przesuwasz o 3 bity w lewo czyli otrzymujesz : 00001000 , np (1<<7) = 10000000

    | - oznacza sumowanie bitowe (OR)

    Zgaszenie bitu
    Dla zgaszenia tego samego bitu używamy iloczynu zmiennej z maską zanegowaną
    (z wartością wszystkich bitów zmienioną na przeciwną: ~0000 1000 = 1111 0111):
    1100 1010 & ~0000 1000 = 1100 1010 & 1111 0111 = 1100 0010

    PORTB &= ~_BV(5); // ustaw wyjście 5 portu B w stan niski -
    // sbi(PORTB, 5);
    // PORTB= PORTB & ~_BV(5); // Zapis równorzędny z powyższym

    Bez używania _BV : ( PORTB &= ~(1<<5); )

    ~ - zmienia wszystkie bity na preciwne

    0
  • #11 16 Mar 2006 19:39
    Vein
    Poziom 22  

    Witam !!!

    Jak narazie wydumałem taki schemat ideowy (jeżeli gdzies sa potrzebne rezystory to prosze mi mowić)
    ukł1 i ukł2 to są zintegrowane tranzystory po 8 sztuk, niestety nie pamiętam oznaczeń (a może ktoś je zna ? byłbym wdzięczny gdyby ktos podpowiedzial bo inaczej czeka mnie masa przegladania forum)

    0
  • #12 16 Mar 2006 21:02
    Hornet60
    Poziom 18  

    Tw układy o które ci chodzi to pewnie uln2803... Przyjrzałem się schematowi i wszystko jest dobrze. Apropos 74164 to spotkałem się raz z płytką gdzie były 4 takie układziki które sterowały 2 podwójnymi wyświetlaczami (układ z jakiegoś TV) i podłączone tam były bezpośrednio do wyświetlaczy... też miały one oznaczenie ls jednak po przejrzeniu karty katalogowej zdziwiłem się troszeczkę bo wydajność prądowa tych układzików to coś ok 5mA... ale jeżeli chcesz zaoszczędzić miejsca na płytce to z pewnością dobrze będą działały układy HC, HCT które mają 20mA wydajności na każdym wyjściu więc w sam raz

    0
  • #13 16 Mar 2006 21:02
    jacur
    Poziom 32  

    zamiast układu nr2 8 rezystorów 100ohm
    zamiast układu1 8 tranzystorów PNP i rezystor 4K7 na baze

    0
  • #14 16 Mar 2006 21:53
    Vein
    Poziom 22  

    dzięki wam :]

    jacur - wolałbym by zamiast tych 8 tranzysotrów, zastosować układ scalony, ze wzgledu na oszczednosc miejsca, bo jak sprawdzilem, cena jednak nie jest taka duża :P, poskłądamy, zobaczymy.
    w układzie uln2803 są stosowane tranzystory npn hmm

    tutaj dałem zmodyfikowany schemat

    poprawilem schemat (tranzystory)

    0
  • #15 17 Mar 2006 16:42
    jacur
    Poziom 32  

    Tranzystory odwrotnie emiter do plusa zasilania kolektor do wyswietlacza. Mozesz jeszcze 164 ustawic w kaskade, czyli z wyjscia D7 jednej 164 na wejscie data1 i data2 drugiej 164 oszczedzasz wtedy jedno wyjscie z procka tylko trzeba wysłąc 2 bajty danych po koleji

    0
  • #16 17 Mar 2006 18:26
    jacobsek
    Poziom 22  

    Przy tej ilości wyświetlaczy i 74ls164 może pojawić się problem "podświetlania segmentów",co objawić się może nieprzyjemnym efektem dla oka gdyż przypadkowe segmenty mogą być nieco rozświetlone.

    0
  • #17 17 Mar 2006 22:46
    Vein
    Poziom 22  

    jacur - az tak bardzo nie oszczedzam na portach, to praktycznie bedzie ten wyświetlacz(tylko zamiast jednego segmentu podwojnego bedzie jeden pojedynczy i 7 LEDów w linijce)+2 porty wejscia impulsow+3 przyciski, jak narazie wiecej nie planuje, zapomnialbym jeszcze o zewnetrznej pamieci podtrzymywanej z jakiejs bateriii, musza byc gdzies zapisywane ustawienia, ale to chyba na przyszlosc bedzie

    Własnie znalazłem oprogramowanie przeznacozne od celu podobnego jaki ma mw zamyśle (soft jest dla 90s2313 ale jest tam wiele rozwiazan ktore warto ziamplementować) narazie musze rozgryzc adresowanie wszystkich portów w atmedze, niestety nic sensownego nie znalazłem (opisu od a do z), wiec prawodpodobnie zorbie taki "dla potomności"

    0