LCD - Siedmiosegmentowe wyświetlacze LCD (szkło)

Pozostałe układy mikrokontrolerów, układy peryferyjne i inne, nie mieszczące się w powyższych kategoriach.
gaweł
User
User
Posty: 345
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

LCD - Siedmiosegmentowe wyświetlacze LCD (szkło)

Postautor: gaweł » środa 17 maja 2017, 23:28

LCD-ilu00.jpg

Bardzo popularnym sposobem prezentacji informacji liczbowej w urządzeniach elektronicznych jest zastosowanie wyświetlaczy siedmiosegmentowych. W większości przypadków pierwsze skojarzenie tego typu wyświetlacza sugeruje użycie wyświetlacza bazującego na diodach LED. Popularność zastosowania wyświetlaczy LED-owych wynika przede wszystkim z prostoty ich użycia. Sterowanie diodą LED należy do banalnie prostych. Dodatkowym atutem jest możliwość sterowania wielocyfrowym wyświetlaczem w trybie multipleksowym, co pozwala często znacząco redukować liczbę komponentów elektronicznych przeznaczonych do budowy takiego zespołu.
Na korzyść wyświetlaczy LCD (w stosunku do wyświetlaczy LED-owch) przemawia znacząco mniejszy pobór energetyczny, co ma znaczenie w urządzeniach z zasilaniem bateryjnym. Istotną wadą wyświetlaczy LCD jest dość złożony sposób ich sterowania. Typowy wyświetlacz LCD (taki, gdzie liczba segmentów nie jest zbyt duża) zawiera jedną wspólną elektrodę tła, często oznaczaną jako BP (ang. Back Plane) oraz po jednej elektrodzie na każdy segment.
Sterowanie takim wyświetlaczem, w sensie włączania/wyłączania poszczególnych segmentów (bo trudno tu mówić o świeceniu segmentów) wymaga doprowadzenia do odpowiednich elektrod sygnału fali prostokątnej. Do wyprowadzenia wspólnego należy doprowadzić przebieg prostokątny o określonej częstotliwości. Wykorzystane w przykładzie wyświetlacze wymagają impulsów prostokątnych o częstotliwości od 30Hz do 50 Hz (typowo używana jest fala prostokątna o częstotliwości 32Hz). Jeżeli do styku BP oraz do styku segmentu zostanie doprowadzony sygnał fali prostokątnej będącej „w fazie”, to odpowiedni segment nie jest włączony. W przypadku wystąpienia na styku segmentu sygnału w przeciwnej fazie (logicznie zanegowanego) z sygnałem styku BP, to dany segment jest włączony.
LCD-ilu01.png
Ilustracje 1 oraz 2 pokazują przebiegi sygnałów na stykach wyświetlacza LCD dla segmentu wyłączonego (lustracja 1) oraz włączonego (ilustracja 2). Przebieg w kolorze błękitnym (górny) pokazuje sygnał na styku BP, przebieg w kolorze żółtym (dolny) pokazuje sygnał na styku segmentu.
W przypadku, gdy oba sygnały fali prostokątnej są w fazie (identyczne), to segment nie jest włączony. Logiczne zanegowanie jednego z sygnałów oznacza, że dany segment jest włączony.
LCD-ilu02.png
Łatwo z tego wywnioskować, że obsługa wyświetlacza LCD wymaga zbudowania generatora przebiegu prostokątnego o częstotliwości kilkudziesięciu Hz.
LCD-ilu03.PNG
Ilustracja 3 pokazuje schemat elektroniczny układu obsługującego jedną cyfrę wyświetlacza LCD. Generator
zbudowany jest w oparciu o układ NE555. Wartości elementów są tak dobrane, by uzyskać przebieg prostokątny o częstotliwości około 64 Hz. Wyjście z generatora jest podane jako sygnał zegarowy dla przerzutnika typu D (74HC74), którego zadaniem jest uzyskanie wypełnienia fali prostokątnej równo 50% (co przy okazji „jako sprzedaż wiązana” dzieli częstotliwość sygnału wejściowego przez 2).
LCD-ilu04.PNG
Wyjście przerzutnika (ilustracja 4) jest źródłem sygnału dla styku wspólnego BP. Jednocześnie sygnał ten jest doprowadzony do zespołu bramek EXOR, które pełnią funkcję „programowalnego” negatora. Podanie na drugie wejście bramki EXOR stanu logicznego zera powoduje, że na wyjściu bramki jest sygnał identyczny jak na wejściu pierwszym. Zmiana stanu odpowiedniego wejścia bramki EXOR do stanu logicznej jedynki implikuje, że na wyjściu bramki pojawia się zanegowany sygnał z wejścia.
Odpowiedni zespół bramek logicznych EXOR przyłączony do wyjścia generatora fali prostokątnej oraz zespół przełączników pozwala na możliwość indywidualnego sterowania każdym segmentem w obrębie jednej cyfry.
Do powyższego schematu zbudowany jest układ praktyczny (ilustracja 5). Przełączniki DIP SWITCH są tak ustawione, by widoczny był każdy segment w obrębie jednej cyfry.
LCD-ilu05.jpg
Manipulacja (poprzez przełączniki) każdą linią pozwala na obrazowanie różnych cyfr. Kilka przykładów pokazują ilustracje 6 oraz 7.
LCD-ilu06.jpg
LCD-ilu07.jpg
Łatwo zauważyć, że obsługa dwucyfrowego wyświetlacza LCD będzie wymagała czterech układów scalonych bramek EXOR. O ile koszt samych bramek jest znikomy, o tyle realizacja w układzie rzeczywistym może sprawiać pewne problemy (sieć połączeń, zajęta powierzchnia na płytce drukowanej). Atrakcyjną alternatywą jest zastosowanie układów logiki programowalnej (PLD). Nawet najmniejszy układ CPLD (jak przykładowo XC9536XL) posiada wystarczające zasoby by zbudować odpowiedni sterownik do prezentowanego wyświetlacza LCD.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

