Xilinx ML506 16×2 LCD Çalışma

Daha önceki yazımda ML506 üzerinde çalıştığımı belirtmiştim. Bu yazımda yine bu geliştirme kartı üzerinde bulunan 16×2 LCD ekranı sürmeyi göstereceğim. Hmm sanırım çok resmi bir yazı girişi oldu. Neyse efendim yazımıza geri dönelim. Ne diyorduk , 16×2 lcd diyorduk. ML50x serisindeki kartların çoğunda bu lcd var. Bildiğimiz karakter tabanlı bir lcd. Benim kartta bulunanın markası ise “Tianma TM162VBA6”. Daha önce bu tarz lcd ekranları mikrodenetleyici ile sürenleriniz varsa zaten konuya aşinalar. Ama kısa bir hatırlatma yaparsak bu lcd ekran 8 bit veri yoluna sahip, 3 adet te yönetim sinyali içeren oldukça basit bir ekran. 8bit ya da 4bit şeklinde iletişim kurulabiliyor.

Ekranla ilgili dosyalar ise 5KS0066U ve TM162Vdc . İlk dosyada ekrandaki yönetici yonga ile ilgili bilgiler bulabilirsiniz. İkinci dosya ise üretici firmanın hazırlamış olduğu kullanım klavuzu. Gerçi bu ekranların neredeyse hepsi birbirinin aynı olduğu için muhtemelen başka firmaların bilgileri de aynıdır. Şimdi tasarımla ilgili bir kaç bilgi vereyim:

  • 100 Mhz saat işareti kullanıldı (USER_CLK=100 MHz)
  • Ekranın kullanım talimatları incelenerek zamanlamalar ona göre ayarlandı.
  • İlk açılış gecikmesi olarak 40ms’lik bir süre kullanıldı (init_d>30ms)
  • Kullanım talimatlarını  incelerseniz çoğu komutun ortalama 40 µs içinde tamamlandığını göreceksiniz. Bazı komutlar ise 1.53 ms içinde tamamlanıyor.
  • Ben ortalama her komut için 50 µs lik bir süre seçtim.
  • Yine kullanım talimatlarında bulunan zamanlama bilgilerine göre yönetim ve bilgi işaretlerinin ortalama tamamlanma süresi 500 ns civarında ki bu Tablo 1’de ve Çizelge 1’de görülebilir.

Çizelge 1 : İşaret Zamanlama Çizelgesi

  • İletişim biçimi olarak ekran, ML506 deney kartına 4bit iletişim tipinde bağlanmış. Komutlar 8bit uzunluğunda olduğuna göre her komutun gönderilmesi ancak iki aşamada tamamlanabiliyor. Önce yüksek değerlilikli 4bit(upper 4bit), sonra da düşük değerlilikli (lower 4bit) gönderiliyor.
  • Ekranın çalışmaya hazır hale getirilmesi ise şöyle gerçekleştiriliyor:
  1. İlk açılış için 30 ms’den fazla bekle
  2. Function Set” ayarını yap. 39 µs’den fazla bekle.
  3. Display On/OFF” ayarını yap. Aynı zamanda imleç seçeneklerini de içerir. 39 µs’den fazla bekle.
  4. Display Clear” ayarını yap. 1.53 ms’den fazla bekle.
  5. Entry Mode Set” ayarını yap. 39 µs’den fazla bekle.
  6. Write Data to RAM“, karakter bas. 43 µs’den fazla bekle.
  • Ekranın desteklediği diğer seçenekler için yazıda paylaştığım kulanım yönergesini inceleyebilirsiniz.

Yukarıdaki bilgilerden sonra bir de kodun çalıştığını gösteren resimlerini ekleyelim. Cep telefonunun kamerası ile çekildiği için çok şahane sayılmaz ama yine de anlaşılır durumda.

Ve son olarak da VHDL kodu. Zamanlamalar 100 MHz işarete göre hesaplanmıştır.

----------------------------------------------------------------------------------
-- Company: www.muuzoo.gen.tr
-- Engineer: Mehmet Muzaffer KOSTEN
--
-- Create Date:    02:27:34 01/07/2010
-- Design Name: 2x16 LCD Ekran Calismasi
-- Module Name:    lcd_216_kabuk - Behavioral
-- Project Name:
-- Target Devices: ML506 Gelistirme Karti
-- Tool versions: ISE 11.3
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity lcd_216_kabuk is
	generic(
		init_d  : integer  :=  4000000;  --40 ms gecikme
		com_dl  : integer  :=  200000;  --2  ms gecikme
	        com_ds  : integer  :=  5000);  --50 us gecikme
	port(
                USER_CLK        : in      std_logic;
                LCD_FPGA_DB	: inout   unsigned(3 downto 0);
                LCD_FPGA_E	: out	  std_logic;
                LCD_FPGA_RS	: out	  std_logic;
		LCD_FPGA_RW	: out	  std_logic);
end lcd_216_kabuk;
 
architecture Behavioral of lcd_216_kabuk is
 
type tip_mesaj is array (0 to 12) of unsigned(7 downto 0);
 
constant mesaj : tip_mesaj :=((X"6D"),(X"75"),(X"75"),(X"7a"),(X"6f"),
                              (X"6f"),(X"2e"),(X"67"),(X"65"),(X"6e"),
                              (X"2e"),(X"74"),(X"72"));
 
