AVR-Grafik LCD Kullanımı

Grafik LCD Kullanımı

Biçerdöver tablasını ayarlanan yükseklikte sabit tutmakta kullanılan sistemi, eski bir model için kendim yapmaya karar verdim. Karakter LCD ile denemelerini yaptım ama görsel olarak tatmin olmadım. Grafik LCD ile daha iyi bir şey yaparım umuduyla araştırmalarıma başladım. Önceki yazılarımda da bahsettim bir amatör olarak öğrendiklerimi bir not defterine yazıp saklamaktansa benim gibi amatörler için ulaşılabilir bir kaynak olması açısında buraya yazıyorum.

Karakter LCD konusuna buradan ulaşabilirsiniz. Grafik LCD’nin farkı ekranın tamamının noktalardan (piksel) oluşması ve bizim bu noktalardan istediğimizi “1” ya da “0” yapabilmemizdir. Karakter LCD de kayıtlı olarak gelen ve 8 adet ile sınırlı oluşturulabilen harf, rakam ve şekiller dışında seçeneğimiz yoktur. Grafik LCD (GLCD) de ise çözünürlük elverdikçe sınırsız diyebiliriz. GLCD ekranların birbirinden farklı kontrolcü/sürücüleri mevcut. KS0108(S6B0108), ST7920 (SPI destekli) ve T6963C gibi ürünler mevcut, sanırım piyasada en çok bulacağınız KS0108 ve kopya ürünlerdir. Bu yazıda KS0108’i anlatmaya çalışacağım.

GLCD

İlk olarak GLCD pin isimleriyle başlayalım. Piyasada bulunan ekranların pin yerleşimi birbirinden farklıdır. Bu nedenle üreticinin bilgi sayfasını kontrol etmeniz gerekiyor. Üründe “1” ile gösterilen pinden başlayarak “20” ile gösterilen pine kadar görevleri aşağıdaki gibidir.

1-VDD (VCC): Pozitif besleme +5V.

2-VSS: Negatif besleme (GND).

3-VO: Ekran zıtlık ayarı, potansiyometrenin orta bacağı bu pine bağlanacak.

4,11- DB0,DB7: Paralel veri pinleri.

12- CS1: Bir numaralı ekran seçiminin yapıldığı pin.

13- CS2: İki numaralı ekran seçiminin yapıldığı pin.

14-RST: GLCD sıfırlama pini.

15-R/W: Okuma ya da Yazma seçiminin yapıldığı pin.

16-RS (D/I): Komut ya da Veri yollanması için gerekli seçimin yapıldığı pin. Register seçimi.

17-EN (E): İletişim için gerekli olan saat darbesinin gönderildiği pin.

18-VEE: Negatif voltaj çıkışı. Potansiyometrenin dış bacaklarından biri bu pine bağlanacak.

19- A(LED+): Arka aydınlatma Led artı pini.

20- K(LED-): Arka aydınlatma Led eksi pini.

KS0108 kullanan 128×64 piksel bir ekranda iki tane KS0108 bulunmaktadır. 128×64 aslında 64×64 iki ekrandan oluşur ve iki farklı sürücü tarafından yönetilir. CS0 ve CS1 numaralı pinler bu seçimi yapmamızı sağlar. Bu pinlerden hangisi “Low” ise o ekran veri alır-verir. İki ekranı aynı anda kontrol etmekte mümkündür.

Ekranlar 64 düşey sütun ve 8 yatay sayfadan oluşur. Her sayfada 8 piksel bulunur. Bu şekilde 64 yatay 64 düşey piksel oluşur. Ekranda bir “A” harfi yazmak istediğimizde öncelikle ekranı seçmeliyiz. Ekran seçimi yapıldıktan sonra sayfayı seçmeli ve gerekli veriyi göndermeliyiz. Şekilde görüldüğü gibi yazabilmemiz için göndereceğimiz veri ilk sütun için “0B 0111 1110” ya da “0x7E” ikinci sütun için “0B 0001 0001” ya da “0x11” olacaktır.