gaweł
User
User
Posty: 345
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: LCD - Siedmiosegmentowe wyświetlacze LCD (szkło)

Postautor: gaweł » środa 17 maja 2017, 23:58

Użycie układu CPLD do sterowania siedmiosegmentowym wyświetlaczem LCD
lcdc_i00.jpg

Bazując na powyższych rozważaniach można rozwiązać problem sterowania siedmiosegmentowym wyświetlaczem LCD z wykorzystaniem układów logiki programowalnej CPLD. Zasoby oferowane przez te układy w zupełności wystarczą do realizacji założonej funkcji. W przykładzie jest użyty układ XC2C256 w obudowie VQFP100 (o 100 wyprowadzeniach). Oczywiście zaproponowany układ jest bardzo przewymiarowany do tego zastosowania, ale jego użycie jest uzasadnione tym, … że jest przylutowany do zestawu uruchomieniowego składającego się z płyty bazowej ZL15PLD oraz modułu CPLD ZL14PLD (oferowanego przez sklep internetowy Kamami).
Z zestawu bazowego (ZL15PLD) wykorzystane będą:
  • dwucyfrowy wyświetlacz LCD (do prezentacji działania obsługi wyświetlacza),
  • zespół 8-bitowego przełącznika (do „zadawania” liczb do wyświetlania).
Z dokumentacji do wymienionego zestawu wynika, że:
lcdc_i01.PNG
wyświetlacz jest przyłączony do układu CPLD w następujący sposób:
Pin CPLD → Znaczenie
10 → Styk segmentu A cyfry jedności
11 → Styk segmentu B cyfry jedności
13 → Styk segmentu C cyfry jedności
14 → Styk segmentu D cyfry jedności
15 → Styk segmentu E cyfry jedności
16 → Styk segmentu F cyfry jedności
17 → Styk segmentu G cyfry jedności
18 → Styk segmentu DP cyfry jedności
1 → Styk segmentu A cyfry dziesiątek
2 → Styk segmentu B cyfry dziesiątek
3 → Styk segmentu C cyfry dziesiątek
4 → Styk segmentu D cyfry dziesiątek
6 → Styk segmentu E cyfry dziesiątek
7 → Styk segmentu F cyfry dziesiątek
9 → Styk segmentu G cyfry dziesiątek
8 → Styk segmentu DP cyfry dziesiątek
27 → Styk wspólnego tła (BP)
przełącznik DIP-SWITCH jest przyłączony w następujący sposób:
lcdc_i02.PNG

