FPGA ile (Sahada Programlanabilir Mantık Dizeleri) gerçekleştirilen uygulamalar günden güne giderek çeşitlenmektedir. FPGA’ların üstünlükleri/eksiklikleri, ile mikroDenetleyicilerin, ASIC’lerin(Uygulama Odaklı Entegre Devre) ve ASSP’lerin(Uygulama Odaklı Standart Ürün) kıyaslanması başlı başına bir makale konusudur. Biz burada buna değinmeyeceğiz.

Örnek uygulamamızda; FPGA çipi olarak ALTERA Firmasının Cyclone IV ailesinden EP4CE6E22C8 model bir FPGA ve HD44780 çipli 2x16LCD kullandık. Bu FPGA çipinin gelişmiş özellikleri için modelin datasheet’i(bilgiSayfası) incelenmelidir. Ama kabaca olarak kullandığımız FPGA çipi; 6272 Lojik Elementli, 270Kbit Gömülü Hafızası, 91 adet I/O (Giriş/Çıkış) Pini bulunan, 144 ayaklı bir çiptir.

ALTERA firmasının üretmiş olduğu FPGA’ları programlayabilmek için, “Quartus” Derleyicisini kullanıyoruz. Quartus Derleyicisinin kurumsal internet sitesinden indirdiğimiz “Demo” versiyonu ile bu örnek uygulamayı gerçekleştirdik. 6272 lojik elementten sadece 74 tanesini kullandığımız için demo limitine takılmadık.

FPGA’ları programlayabilmek için yaygın olarak kullanılan iki dil; VDHL ve Verilog içerisinden, “C” söz dizimine daha yakın geldiği için “Verilog” ile programlamayı tercih ettik.

FPGA ve LCD arasındaki Pin Bağlantıları :

fpgaLCDpinbag

Çıkış Pinleri
PIN_85 >> rs
PIN_99 >> rw
PIN_100 >> en
PIN_101 >> veri[0]
PIN_103 >> veri[1]
PIN_104 >> veri[2]
PIN_105 >> veri[3]
PIN_106 >> veri[4]
PIN_110 >> veri[5]
PIN_111 >> veri[6]
PIN_112 >> veri[7]
Giriş Pinleri
PIN_23 << saatDarbesi

HD44780 LCD Karakter Kodları :
Örnek uygulamamızda, mikroDenetleyici uygulamalarındaki gibi hazır bir kütüphane kodu kullanmadığımız için; Karakter ve Komut kodlarına ihtiyaç duyduk. HD44780 çipli LCD’lerde kullanılan karakter kodları için aşağıdaki tablo incelenmelidir.

lcdKarakterKodlari

HD44780 çipli LCD’lerde kullanılan kontrol komutları için ise internette oldukça fazla kaynak bulunmaktadır ayrıca HD44780 çipli LCD datasheet’i(bilgiSayfası) incelenebilir.
Örnek Uygulamanın RTL* Diagramı :

*RTL : Register Transfer Level (Kaydedici İletim Seviyesi Gösterimi)

lcd1602rtl

Program Kodu :