Bahsettiğim sayfa seçimleri ve benzeri işlemlerin nasıl yapılacağı bilgi sayfasında mevcut. Bu bilgilerden faydalanarak devam edelim. GLCD veri göndermek-almak ya da gerekli ayarlama ve seçimleri yapmak için RS ve R/W pinlerini kullanırız.

Satır, sütun seçimi ve ekran açma kapatma gibi komutları işlemek için RS ve RW “Low” olmalıdır. GLCD durum kontrolü için RS “Low” ve RW “High” olmalıdır. Veri gönderirken RS “High” RW “Low” veri okurken RS “High” ve RW “High” olmalıdır. Pin seçimleri bu şekilde yaptıktan sonra aşağıdaki tabloda diğer ayrıntıları görebiliriz.

Komutlar

Display on/off: Ekran açma/kapatma. GLCD ye bağlı data pinleri “0B 0011 1110” (0x3E) olursa/gönderirsek ekran kapanır. “0B 0011 1111” (0x3F) olursa ekran açılır.

Set Address: Y adresi olarak görünmekte ama ben x-y koordinat sistemi gibi düşünerek sütunlara “X” diyeceğim. 64 adet sütun olan ekranlardan hangi sütunu seçmek istediğimize bağlı olarak veriyi gönderiyoruz. İlk sütunun adresi (data pinleri) “0B 0100 0000” (0x40) ve sağa doğru sütun ilavesinde bir artırarak 63 numaralı sütuna ulaşabiliriz. Son sütunun adresi “0B 0111 1111” (0x7F). Gördüğünüz gibi işlemler ikili sayı sistemine göre yapılıyor. D7 ve D6 değişmeden “1” artırılıyor.

Set Page: Sayfa seçimi X adresi olarak görünmekte ama “Y” diyeceğim. Yukarıda belirttiğim 8 adet sayfanın seçimi için veriyi gönderiyoruz. İlk sayfa için (data pinleri) “0B 1011 1000” (0xB8) ve aşağı doğru son sayfa için “0B 1011 1111” (0xBF) olmalıdır.

Display Start Line: Ekranda üst sıradaki yerini ayarlar. Ekranı yukarı/aşağı kaydırabiliriz. İlk sayfanın DB0 numaralı pikselinin üstte olması için (data pinleri) “0B 1100 0000” (0xC0) son sayfanın DB7 numaralı pikseli için “0B 1111 1111” (0xFF) olmalıdır.

Status Read: GLCD veri alma/verme için uygun değilse, başka bir işlem ile meşgulse gönderdiğimz komutalara hatalı cevaplar verecektir. Bu nedenle uygunluk durumu, ekranın durumu ve reset durumu gibi verilerin okunduğu komuttur.

Write Display Data: Ekran, sayfa ve sütun seçimi yapıldıktan sonra RS “High” ve RW “Low” yapılarak ekrana veri gönderir ve pikselleri “1” ya da “0” yaparak istediğimiz görüntüyü oluşturabiliriz.

Read Display Data: Ekran, sayfa ve sütun seçimi yapıldıktan sonra RS “High” ve RW “High” yapılarak ekranda piksellerin “1” ya da “0” durumunu okuyabiliriz. Bu okuma piksel olarak yapacağımız işlemlerde gerekli olacaktır. Artık komutların ve pinlerin işlevine göre makroları ve fonksiyonları oluşturabiliriz.

Makrolar

Buraya kadar anlattığım işlemlerde bazı pinleri “1” High ya da “0” Low yapmak gerekiyor. Bunu kolayca tek komutla yapmak ve de hafızada fazladan yer kaplamadan yapmanın yolu ön tanımlı makrolardır. Ben uygulamayı Atmega32A ile yapıyorum farklı bir denetleyici için yani taşınabilir olması için Pin-Port tanımlarını değiştirmek yeterlidir. Port ve pinlerin giriş-çıkış durumlarını ve pinlerin 1-0 durumlarını tanımlıyorum. Bu tanımlardan sonra sıra fonksiyonlara geliyor.

Yazma Fonksiyonları