Pin CPLD → Znaczenie
39 → Bit 7 (najbardziej znaczący),
40 → Bit 6
41 → Bit 5
42 → Bit 4
43 → Bit 3
44 → Bit 2
46 → Bit 1
49 → Bit 0 (najmniej znaczący)
Za pomocą przełączników są podawane do sterownika kody dwóch liczb (jako dwie cyfry 4-bitowe), zadaniem układu jest realizacja obsługi pozwalająca na zobrazowanie zadanych liczb (jako liczby szesnastkowe). Do implementacji sterownika zastosowane jest bezpłatne oprogramowanie narzędziowe oferowane przez firmę XILINX.
Postać źródłowa (w języku opisu sprzętu VHDL; również w oprogramowaniu narzędziowym istnieje możliwość narysowania odpowiedniego schematu) jest następująca (moduł główny, plik LCD.VHD):

Kod: Zaznacz cały

library IEEE ;
use IEEE.STD_LOGIC_1164.ALL ;
use IEEE.STD_LOGIC_ARITH.ALL ;
use IEEE.STD_LOGIC_UNSIGNED.ALL ;
 
entity LCD is port ( Clk : in std_logic ;
                     Reset : in std_logic ;
                     SWKey : in std_logic_vector ( 7 downto 0 ) ;
                     LCD_BP : out std_logic ;
                     LCD1_A : out std_logic ;
                     LCD1_B : out std_logic ;
                     LCD1_C : out std_logic ;
                     LCD1_D : out std_logic ;
                     LCD1_E : out std_logic ;
                     LCD1_F : out std_logic ;
                     LCD1_G : out std_logic ;
                     LCD1_DP : out std_logic ;
                     LCD10_A : out std_logic ;
                     LCD10_B : out std_logic ;
                     LCD10_C : out std_logic ;
                     LCD10_D : out std_logic ;
                     LCD10_E : out std_logic ;
                     LCD10_F : out std_logic ;
                     LCD10_G : out std_logic ;
                     LCD10_DP : out std_logic ) ;
end LCD ;

architecture Behavioral of LCD is

  constant FDivCntSizeParam : integer := 10 ;

  component LCD2DigDisp port ( MClk : in std_logic ;
                               Tetr0 : in std_logic_vector ( 3 downto 0 ) ;
                               Tetr1 : in std_logic_vector ( 3 downto 0 ) ;
                               LCD_BP : out std_logic ;
                               LCD1_A : out std_logic ;
                               LCD1_B : out std_logic ;
                               LCD1_C : out std_logic ;
                               LCD1_D : out std_logic ;
                               LCD1_E : out std_logic ;
                               LCD1_F : out std_logic ;
                               LCD1_G : out std_logic ;
                               LCD1_DP : out std_logic ;
                               LCD10_A : out std_logic ;
                               LCD10_B : out std_logic ;
                               LCD10_C : out std_logic ;
                               LCD10_D : out std_logic ;
                               LCD10_E : out std_logic ;
                               LCD10_F : out std_logic ;
                               LCD10_G : out std_logic ;
                               LCD10_DP : out std_logic ) ;
  end component ;
  component FDivider generic ( constant CntSize : integer := 8 ) ;
                     port ( Clk : in std_logic ;
                            Reset : in std_logic ;
                            FDiv : out std_logic ) ;
  end component ;

  signal MClk : std_logic ;
  signal LCDDig1 : std_logic_vector ( 3 downto 0 ) ;
  signal LCDDig10 : std_logic_vector ( 3 downto 0 ) ;

begin

  LCDDig1 <= SWKey ( 3 downto 0 ) ;
  LCDDig10 <= SWKey ( 7 downto 4 ) ;
  FDivInstance : FDivider generic map ( CntSize => FDivCntSizeParam )
                          port map ( Clk => Clk ,
                                     Reset => Reset ,
                                     FDiv => MClk ) ;
  LCDMuxInstance : LCD2DigDisp port map ( MClk => MClk ,
                                          Tetr0 => LCDDig1 ,
                                          Tetr1 => LCDDig10 ,
                                          LCD_BP => LCD_BP ,
                                          LCD1_A => LCD1_A ,
                                          LCD1_B => LCD1_B ,
                                          LCD1_C => LCD1_C ,
                                          LCD1_D => LCD1_D ,
                                          LCD1_E => LCD1_E ,
                                          LCD1_F => LCD1_F ,
                                          LCD1_G => LCD1_G ,
                                          LCD1_DP => LCD1_DP ,
                                          LCD10_A => LCD10_A ,
                                          LCD10_B => LCD10_B ,
                                          LCD10_C => LCD10_C ,
                                          LCD10_D => LCD10_D ,
                                          LCD10_E => LCD10_E ,
                                          LCD10_F => LCD10_F ,
                                          LCD10_G => LCD10_G ,
                                          LCD10_DP => LCD10_DP ) ;