/*******************************************************************************
* @dosya LCD Uygulaması
* @yazar Erkan ÇİL
* @sürüm V0.0.1
* @tarih 07-Temmuz-2016
* @özet Cyclone IV EP4CE6 FPGA 2x16 LCD Karakter Uygulaması
*
* Bu örnek uygulamada, Cyclone IV EP4CE6 FPGA kartını ile 16x2 LCD kullanılarak
* yazı karakterleri gösterilecektir. Hitachi HD44780 sürücüsü kullanılan
* her LCD için uyumlu olarak çalışacaktır.
******************************************************************************
*
* Bu program özgür yazılımdır: Özgür Yazılım Vakfı tarafından yayımlanan GNU
* Genel Kamu Lisansı’nın sürüm 3 ya da (isteğinize bağlı olarak) daha sonraki
* sürümlerinin hükümleri altında yeniden dağıtabilir ve/veya değiştirebilirsiniz.
*
******************************************************************************/
module lcd1602(saatDarbesi, rs, rw, en,veri); //lcd1602 MODÜLÜ TANIMI
//-------------Giriş Portları-----------------------------
input saatDarbesi;
//-------------Çıkış Portları----------------------------
output [7:0] veri; //data pinleri
output rs,rw,en; //Register Select, Read Write, Enable Pinleri
//tri en;
//-------------Çıkış Portları Veri Tipleri------------------
// Çıkış portları bellek elemanı(reg-yazmaç) veya bir tel olabilir
reg e;
reg [7:0] veri;
reg rs;
reg [15:0] sayici;
reg [6:0] simdiki,sonraki;
reg saatDarbesiKayit;
reg [1:0] cnt;
//-------------Parametre Tanımlamaları----------------------------
parameter set0=4'h00;
parameter set1=4'h01;
parameter set2=4'h02;
parameter set3=4'h03;
parameter veri0=4'h04;
parameter veri1=4'h05;
parameter veri2=4'h06;
parameter veri3=4'h07;
parameter veri4=4'h08;
parameter veri5=4'h09;
parameter veri6=4'h0A;
parameter veri7=4'h0B;
parameter veri8=4'h0C;
parameter veri9=4'h0D;
parameter veri10=4'h0E;
parameter veri11=5'h10;
parameter veri12=5'h11;
parameter veri13=5'h12;
parameter veri14=5'h13;
parameter veri15=5'h14;
parameter set4=5'h15;
parameter veri16=5'h16;
parameter veri17=5'h17;
parameter veri18=5'h18;
parameter veri19=5'h19;
parameter veri20=6'h20;
parameter veri21=6'h21;
parameter veri22=6'h22;
parameter veri23=6'h23;
parameter veri24=6'h24;
parameter veri25=6'h25;
parameter veri26=6'h26;
parameter veri27=6'h27;
parameter veri28=6'h28;
parameter veri29=6'h29;
parameter veri30=6'h2A;
parameter veri31=6'h2B;
parameter nul=4'hF;
//------------Kod Burada Başlamaktadır-------------------------
// Bu sayaç yükselen kenar tetiklemeli olduğundan,
// Bu bloğu saatin
// yükselen kenara göre tetikleyeceğiz.
always @(posedge saatDarbesi)
begin
sayici=sayici+1;
if(sayici==16'h000f)
saatDarbesiKayit=~saatDarbesiKayit;
end
always @(posedge saatDarbesiKayit)
begin
simdiki=sonraki;
case(simdiki)
set0: begin rs<=0; veri<=8'h38; sonraki<=set1; end // LCD 1 satır 2 satır ayarı !!!
set1: begin rs<=0; veri<=8'h0c; sonraki<=set2; end // LCD yi aç
set2: begin rs<=0; veri<=8'h06; sonraki<=set3; end // LCD imleç artan mod
set3: begin rs<=0; veri<=8'h01; sonraki<=veri0; end // LCD yi temizle
veri0: begin rs<=1; veri<=8'h3C; sonraki<=veri1; end
veri1: begin rs<=1; veri<="m"; sonraki<=veri2; end
veri2: begin rs<=1; veri<="c"; sonraki<=veri3; end
veri3: begin rs<=1; veri<="u"; sonraki<=veri4; end
veri4: begin rs<=1; veri<="-"; sonraki<=veri5; end
veri5: begin rs<=1; veri<="t"; sonraki<=veri6; end
veri6: begin rs<=1; veri<="u"; sonraki<=veri7; end
veri7: begin rs<=1; veri<="r"; sonraki<=veri8; end
veri8: begin rs<=1; veri<="k"; sonraki<=veri9; end
veri9: begin rs<=1; veri<="e"; sonraki<=veri10; end
veri10: begin rs<=1; veri<="y"; sonraki<=veri11; end
veri11: begin rs<=1; veri<="."; sonraki<=veri12; end
veri12: begin rs<=1; veri<="c"; sonraki<=veri13; end
veri13: begin rs<=1; veri<="o"; sonraki<=veri14; end
veri14: begin rs<=1; veri<="m"; sonraki<=veri15; end
veri15: begin rs<=1; veri<=8'h3E; sonraki<=set4; end
set4: begin rs<=0; veri<=8'hC0; sonraki<=veri16; end // LCD yi 2. satıra geçir
veri16: begin rs<=1; veri<=8'h7E; sonraki<=veri17; end
veri17: begin rs<=1; veri<="m"; sonraki<=veri18; end
veri18: begin rs<=1; veri<="e"; sonraki<=veri19; end
veri19: begin rs<=1; veri<="r"; sonraki<=veri20; end
veri20: begin rs<=1; veri<="h"; sonraki<=veri21; end
veri21: begin rs<=1; veri<="a"; sonraki<=veri22; end
veri22: begin rs<=1; veri<="b"; sonraki<=veri23; end
veri23: begin rs<=1; veri<="a"; sonraki<=veri24; end
veri24: begin rs<=1; veri<=" "; sonraki<=veri25; end
veri25: begin rs<=1; veri<=" "; sonraki<=veri26; end
veri26: begin rs<=1; veri<="d"; sonraki<=veri27; end
veri27: begin rs<=1; veri<="u"; sonraki<=veri28; end
veri28: begin rs<=1; veri<="n"; sonraki<=veri29; end
veri29: begin rs<=1; veri<="y"; sonraki<=veri30; end
veri30: begin rs<=1; veri<="a"; sonraki<=veri31; end
veri31: begin rs<=1; veri<=8'h7F; sonraki<=nul; end
nul: begin rs<=0; veri<=8'h00; //null durum tanımı
if(cnt!=2'h2)
begin
e<=0;
sonraki<=set0;
cnt<=cnt+1;
end
else
begin
sonraki<=nul;
e<=1;
end
end
default: sonraki=set0;
endcase
end
assign en=saatDarbesiKayit|e;
assign rw=0;
endmodule // LCD1602 modülünün sonu

Örnek Uygulamanın Görseli :

Jpeg

FPGA ile 2x16 LCD Uygulaması

Makalenin PDF Dökümanı :

İndir (PDF, 1011KB)