signal  lcd  :  unsigned(6 downto 0):="1111111";
 
begin
 
LCD_FPGA_DB	<=	lcd(3 downto 0);
LCD_FPGA_E	<=	lcd(6);
LCD_FPGA_RS	<=	lcd(5);
LCD_FPGA_RW	<=	lcd(4);
 
process(USER_CLK)
variable	adim	:	integer range 0 to 23		:=	0;
variable	sayac	:	integer range 0 to 4194303	:=	0;
variable	i	:	integer range 0 to 12		:=	0;
  begin
    if(rising_edge(USER_CLK))	then
       sayac:=sayac+1;
       case	adim	is
---------------Acilis Gecikmesi, 40 ms -----------------------------
		when	0	=>	if (sayac=init_d)	then
						sayac	:=	0;
						adim	:=	1;
					end if;
---------------Acilis Ayarlari, 2x16 biciminde calis----------------
		when	1	=>	lcd <= "1000010";
					if (sayac=com_ds/20) then
						sayac	:=	0;
						adim	:=	2;
					end if;
		when	2	=>	lcd <= "0000010";
					if (sayac=com_ds/20) then
						adim	:=	3;
					end if;
		when	3	=>	lcd <= "1000010";
					if (sayac=com_ds/10) then
						adim	:=	4;
					end if;
		when	4	=>	lcd <= "0000010";
					if (sayac=3*com_ds/20) then
						adim	:=	5;
					end if;
		when	5	=>	lcd <= "1001000";
					if (sayac=com_ds/5) then
						adim	:=	6;
					end if;
		when	6	=>	lcd <= "0000010";
					if (sayac=com_ds) then
						adim	:=	7;
						sayac	:=	0;
					end if;
---------------Ekrani Acma, Imlec ayarlari, Yanip/sonme---------------
		when	7	=>	lcd <= "1000000";
					if (sayac=com_ds/20) then
						adim	:=	8;
					end if;
		when	8	=>	lcd <= "0000000";
					if (sayac=com_ds/10) then
						adim	:=	9;
					end if;
		when	9	=>	lcd <= "1001111";
					if (sayac=3*com_ds/20) then
						adim	:=	10;
					end if;
		when	10	=>	lcd <= "0001111";
					if (sayac=com_ds) then
						adim	:=	11;
						sayac	:=	0;
					end if;
---------------Ekrani Temizle, Baslangic Adresine Git-----------------
		when	11	=>	lcd <= "1000000";
					if (sayac=com_dl/800) then
						adim	:=	12;
					end if;
		when	12	=>	lcd <= "0000000";
					if (sayac=com_ds/400) then
						adim	:=	13;
					end if;
		when	13	=>	lcd <= "1000001";
					if (sayac=3*com_dl/800) then
						adim	:=	14;
					end if;
		when	14	=>	lcd <= "0000001";
					if (sayac=com_dl) then
						adim	:=	15;
						sayac	:=	0;
					end if;
---------------Adresleme Ayarlari Adres Arttirici---------------------
		when	15	=>	lcd <= "1000000";
					if (sayac=com_ds/20) then
						adim	:=	16;
						end if;
		when	16	=>	lcd <= "0000000";
					if (sayac=com_ds/10) then
						adim	:=	17;
					end if;
		when	17	=>	lcd <= "1000110";
					if (sayac=3*com_ds/20) then
						adim	:=	18;
					end if;
		when	18	=>	lcd <= "0000110";
					if (sayac=com_ds) then
						adim	:=	19;
						sayac	:=	0;
					end if;
---------------Ekrana Karakter Basma slemi--------------------------
		when	19	=>	lcd <= "110"&mesaj(i)(7 downto 4);
					if (sayac=com_ds/20) then
						adim	:=	20;
					end if;
		when	20	=>	lcd <= "010"&mesaj(i)(7 downto 4);
					if (sayac=com_ds/10) then
						adim	:=	21;
					end if;
		when	21	=>	lcd <= "110"&mesaj(i)(3 downto 0);
					if (sayac=3*com_ds/20) then
						adim	:=	22;
					end if;
		when	22	=>	lcd <= "010"&mesaj(i)(3 downto 0);
					if (sayac=com_ds) then
						adim	:=	23;
					end if;
		when	23	=>	if (i<12) then
						i:=i+1;
						adim	:=	19;
					else
						adim	:=	23;
					end if;
       end case;
    end if;
end process;
end Behavioral;

2 thoughts on “Xilinx ML506 16×2 LCD Çalışma

  1. FxDev dedi ki:

    Bence bu tür işleri FPGA’in içine gömülebilecek mikroişlemcilerle yapmak en iyisi.
    Zaten yer oldukça fazla olduğundan bir sorun teşkil edeceğini de sanmam. Böylelikle paralel çalışmanın nimetlerinden de faydalanmış oluruz.
    Xilinx için Picoblaze hoş bence 😉

  2. muuzoo dedi ki:

    Aslına bakarsanız haklısınız biraz zorlama bir çalışma 🙂 .Bu tarz işlemler için mikroişlemci kullanmak en mantıklısı. Bu çalışma aslında bir arkadaşın sorusu üzerine yapıldı. Ve yine bir arkadaşın çalışmasında hata ayıklama işlemi için kullanıldı.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir