logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Wyświetlanie zmiennej na 4-cyfrowym wyświetlaczu LED w Bascom AVR

thorin00 10 Mar 2006 13:29 2588 20
REKLAMA
  • #1 2397721
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    witam
    zaczyna programowac w bascomie i chcialbym wyswietlic wartosc zmiennnej (np wysw) na 4 cyfrowym 7 segmentowym wyswietlaczu led (czyli watosc od 0-9999) i np jakiegos znaku (pobieranego z tablicy) na dodatkowych dwoch wyswietlaczach led, zauzmy ze sterowanie anodami wyswietlaczy bedzie z portb 0-5 a poszczegolnymi segmentami z portd, wiem jak umiescic poszczegolne cyfry i znaki w tabeli i wysterowac tylko jeden wyswietlacz, natomiast nie wiem jak wyswietlic wartos zmiennej (np. wysw) na czterech wyswietlaczach i jakis znak na pozostalych dwoch
    z gory dziekuje za pomoc
    pozdrawiam

    zapomniale dopisac ze chdzi mi o bascom avr
  • REKLAMA
  • #2 2397742
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    W skrócie musisz multipleksować wyświetlacze. Ich zasilania podłączasz przez tranzystory do 4 linii uC, a linie danych łączysz wspólną magistralą do 1 portu uC. I robisz tak: wystawiasz na port daną na pierwszy wyswietlacz i uaktywniasz jego linie zasilania, potem wystawiasz daną na drugi i uwktywniasz jego linię zasilania (wyłączając zasilanie poprzedniego) i tak robisz do 4, a później od początku.
    Pozdrawiam.
  • #3 2397774
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    wiem jak to ma wyladac i mniej wiecej wiem jak to zrealizowac ..... natomiast nie wiem jak zrobic zeby wartos zmiennej wyswietlic na tych czterech wyswietlaczach tzn jakie program napisac aby wartosc jednosci byla na 1 wyswietlaczu, wartosc dziesiatek na 2, setek na 3 i tysiecy na czwartym
  • #4 2397791
    john_t
    Poziom 29  
    Posty: 1070
    Pomógł: 127
    Ocena: 89
    Obsługa więcej niż jednego wyświetlacza to multipleksowanie. Ponieważ sterowanie 1 wyświetlaczem wymaga 7 sygnałów (pinów) oraz dodatkowego sygnału do obsługi anody to odbywa się to tak. Np. chcemy wyświetlić liczbę 1234 na 4 wyświetlaczach. Wykorzystujemy 7 pinów danych do wszystkich 4 wyświetlaczy (połączone równolegle) oraz 4 dodatkowe piny do naprzemiennego sterowania anod. I tak, wyświetlamy cyfrę 1 na 1-szym wyświetlaczu (przez pewien czas z reguły 10ms) potem go gasimy (sterownie anodą) i jednocześnie zapalamy 2-gi wyświetlacz podając na 7 pinów danych cyfrę 2 itd... Czas wyświetlania danych na kolejnych wyświetlaczach nie może być zbyt długi gdyż wystąpi niekorzystny efekt migotania ale nie może też być zbyt krótki gdyż wyświetlacze będą świecić zbyt ciemno. Z doświadczenia ten czas to od 5 do 15ms.
    Pozdrawiam.
  • #5 2397819
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    wyswielic stale ktore juz miale przypisane do poszczegolnych wyswietlaczy tez mi sie udalo natomiat nie wiem jak wyswielic zmienna z jakiegos rejestru ktora jest czterocyfrowa (dziesietnie) i wyswietlic odpowiednio jednosci na 1 wys, dziesiatki na 2 itd z tego co czytalem to trzeba uzyc dzielenia z reszta ale nie wiem jak to ma wygladac
  • REKLAMA
  • #6 2397944
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    Witam.
    Ja mam to zrobione tak:
    '------------ obliczanie cyfr 1-4 do wyświetlenia --------------------------
    Cyfra(1) = Nastaw / 1000 'tysiące
    Cyfra(2) = Nastaw Mod 1000
    Cyfra(2) = Cyfra(2) / 100 'setki
    Cyfra(3) = Nastaw Mod 100
    Cyfra(3) = Cyfra(3) / 10 'dziesiątki
    Cyfra(4) = Nastaw Mod 10 'jedności
    '--------------- wygaszanie zer nieznaczących -------------------------------
    If Cyfra(1) = 0 Then
    Cyfra(1) = 10
    If Cyfra(2) = 0 Then
    Cyfra(2) = 10
    If Cyfra(3) = 0 Then
    Cyfra(3) = 10
    If Cyfra(4) = 0 Then Cyfra(4) = 20 'gdy C(4)=0 to kreska pozioma
    End If
    End If
    End If

    Segmenty:
    Data 18 , 119 , 42 , 38 , 71 , 134 , 130 , 55 , 2 , 6 , 'kod cyfr 0-9
    Data 255 , 138 , 235 , 154 , 54 , 190 , 3 , 226 , 103 , 11 , 239 , 218 , 242,
    Data 174 , 191 , 98 , 227
    '10-pusta
    ten dalej to wygaszanie zer nieznaczących z przodu,możesz tego nie stosować jeśli nie przeszkadza Ci świecenie zer.
    Samo "rozebranie liczby na czynniki jest na początku,działa znakomicie i tak to mniej więcej się robi.Zmienna "nastaw" to u mnie zmienna która przechowuje właśnie tą 4 cyfrową liczbę do wyświetlenia.
    Pozdrawiam.
  • #7 2397958
    john_t
    Poziom 29  
    Posty: 1070
    Pomógł: 127
    Ocena: 89
    Jest taka fajna funkcja MID tyle że działa na łańcuchach tekstowych. Czyli Twoją zmienną liczbę trzeba zamienić na zmienną tekstową. A następnie rozebrać na poszczególne kolejne pojedyncze cyfry. Przedstawia to poniższy program w Bascom'ie:

    Dim A As Integer
    Dim C As String * 1
    Dim D As String * 1
    Dim E As String * 1
    Dim F As String * 1
    Dim Z As String * 4


    A = 6789 'zmienna cyfra
    Z = Str(a) 'zmienna text

    C = Mid(z , 1 , 1) 'Pierwsza cyfra
    D = Mid(z , 2 , 1) 'Druga cyfra
    E = Mid(z , 3 , 1) 'Trzecia cyfra
    F = Mid(z , 4 , 1) 'Czwarta cyfra


    Print C ' Tu można sprawdzić wynik na symulku
    Print D ' lub przerobić na cyfrę np: d=val(d) i wysłać na port
    Print E ' sterujący wyświetlaczami
    Print F

    End


    Pozdrawiam.
  • #8 2397995
    Jaca
    Poziom 32  
    Posty: 1332
    Pomógł: 239
    Ocena: 216
    ...albo:

    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Dim Dig(4) As Byte
    Dim Wart As Word
    Dim Petla As Byte
    Dim Tmp As Word
    
    Wart = 1234
    For Petla = 1 To 4
       Tmp= Wart Mod 10
       Dig(petla) = Tmp
       Wart = Wart / 10
    Next
    
    Do
    Loop
    End


    Pozdrawiam...
  • #9 2398020
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    tak też można,procedura z dzieleniem zajmuje odrobinę mniej pamięci, jeśli jest jej mało to można zyskać ze 2 bajty

    Dodano po 2 [minuty]:

    (dotyczyło to procedury ze zmiennymi łańcuchowymi)
  • #10 2400310
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    witam
    wlasnie siedze i bawie sie tymi procedurami
    napisalem cos takiego ale niestety jakies dziwne rzeczy mi sie wyswietlaja na wyswietlaczu (cyfry w tablicy mam dobrze zapisane), jezeli zwieksze czas waitms to wyswietlacz zaczyna "migac", ale nie to jest najwazniejsze, poprostu zamiast cyfr na wyswietlaczu mam jakies dziwne "krzaczko-robaczki" :)
    zastosowalem pomysl @john_t
    moze ktos zerknie na to i cos mi doradzi bo siedze nad tym juz dosyc dlugo i nic nie wymyslilem

    $regfile = "m8515.dat"
    $crystal = 8000000

    Config Porta = Output
    Config Portc = Output

    Dim Wartosc As Integer
    Dim A As String * 1
    Dim B As String * 1
    Dim C As String * 1
    Dim D As String * 1
    Dim Z As String * 4


    Dim W1 As Byte
    Dim W2 As Byte
    Dim W3 As Byte
    Dim W4 As Byte

    C1 Alias Portc.0
    C2 Alias Portc.1
    C3 Alias Portc.2
    C4 Alias Portc.3

    Wys Alias Porta



    Wartosc = 6789 'zmienna cyfra

    Do



    Z = Str(wartosc) 'zmienna text

    A = Mid(z , 1 , 1) 'Pierwsza cyfra
    B = Mid(z , 2 , 1) 'Druga cyfra
    C = Mid(z , 3 , 1) 'Trzecia cyfra
    D = Mid(z , 4 , 1) 'Czwarta cyfra


    W1 = Lookup(a , Segmenty)
    W2 = Lookup(b , Segmenty)
    W3 = Lookup(c , Segmenty)
    W4 = Lookup(d , Segmenty)

    Reset C1
    Wys = W1
    Waitms 1
    Set C1

    Reset C2
    Wys = W2
    Waitms 1
    Set C2

    Reset C3
    Wys = W3
    Waitms 1
    Set C3

    Reset C4
    Wys = W4
    Waitms 1
    Set C4

    Loop

    End



    Segmenty:
    Data 1 , 79 , 18 , 6 , 76 , 36 , 32 , 15 , 0 , 4



    moze kod nie jest profesjonalny ale dopiero sie ucze :)
  • #11 2400627
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    moim zdaniem błąd tkwi w przypisywaniu zmiennym typu byte wartości zmiennych typu string,możliwe że dlatego wynik nie jest poprawny
  • #12 2400750
    Vein
    Poziom 22  
    Posty: 742
    Pomógł: 1
    Ocena: 51
    ja mam wiekszy problem, chcialbym zastosować atmege8 albo atmege16 do wysterowania 2 wyświetlaczy LED, tzn jeden wyświetlacz skłądał 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 :| ) można by było wykorzystać jakiś układzik, który sterowało by się tylko 3 bitami, na 3 bitach można by bło wysterować już 27 wyświetlaczy (teoretycznie), ale niestety ja nie znam takiego układu :( , 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 :]
  • REKLAMA
  • #13 2400830
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    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.
  • #14 2403052
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    @jacobsek zdeklarowalem jeszcze zmienne dim aa as byte itd. i dodalem aa=val(a) i wywalilem na wys zmienna aa (analogicznie dla pozostalych cyfr) Teraz dziala :)

    ale mam pytanko nastepne .....
    jak mam wyeliminowac "migotanie" wyswietlaczy .... nie moge zmniejszyc czasu zapalania wyswietlaczy bo jest waitms 1, a mniejszej wartosci sie nie da ustawic
  • #15 2404185
    submariner
    Poziom 32  
    Posty: 2319
    Pomógł: 51
    Ocena: 268
    do innych opoznien uzyj np petli for next albo odswiezaj wielokrotnie wyswietlacze- w petli u mnie drugie rozwiazanie dziala ok i nic nie miga
  • #16 2404252
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    witam.
    Jeśli chcesz użyć mniejszego czasu opóźnienia to podawaj go w postaci waitus,czas
    czas po waitus oznacza mikrosekundy(1-65535).
    Pozdrawiam

    Dodano po 3 [minuty]:


    Cyfra(1) = liczba / 1000 'tysiące
    Cyfra(2) = liczba Mod 1000
    Cyfra(2) = Cyfra(2) / 100 'setki
    Cyfra(3) = liczba Mod 100
    Cyfra(3) = Cyfra(3) / 10 'dziesiątki
    Cyfra(4) = liczba Mod 10 'jedności

    spróbuj tej procedury,ona naprawdę zajmuje mniej miejsca pamieci proca,tylko oczywiście zadeklaruj zmienne.
  • REKLAMA
  • #18 2406259
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    Jesli chodzi o C to lipa,odpisałem Tobie w Twoim drugim poście co do transmisji.
    Pracuję jak na razie tylko z bascomem C mam zamiar dopiero poznać.
  • #19 2407214
    cyberdar
    Poziom 31  
    Posty: 1465
    Pomógł: 161
    Ocena: 73
    Witam

    Problem sterowania jest zasadniczo dość prosty jedanak trzeba zdać sobie sprawę z pewnych zjawisk i ich następstw. W jednym z postów ktoś napisał, że odświeżanie następuje co 10ms (5-15ms). Jest to prawda i nie jest. Trzeba wiedzieć, że wyświetlacz przy multipleksowaniu powinien być odświeżany z częstotliowścią nie mniejszą niż 50Hz. Przy podanych założeniach (10ms) aby uniknąć efektu migotania właściwie możnaby podłączyć 2 kostki LED. Należy unikać częstotliwości dokładnie 50Hz. Bezpieczniej dać ją nieco wyższą. Do sterowania (odświeżania) najlepiej "zatrudnić" Timer. Zagwarantuje to stabilną częstotliwość odświeżania.
    Jak powinna wyglądać obsługa takiego przerwania ? Po jego wystąpieniu pierwszą rzeczą powinno być załadowanie Timera, następnie wygaszenie (najlepiej) wszystkich wyświetlaczy. Potem należy inkrementować zmienną, która "zlicza do ilości użytych wyświetlaczy". Po osiągnięciu ilości użytych wyświetlaczy należy ją wyzerować. W tym przerwaniu musi oczywiście nastąpić wystawienie odpowiedniej wartości na odpowiedni wyświetlacz i jej wyświetlenie. Wartość dla katod albo wystawiamy na port albo wysyłamy szeregowo do 74164 np. przy pomocy instrukcji SHIFTOUT. Następnie zapalmy dany wyświetlacz. I właściwie na tym kończy się przerwanie.
    Zapewne ktoś zapyta skąd dane do tego wyświetlacza. Można to zrobić na wiele sposobów ale odradzam przygotowywanie tej wartości w przerwaniu. Może się okazać (w pewnych przypadkach), że procesor nie zdąży obsłużyć innych rzeczy tylko "skoncentruje się" na wyświetlaczu. Ostatnio wpadłem na pomysł aby dane dla wyświetlacza były przygotowywane w czasie pracy programu. Dosłownie jest to jedna z procedur. Wartość, którą mam wyświetlić (liczbowa) jest formatowana do takiej ilości znaków ile jest wyświetlaczy. Oczywiście jest zamieniana na string. Jedyne co trzeba potem zrobić to przy pomocy instrukcji MID wyłuskać znak i zamienić go na "cyfrę". Cyfry dla wygody umieścić w tablicy.

    Opis jest może trochę skomplikowany ale metoda jest dość przejrzysta. Podany pomysł na generowanie odpowiedniej wartości do wyświetlenia nie spowoduje żadnych zakłóceń podczas wyświetlania. Jeśli zajdzie potrzeba udostępnię listing na privie.

    --
    pozdrawiam
  • #20 2407844
    thorin00
    Poziom 14  
    Posty: 163
    Pomógł: 2
    witam

    @jacobsek
    zastosowalem procedure ktora mi podales ale tez mam problem poniewaz kiedy podlaczylem timer (po przepelnieniu inkramenuje mi zmienna wartosc typu integer) dolicza do 0230 poczym na wyswiellaczu wyskakuje wartosc 1031 liczy do 1056 (chyba jakos tak bo dos szybko liczy) i zaczyna od zera, po wylaczeniu timera i wpisaniu do zmiennej wartosc - 9999 na wys pokazuje mi sie wartosc 0041

    z procedura ktroa zamiescilem kilka postow wyzej ( oczywiscie z poprawkami div) (ta ze zmiennymi typu string) mam maly problem poniewaz kiedy uruchomilem timer zeby mi zliczal impulsy i wyswietlal na wys, zaczynal wyswietlac na wyswietlaczu tysiecznym (tzn. pierwszym od lewej) a nastepnie przesuwal jednosci na wyswietlacz setny i dziesiatki liczyl na tysiecznym, analogicznie dalej ..... nie wiedzialem jak ten problem rozwiazac

    @cyberdar jezeli chodzi o timery to niestety wszystkie bede musial uzyc do czegos innego ale jezeli mozesz mi przeslac ta procedure na maila to chetnie sie z nia zapozna i moze mi sie przyda w przyszlosci
    pozdrawiam
  • Pomocny post
    #21 2408215
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    jeśli nasz zmienną typu integer to zmienne obliczjące cyfry też zmień na integer