end Behavioral ;

Zastosowany w powyższym module komponent dzielnika częstotliwości ma następującą postać (plik FDIVIDER.VHD):

Kod: Zaznacz cały

library IEEE ;
use IEEE.STD_LOGIC_1164.ALL ;
use IEEE.STD_LOGIC_ARITH.ALL ;
use IEEE.STD_LOGIC_UNSIGNED.ALL ;

entity FDivider is generic ( constant CntSize : integer := 8 ) ;
                   port ( Clk : in std_logic ;
                          Reset : in std_logic ;
                          FDiv : out std_logic ) ;
end FDivider ;

architecture Behavioral of FDivider is

  signal FDivCnt : std_logic_vector ( CntSize - 1 downto 0 ) ;

begin

  FDividerInstance : process ( Clk , Reset )
  begin
    if Reset = '0' then
      FDivCnt <= ( others => '0' ) ;
    else
      if Clk'event and Clk = '0' then
        FDivCnt <= FDivCnt + 1 ;
      end if ;
    end if ;
  end process ;

  FDiv <= FDivCnt ( FDivCnt'left ) ;

end Behavioral ;

Użyty w module głównym komponent obsługi wyświetlacza ma następującą postać (plik LCD2DIGDISP.VHD):

Kod: Zaznacz cały

library IEEE ;
use IEEE.STD_LOGIC_1164.ALL ;
use IEEE.STD_LOGIC_ARITH.ALL ;
use IEEE.STD_LOGIC_UNSIGNED.ALL ;

entity LCD2DigDisp is port ( MClk : in std_logic ;
                             Tetr0 : in std_logic_vector ( 3 downto 0 ) ;
                             Tetr1 : in std_logic_vector ( 3 downto 0 ) ;
                             LCD_BP : out std_logic ;
                             LCD1_A : out std_logic ;
                             LCD1_B : out std_logic ;
                             LCD1_C : out std_logic ;
                             LCD1_D : out std_logic ;
                             LCD1_E : out std_logic ;
                             LCD1_F : out std_logic ;
                             LCD1_G : out std_logic ;
                             LCD1_DP : out std_logic ;
                             LCD10_A : out std_logic ;
                             LCD10_B : out std_logic ;
                             LCD10_C : out std_logic ;
                             LCD10_D : out std_logic ;
                             LCD10_E : out std_logic ;
                             LCD10_F : out std_logic ;
                             LCD10_G : out std_logic ;
                             LCD10_DP : out std_logic ) ;
end LCD2DigDisp ;

architecture Behavioral of LCD2DigDisp is

  component LCDHexConv port ( Tetr : in std_logic_vector ( 3 downto 0 ) ;
                              Seg_A : out std_logic ;
                              Seg_B : out std_logic ;
                              Seg_C : out std_logic ;
                              Seg_D : out std_logic ;
                              Seg_E : out std_logic ;
                              Seg_F : out std_logic ;
                              Seg_G : out std_logic ) ;
  end component ;

  signal LCD1 : std_logic_vector ( 6 downto 0 ) ;
  signal LCD10 : std_logic_vector ( 6 downto 0 ) ;

begin

  Conv1Instance : LCDHexConv port map ( Tetr => Tetr0 ,
                                        Seg_A => LCD1 ( 0 ) ,
                                        Seg_B => LCD1 ( 1 ) ,
                                        Seg_C => LCD1 ( 2 ) ,
                                        Seg_D => LCD1 ( 3 ) ,
                                        Seg_E => LCD1 ( 4 ) ,
                                        Seg_F => LCD1 ( 5 ) ,
                                        Seg_G => LCD1 ( 6 ) ) ;
  Conv10Instance : LCDHexConv port map ( Tetr => Tetr1 ,
                                         Seg_A => LCD10 ( 0 ) ,
                                         Seg_B => LCD10 ( 1 ) ,
                                         Seg_C => LCD10 ( 2 ) ,
                                         Seg_D => LCD10 ( 3 ) ,
                                         Seg_E => LCD10 ( 4 ) ,
                                         Seg_F => LCD10 ( 5 ) ,
                                         Seg_G => LCD10 ( 6 ) ) ;
  LCD_BP <= MClk ;
  LCD1_A <= LCD1 ( 0 ) xor MClk ;
  LCD1_B <= LCD1 ( 1 ) xor MClk ;
  LCD1_C <= LCD1 ( 2 ) xor MClk ;
  LCD1_D <= LCD1 ( 3 ) xor MClk ;
  LCD1_E <= LCD1 ( 4 ) xor MClk ;
  LCD1_F <= LCD1 ( 5 ) xor MClk ;
  LCD1_G <= LCD1 ( 6 ) xor MClk ;
  LCD1_DP <= MClk ;
  LCD10_A <= LCD10 ( 0 ) xor MClk ;
  LCD10_B <= LCD10 ( 1 ) xor MClk ;
  LCD10_C <= LCD10 ( 2 ) xor MClk ;
  LCD10_D <= LCD10 ( 3 ) xor MClk ;
  LCD10_E <= LCD10 ( 4 ) xor MClk ;
  LCD10_F <= LCD10 ( 5 ) xor MClk ;
  LCD10_G <= LCD10 ( 6 ) xor MClk ;
  LCD10_DP <= MClk ;
end Behavioral ;

Dekoder (kodu binarnego na postać wymaganą przez wyświetlacz) ma następująca postać (plik LCDHEXCONV.VHD):

Kod: Zaznacz cały

library IEEE ;
use IEEE.STD_LOGIC_1164.ALL ;
use IEEE.STD_LOGIC_ARITH.ALL ;
use IEEE.STD_LOGIC_UNSIGNED.ALL ;

entity LCDHexConv is port ( Tetr : in std_logic_vector ( 3 downto 0 ) ;
                            Seg_A : out std_logic ;
                            Seg_B : out std_logic ;
                            Seg_C : out std_logic ;
                            Seg_D : out std_logic ;
                            Seg_E : out std_logic ;
                            Seg_F : out std_logic ;
                            Seg_G : out std_logic ) ;
end LCDHexConv ;

architecture Behavioral of LCDHexConv is

  signal Segments : std_logic_vector ( 6 downto 0 ) ;
  signal Neg : std_logic ;

begin
  Neg <= '1' ;
  Seg_A <= Neg xor Segments ( 0 ) ;
  Seg_B <= Neg xor Segments ( 1 ) ;
  Seg_C <= Neg xor Segments ( 2 ) ;
  Seg_D <= Neg xor Segments ( 3 ) ;
  Seg_E <= Neg xor Segments ( 4 ) ;
  Seg_F <= Neg xor Segments ( 5 ) ;
  Seg_G <= Neg xor Segments ( 6 ) ;
-- przyporządkowanie segmentów w Segments
--      0
--     --- 
--  5 |   | 1
--     ---   <- 6
--  4 |   | 2
--     ---
--      3
  with Tetr select
    Segments <= "1000000" when "0000" ,  --0
                "1111001" when "0001" ,  --1
                "0100100" when "0010" ,  --2
                "0110000" when "0011" ,  --3
                "0011001" when "0100" ,  --4
                "0010010" when "0101" ,  --5
                "0000010" when "0110" ,  --6
                "1111000" when "0111" ,  --7
                "0000000" when "1000" ,  --8
                "0010000" when "1001" ,  --9
                "0001000" when "1010" ,  --A
                "0000011" when "1011" ,  --b
                "1000110" when "1100" ,  --C
                "0100001" when "1101" ,  --d
                "0000110" when "1110" ,  --E
                "0001110" when "1111" ,  --F
                "1111111" when others ;

end Behavioral ;

Po zaprogramowaniu układu CPLD, można zaobserwować działanie sterownika. Manipulując odpowiednimi przełącznikami, na wyświetlaczu obrazowane są właściwe liczby.
lcdc_i03.jpg
lcdc_i04.jpg
lcdc_i05.jpg
lcdc_i06.jpg
lcdc_i07.jpg
lcdc_i08.jpg
lcdc_i09.jpg


Załącznik, projekt (WebPack, Xilinx)
lcd.zip
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.


Wróć do „Inne mikroklocki, również peryferyjne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość