Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięmultopleksowany wyswietlacz led i bascom8051
Moderatorzy:Jacek Bogusz, procesorowiec, robertw, tomasz_jablonski, r-mik, Moderatorzy
Witam
Nie bardzo potrafię napisać procedurę do multipeksowego starowania czterema wyświetlaczami led.
Chcę wyświetlić na nim godziny i minuty odebrane z PCF8583, mikrokontroler to AT89S52.
Proszę o jakieś wskazówki, bo walczę z tym już długo i nici.
Jeśli ktoś ma taką procedurę z opisem to bardzo proszę o jej udostępnienie, nie szukam gotowca, tylko kawałka kodu z dokładnym opisem co i jak.
Po prostu chcę zrozumieć idee multipleksowego sterowania wyswietlaczem.
Pozdrawiam
Nie bardzo potrafię napisać procedurę do multipeksowego starowania czterema wyświetlaczami led.
Chcę wyświetlić na nim godziny i minuty odebrane z PCF8583, mikrokontroler to AT89S52.
Proszę o jakieś wskazówki, bo walczę z tym już długo i nici.
Jeśli ktoś ma taką procedurę z opisem to bardzo proszę o jej udostępnienie, nie szukam gotowca, tylko kawałka kodu z dokładnym opisem co i jak.
Po prostu chcę zrozumieć idee multipleksowego sterowania wyswietlaczem.
Pozdrawiam
Chodzi Ci o wyswietlacz 7-segm? Zreszta idea jest taka sama.
Do 4 wyswietlaczy bedzie Ci, w najprostszej kombinacji, potrzebny 1 pelny port + 4 linie z innego portu (nazwijmy je sterujacymi).
Zalozmy ze masz podpiete wyswietlacze bezposrednio do portow (i ze te porty to wytrzymaja pradowo). Wyswietlacze ze wspolna katoda. Oczywiscie rezystory ograniczajace prad to wymog, upewnienie sie ze porty wytrzymaja obiazenie, ale o tym juz wspominalem.
Na porcie sterujacym jest b1111. Na porcie pelnym wystawiasz co chcesz wyswietlic, czyli np. b00000110 (dla jedynki, w ukladzie DPgfedcba - DP to kropka), zas na 4 liniach sterujacych, zanegowany wybor wyswietlacza - np. b1110 - dla skrajnie prawego, b1011 - dla 2-go od lewej).
Odczekujesz chwile, i zmiana -> sterujacy na b1111, pelny na to co ma byc na nastepnej cyfrze, np. b01011011 - dla dwojki, i sterujacy na nastepny wyswietlacz, np. b1101).
Zauwaz ze wyswietlacze poza wybranym beda mialy segmenty spolaryzowane albo zaporowo, albo obie koncowki na potencjale 1. to samo sie tyczy zbednych segmentow wybranego wyswietlacza. Diody maja swoja bezwladnosc swietlna, a wiec tak zrealizowane wyswietlania bedzie przy odpowiednim "przemiataniu" niezauwazalne.
To byl najprostszy przyklad, teraz bardziej uniwersalne rozwiazanie, bezpieczniejsze dla ukladu sterujacego:
W zasadzie zamiany sa tylko takie, ze miedzy katode wyswietlacz (kazdego z 4 osobny) a mase ukladu wstawiasz tranzystor (tu NPN), baza (przez rezystorek) sterujesz z portu "sterujacego". Roznica jest jeszcze taka, ze teraz port sterujacy jest niezanegowany, tylko wprost wskazuje wyswietlacz, ktory chcemy obsluzyc -> b0001, b0010, b0100, b1000. Stan spoczynkowy b0000. Reszta bez zmian. Funkcjonalnie rozni sie tym, ze katoda niewybranego wyswietlacza jest w stanie wysokiej impedancji. Jest to wiec sterowanie bezpieczniejsze, pozatym dajace wieksze mozliwosci jesli chodzi o max prad swiecenia segmentu (juz nie przykladowe 20mA na wszystkie 7 segm w stanie niskim, tylko po 20 mA na kazdy segment w stanie wysokim).
Oczywiscie mozna to jeszcze rozwijac, np. zastosowac multiplexem 2 na 4, dzieki czemu ograniczymy liczbe linii sterujacych do 2. Zastosowac jakis rejestr przesowny czy dziwaczny licznik, to nawet do 1 linii.
Mam nadzieje, ze cos z tego zrozumiesz... mam dzis co prawda checi, ale niezbyt chyba forme na tlumaczenie przemysl wiec dokladnie zanim cos wykonasz w sprzecie.
Segment - pojedyncza "belka" na wyswietlaczu - to jakby ktos mial watpliwosci.
Do 4 wyswietlaczy bedzie Ci, w najprostszej kombinacji, potrzebny 1 pelny port + 4 linie z innego portu (nazwijmy je sterujacymi).
Zalozmy ze masz podpiete wyswietlacze bezposrednio do portow (i ze te porty to wytrzymaja pradowo). Wyswietlacze ze wspolna katoda. Oczywiscie rezystory ograniczajace prad to wymog, upewnienie sie ze porty wytrzymaja obiazenie, ale o tym juz wspominalem.
Na porcie sterujacym jest b1111. Na porcie pelnym wystawiasz co chcesz wyswietlic, czyli np. b00000110 (dla jedynki, w ukladzie DPgfedcba - DP to kropka), zas na 4 liniach sterujacych, zanegowany wybor wyswietlacza - np. b1110 - dla skrajnie prawego, b1011 - dla 2-go od lewej).
Odczekujesz chwile, i zmiana -> sterujacy na b1111, pelny na to co ma byc na nastepnej cyfrze, np. b01011011 - dla dwojki, i sterujacy na nastepny wyswietlacz, np. b1101).
Zauwaz ze wyswietlacze poza wybranym beda mialy segmenty spolaryzowane albo zaporowo, albo obie koncowki na potencjale 1. to samo sie tyczy zbednych segmentow wybranego wyswietlacza. Diody maja swoja bezwladnosc swietlna, a wiec tak zrealizowane wyswietlania bedzie przy odpowiednim "przemiataniu" niezauwazalne.
To byl najprostszy przyklad, teraz bardziej uniwersalne rozwiazanie, bezpieczniejsze dla ukladu sterujacego:
W zasadzie zamiany sa tylko takie, ze miedzy katode wyswietlacz (kazdego z 4 osobny) a mase ukladu wstawiasz tranzystor (tu NPN), baza (przez rezystorek) sterujesz z portu "sterujacego". Roznica jest jeszcze taka, ze teraz port sterujacy jest niezanegowany, tylko wprost wskazuje wyswietlacz, ktory chcemy obsluzyc -> b0001, b0010, b0100, b1000. Stan spoczynkowy b0000. Reszta bez zmian. Funkcjonalnie rozni sie tym, ze katoda niewybranego wyswietlacza jest w stanie wysokiej impedancji. Jest to wiec sterowanie bezpieczniejsze, pozatym dajace wieksze mozliwosci jesli chodzi o max prad swiecenia segmentu (juz nie przykladowe 20mA na wszystkie 7 segm w stanie niskim, tylko po 20 mA na kazdy segment w stanie wysokim).
Oczywiscie mozna to jeszcze rozwijac, np. zastosowac multiplexem 2 na 4, dzieki czemu ograniczymy liczbe linii sterujacych do 2. Zastosowac jakis rejestr przesowny czy dziwaczny licznik, to nawet do 1 linii.
Mam nadzieje, ze cos z tego zrozumiesz... mam dzis co prawda checi, ale niezbyt chyba forme na tlumaczenie przemysl wiec dokladnie zanim cos wykonasz w sprzecie.
Segment - pojedyncza "belka" na wyswietlaczu - to jakby ktos mial watpliwosci.
Witam
Tak się składa, że od strony sprzętowej wszystko jest ok.
Wyświetlacze, tranzystory sterujące katody- to wszystko działa i jest dla mnie oczywiste.
Znalazłem gdzieś w internecie kilka programów i wyłuskałem z nich procedurkę obsługi wyświetlacza.
Musze przyznać, że nawet działa
Mam problem z rozbiciem całego bajtu na części.
Dokładniej mówiąc mam w zmiennej cała liczbę (dziesiątki i jedności ), chcę wyswietlić dziesiatki na starszym wyświetlaczu, a jedności na młodszym i tu jest problem.
Do 15 wyświetla dobrze od 16 wyświetlają się krzaki, to znaczy segmenty skaczą np. zamiast wyświetlić 7 to wyświetla się 1 i co jakiś czas dopala się segment A wyświetlacza.
Pozdrawiam
Tak się składa, że od strony sprzętowej wszystko jest ok.
Wyświetlacze, tranzystory sterujące katody- to wszystko działa i jest dla mnie oczywiste.
Znalazłem gdzieś w internecie kilka programów i wyłuskałem z nich procedurkę obsługi wyświetlacza.
Musze przyznać, że nawet działa
Mam problem z rozbiciem całego bajtu na części.
Dokładniej mówiąc mam w zmiennej cała liczbę (dziesiątki i jedności ), chcę wyswietlić dziesiatki na starszym wyświetlaczu, a jedności na młodszym i tu jest problem.
Kod: Zaznacz cały
cyfra = H / 10 ' dziesiątki godzin
cyfra = H mod 10 ' jedności godzin (mod - to reszta z dzielenia)
Pozdrawiam
Witam
Już pokazuję.
teraz jest tak, że cały program zamula, mikrokontroler reaguje na wciśniecie przycisku z dużym opóźnieniem itp.
Kombinowałem z różnymi wartościami ładowanymi do timera, ale nic to nie dało.
no i dalej jest problem z wyświetlaniem...
Pozdrawiam
Już pokazuję.
Kod: Zaznacz cały
$crystal = 8000000
Config Timer0 = Timer , Gate = Internal , Mode = 2
Load Timer0 , 125
On Timer0 Mult_wysw
Enable Timer0
Enable Interrupts
Start Timer0
Main:
goto main
Mult_wysw:
Load Timer0 , 125
Hh = G
Mm = M
Hh = Makedec(hh)
Mm = Makedec(mm)
Hj = Hh / 10
hd = Hh Mod 10
Mj = Mm / 10
Md = Mm mod 10
Set Mux
Set W4
Set W1
Set W2
Set W3
Incr Mux
If Mux = 4 Then Mux = 0
Select Case Mux
Case 0 : Digivalue = Hj
Reset W1
Case 0 : Digivalue = Hd
Reset W2
Case 0 : Digivalue = Mj
Reset W3
Case 0 : Digivalue = Md
Reset W4
End Select
Seg = Lookup(digivalue , Digits)
Reset Mux
Return
Digits:
Data &B10000001 , &B11110011 , &B01001001 , &B01100001 , &B00110011 , &B00100101 , &B00000101 , &B11110001 , &B00000001 , &B00100001
Kombinowałem z różnymi wartościami ładowanymi do timera, ale nic to nie dało.
no i dalej jest problem z wyświetlaniem...
Pozdrawiam
Ech... bascom...
O powyzszym listingu powiem tak:
Jak dla mnie niespojny, nielogiczny i z masa niescislosci. Troche rzeczy mozna by ponadto zoptymalizowac.
Co to jest G i H, jaki typ i skad sie biora wartosci. Czy napewno sa w BCD? Pozatym dla wlasnej wygody zacznij trzymac sie malych_WIELKICH liter w nazwach, bo oczoplasu mozna dostac. Ps. Czyz nie lepiej bylo by jesli juz Hh=Makedec(G);
Mux, W1, W2, W3, W4.. mozna sie domyslic co za stale, ale... chwile pozniej Mux juz uzywasz jak zmiennej, inkrementujesz ja. Na dodatek konstrukcja case ma 4 przypadki, wszystkie dla Mux=0?? Absurd, po co wogole case w takim razie?
Co zawiera ta tabela digits? Bo takich hieroglifow jak tam sa to by sie chyba nawet predator nie powstydzil (i nie odczytal). No chyba ze masz jakos pomerdane te wyprowadzenia (ale nawet wowczas zapalone/zgaszone mi sie nie zgadzaja).
Czy Ty jestes pewien ze ten program choc w 10% dziala tak jak chciales, on cokolwiek robi sensownego?
Byc moze ja juz calkiem odroslem od bascoma, ale jak dla mnie to jest groch z kapusta.
O powyzszym listingu powiem tak:
Jak dla mnie niespojny, nielogiczny i z masa niescislosci. Troche rzeczy mozna by ponadto zoptymalizowac.
Co to jest G i H, jaki typ i skad sie biora wartosci. Czy napewno sa w BCD? Pozatym dla wlasnej wygody zacznij trzymac sie malych_WIELKICH liter w nazwach, bo oczoplasu mozna dostac. Ps. Czyz nie lepiej bylo by jesli juz Hh=Makedec(G);
Mux, W1, W2, W3, W4.. mozna sie domyslic co za stale, ale... chwile pozniej Mux juz uzywasz jak zmiennej, inkrementujesz ja. Na dodatek konstrukcja case ma 4 przypadki, wszystkie dla Mux=0?? Absurd, po co wogole case w takim razie?
Co zawiera ta tabela digits? Bo takich hieroglifow jak tam sa to by sie chyba nawet predator nie powstydzil (i nie odczytal). No chyba ze masz jakos pomerdane te wyprowadzenia (ale nawet wowczas zapalone/zgaszone mi sie nie zgadzaja).
Czy Ty jestes pewien ze ten program choc w 10% dziala tak jak chciales, on cokolwiek robi sensownego?
Byc moze ja juz calkiem odroslem od bascoma, ale jak dla mnie to jest groch z kapusta.
Witam
Dzięki za krytykę
Ten kod jest roboczy i dlatego trochę pokręcony.
G i H przechowują godziny i minuty odczytane z PCF8583 i są w kodzie BCD, no i oczywiście są to zmienne bajtowe.
Co do Tabeli digits wszystko się w niej zgadza znaki są poprawnie w niej zapisane i wyświetlane.
Przez tranzystor podaję na wyświetlacz +5V, a dane pobierane są z tej tabeli.
Podaję aktualny kod przerwania, problem z wyświetlaniem nie ustąpił.
Cały czas "latają cyfry", zamiast 17 wyświetla mi 11 i co jakiś czas dopala segment A, czyli miga mi między 1 a 7.
Dzięuję za wszelką pomoc i pozdrawiam
Dzięki za krytykę
Ten kod jest roboczy i dlatego trochę pokręcony.
G i H przechowują godziny i minuty odczytane z PCF8583 i są w kodzie BCD, no i oczywiście są to zmienne bajtowe.
Co do Tabeli digits wszystko się w niej zgadza znaki są poprawnie w niej zapisane i wyświetlane.
Przez tranzystor podaję na wyświetlacz +5V, a dane pobierane są z tej tabeli.
Podaję aktualny kod przerwania, problem z wyświetlaniem nie ustąpił.
Cały czas "latają cyfry", zamiast 17 wyświetla mi 11 i co jakiś czas dopala segment A, czyli miga mi między 1 a 7.
Kod: Zaznacz cały
Const Xtal = 8000000
$crystal = Xtal
Const Sysclock = Xtal / 12
Const Timer0value = 65536 -(sysclock / 200) '200 przerwań od T0 na sekundę
Seg Alias P3
Disp Alias P1
Dim Mux As Byte , T0cntr As Byte
Dim Ss As Byte , Mm As Byte , Hh As Byte , Digivalue As Byte
Config Timer0 = Timer , Gate = Internal , Mode = 1
On Timer0 T0_int
Enable Timer0
Enable Interrupts
Seg = 255
Disp = 255
T0cntr = 0
Counter0 = Timer0value
Start Timer0
T0_int:
Th0 = High(timer0value)
Incr T0cntr
If T0cntr > 200 Then
T0cntr = 0
End If
Hh = G
Mm = M
Hh = Makedec(hh)
Mm = Makedec(mm)
Set Disp.mux
Incr Mux
Mux = Mux And 3
Select Case Mux
Case 0 : Digivalue = Hh / 10
Case 1 : Digivalue = Hh Mod 10
Case 2 : Digivalue = Mm / 10
Case 3 : Digivalue = Mm Mod 10
End Select
Seg = Lookup(digivalue , Digits)
Reset Disp.mux
Return
Digits:
Data &B10000001 , &B11110011 , &B01001001 , &B01100001 , &B00110011 , &B00100101 , &B00000101 , &B11110001 , &B00000001 , &B00100001
Ok, teraz wyglada troszke ladniej sprobuje przeanalizowac jutro, chyba ze do tej pory ktos z bascomowcow poda jakies uwagi.
Acha... cyfry faktycznie sa ok, tyle ze masz wyswietlacze ze wspolna ANODA (nie katoda), to mnie troche zmylilo, pozatym uklad jest lekko inny niz sam zwykle przyjmuje, ale w sumie tez przystepny.
Acha... cyfry faktycznie sa ok, tyle ze masz wyswietlacze ze wspolna ANODA (nie katoda), to mnie troche zmylilo, pozatym uklad jest lekko inny niz sam zwykle przyjmuje, ale w sumie tez przystepny.
Witam
Ja już rwę włosy z głowy.
Dziwne bo na AVR multipleksowanie działa mi dobrze.
Początkowo przeniosłem procedurę z AVR na 8051 i lipa.
Wszystko było by ok gdyby nie błędne wyświetlanie...
Pozdrawiam
Po niedługim czasie znalazłem błąd
Po odczycie z RTC dane zamieniałem z kodu BCD na kod dziesiętny.
W przerwaniu wartość zmiennej w postaci dziesiętnej jeszcze raz zamieniałem na wartość dziesiętną.
Wystarczyło skasować jedną linijkę i wszystko ruszyło z kopyta.
Ja już rwę włosy z głowy.
Dziwne bo na AVR multipleksowanie działa mi dobrze.
Początkowo przeniosłem procedurę z AVR na 8051 i lipa.
Wszystko było by ok gdyby nie błędne wyświetlanie...
Pozdrawiam
Po niedługim czasie znalazłem błąd
Po odczycie z RTC dane zamieniałem z kodu BCD na kod dziesiętny.
W przerwaniu wartość zmiennej w postaci dziesiętnej jeszcze raz zamieniałem na wartość dziesiętną.
Wystarczyło skasować jedną linijkę i wszystko ruszyło z kopyta.
Kto jest online
Użytkownicy przeglądający to forum: Bing [Bot] i 16 gości