Podsumowanie tematu

✨ Dyskusja dotyczy wyświetlania wartości zmiennej (np. od 0 do 9999) na 4-cyfrowym 7-segmentowym wyświetlaczu LED sterowanym mikrokontrolerem w Bascom AVR oraz wyświetlania znaków na dodatkowych dwóch wyświetlaczach. Kluczowym zagadnieniem jest multipleksowanie wyświetlaczy, czyli naprzemienne włączanie zasilania poszczególnych wyświetlaczy i podawanie na wspólne linie segmentów odpowiednich danych. Wartość zmiennej dzieli się na poszczególne cyfry (tysiące, setki, dziesiątki, jedności) za pomocą operacji dzielenia i modulo, które następnie są wyświetlane na kolejnych wyświetlaczach. Alternatywnie można konwertować liczbę na łańcuch znaków i wyodrębniać cyfry funkcją MID. Problemy zgłaszane to migotanie wyświetlaczy, które można zredukować stosując krótsze czasy odświeżania (np. waitus zamiast waitms) lub wielokrotne odświeżanie w pętli, a także stabilne sterowanie za pomocą przerwań timerów, które zapewniają stałą częstotliwość multipleksowania (zalecane powyżej 50 Hz). Wskazano, że zmienne przechowujące cyfry powinny mieć odpowiedni typ (np. integer lub byte), aby uniknąć błędów przy konwersji z łańcuchów znaków. W kwestii sprzętowej zaproponowano użycie rejestrów przesuwających 74LS164 do zmniejszenia liczby potrzebnych linii portów mikrokontrolera oraz sterowanie anodami przez tranzystory. Dyskutowano także o synchronizacji multipleksowania z timerem i oprogramowaniu w Bascom AVR, z przykładami kodu dzielącego liczbę na cyfry i konwertującego je do postaci segmentów.
Wygenerowane przez model językowy.
REKLAMA