Yukarıdaki şemada GLCD yazma zaman çizelgesi bulunmaktadır. Veriyi yazmadan önce yapılması gerekenler görülmektedir. EN pininin high ve low olması yani bir dönem zamanı “tC” min 1ms olmalıdır. EN pini high olmadan “tASU” 140ns önce ekran seçimi yapılmalı, RS pini high ya da low ve RW low olmalıdır. E pini high olduktan sonra tekrar low olmadan “tDSU” 200ns önce data pinlerine veri yazılmalıdır. Bu işlemleri iki farklı fonksiyonda yapacağız. Bu fonksiyonlardan biri veri yazmak için diğeri komut yazmak için oluşturacağız. Bu arada önemli not GLCD de EN pini düşen kenarda veri yazılır, yükselen kenarda veri okunur.

Çizelgede görünen süreleri karşılamak için EN saat darbesi öncesi ekran seçimi ve register seçimi yapılıyor. Yazma yapılacağından RW low yapılarak data portuna istenen veriye göre pin durumu yazılıyor. Örneğin (0xF0) “0B 1111 0000” gibi bir veri yazmak istersek data portu 7-0 pinleri arası “11110000” şeklinde pinler “1” ya da “0” olacaktır. Böylece tASu ve tDSU süreleri karşılanacaktır. Sonrasında EN high-low yapılarak işlem tamamlanır.

Veri yazmada olduğu gibi komut yazmada da aynı işlemler yapılır. Aradaki fark RS pininin high-low durumu yani komut ya da veri seçimidir.

Okuma Fonksiyonları

Yazma için olduğu gibi okuma içinde zaman çizelgesinde yapılması gerekenler görülmektedir. RW high durumdayken RS low olduğunda durum okuması yapılırken RS high olduğunda GLCD veri okuması yapılır. Okuma yaparken “tD” 320ns süresi önemli bu nedenle önce EN high yapılmalı sonra data portu okunmalıdır.

Okuma fonksiyonu sadece piksel olarak işlem yaptığımızda gereklidir. Örnek olarak “0” numaralı satırda yukarıdan aşağıya doğru birer artarak (bir piksel) çizgi çizmek istersek göndereceğimiz veri sırasıyla {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80} olacaktır. Bu şekilde yazdığımızda kayan bir nokta görürüz. Amaca ulaşmak için ekranın tüm bilgisini tutacağımız bir bellek oluşturmak işlemi buna göre yapmak mümkündür. Sadece düşeyde iş gören önceki satırla şimdiki satır aynıysa daha önce gönderilen veriyi şimdikiyle “OR” işlemiyle yazmakta bir seçenek. (data=0x01|0x02; gibi) ben böyle bir işlemi çok uzun sürmediği için veri okumasıyla yapmayı tercih ettim. Süre çok önemliyse RAM de bellek içinde ekranın bir görüntüsünü oluşturmak mantıklı olacaktır. Önemli not okuma yaparken boş okuma sonra veri okuma doğru olacaktır. Durum okumasında buna gerek yoktur.

GLCD zaman çizelgesinde görülen fakat fonksiyonlarda belirtmediğimiz gerekli süreleri sağlamak gereksiz beklemeler yapmamak için bu fonksiyonu kullanmalıyız. Belirtilen süreler değişkenlik gösterebilmektedir. Bir komutta sorun olmazken çok sayıda ve arka arkaya komutlar gönderdiğimizde bu fonksiyon daha önemli olmaktadır. Buraya kadar ki fonksiyonlar kalan işlemlere temel oluşturacaktır.

Ana Fonksiyonlar

Başlatma fonksiyonu: İlk açılışta GLCD nin hazırlanması gerekir. Açılışta sıfırlamak, X-Y ve Z adreslerini başlangıca almak gerekiyor.

Ekran Seçimi: 64×64 iki ekrandan oluşan ve iki adet sürücü tarafından kontrol edilen GLCD de ekran seçimi CS1 ve CS2 pinleri ile yapılır. Seçili olan ekranı bilmek ve işlem yapmak için chip değişkenine yazıyoruz.

Satır ve Sütun Seçimi: Sütun “x” ve satır “y” seçimin yapıldığı fonksiyondur. Satırlar piksel olarak girilir sayfa olarak seçilir. 128 (0-127) sütun 64 (0-63) satır vardır. Fonksiyon parametreye göre sayfa ve ekran seçimini gerçekleştirir.

Ekran Silme: Ekrandaki görüntüyü silen fonksiyon, burada yapılan ekrana “0x00” yazmaktır. Bunu yaparken iki ekran birlikte seçiliyor. For döngüsüyle 8 sayfanın tamamında, her sayfanın içinde bulunan 64 sütuna “0x00” verisi yazılıyor.

Ekran Yazı, Grafik Fonksiyonları

Yukarıda anlatmaya çalıştığım fonksiyonları kullanarak çeşitli programlarla oluşturacağınız farklı fontlar ile harf ve rakamlar yazabilirsiniz. Şekiller çizebilir yine programlarla dönüştüreceğiniz fotoğrafları görüntüleyebilirsiniz. İlk olarak karakter LCD’ de kullanılan karakterleri ekrana yazmamızı sağlayan fonksiyonla başlayalım.

Yaz fonksiyonu: İnternetten bulacağınız ya da programlarla oluşturacağınız çok boyutlu karakter dizisi ile ASCII tablosundaki karakterleri yazdırabilirsiniz. { 0x7E, 0x11, 0x11, 0x11, 0x7E }, Büyük “A” harfi için veri bu şekildedir. LCD için oluşturulan karakterler 8 yatay, 5 dikey noktadan oluşur. Bildiğiniz gibi düşeyde her sütun bir bayt toplam 5 bayt bir karakter oluşturur. Çok boyutlu dizinin ilk karakteri 0x20 ile başlıyor, parametre olarak ‘A’ girdiğimizde _chr=0x41 (65) olarak fonksiyon işleyecektir. Tablodaki “_” yazılacaktır. Bunun olmaması için parametreden 0x20 (32) çıkartıyoruz böylece “A” yazmak istediğimizde _chr= 0x21(33) olarak işlem yapılacaktır. İki ekranın ortasında kalan karakterler için diğer ekrana geçiş yapılıyor ve ekranın sonunda kalan karakterleri bölmemek için alt satırdan devam ediyoruz.

Tabloda her karakteri 6 bayt veriden oluşturup 0x00 ile karakter arası boşluk ayarlayabilirdik ama gereksiz yer tutmamak için karakter bitişinde boşluk bırakıyoruz. Sütun otomatik olarak değiştiriliyor, bunun takibini yapmazsak diğer ekrana geçiş ve alt satıra geçiş gibi işlemleri yapmak için farklı algoritmalar yapmamız gerekir.

Dizi Fonksiyonu: Girilen diziyi tek karakter halinde dizi elemanı bitene kadar yazdırır. Str[i]= 0 (null) olunca döngüden çıkılır.

Piksel Fonksiyonu: Bu fonksiyon ile 64 yatay 128 düşey pikselin istenen bir tanesine 0x01 yazılır. Yukarıda değindiğim gibi bu işlemi yaparken 8 bitten oluşan sayfa verisini korumak için okuma yapılmaktadır. Ekran görüntüsünü oluşturup hafızada yer tutmamak için bu yöntemi kullanmaktayım. Parametre olarak (5,5) yazıldığında sütun 5 ile D5 satıra bir nokta yazılacaktır. Bunu yapabilmek için GLCD ye “0B 0010 0000” (0x10) yazmamız gerekir. Data verisini 8’ e böldüğümüzde kalan 5 olur ve 5 bit sola kaydırma yaparak istediğimiz sonucu buluruz. Okuma yaparak mevcut veriyi “OR” işlemiyle koruyarak işlemi tamamlarız.

Çizgi Fonksiyonu: Bresenham çizgi algoritması ile hızı ve düzgün sonuçlar alınabiliyor. Doğru denklemiyle denemelerim oldu ama çok düzgün sonuçlar alamadım. Bu algoritmada sürekli artan “x” ya da “y” durumuna göre hareket ediliyor. Çok fazla kaynak mevcut anlatma kısmını geçiyorum. Bu fonksiyon ile farklı fonksiyonlar türetilebilir.

Resim Fonksiyonu: Program aracılığıyla dönüştüreceğiniz fotoğraflı ekrana aktarabilirsiniz. Deneme çalışması aşağıdadır.

Bu yazı Haluk ŞİMŞEK tarafından yazılmıştır.

 

 

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.