2×16 LCD’ler için esnek sürücü programı

lcd

lcd

LCD Display’in Çalışma Prensibi:

LCD ekrana iki farklı veri gönderilir. Bunlar normal veri (1, 2, 4, A, B, K… gibi) diğeri ise komuttur. LCD kendisine gelen verinin komut veya normal veri olduğunu anlayamaz. Bunun için veri LCD ekrana gönderildiğinde bu verinin komut veya normal veri olduğunu belirtilmelidir. LCD ekrana gönderilen veri komut ise LCD ekranın 4. biti (RS sinyali) programlayıcı tarafından 0 (sıfır- pasif) yapılır. Eğer LCD Ekrana gönderilen veri normal veri ise LCD ekranın 4. biti (RS sinyali) programlayıcı tarafından 1 (bir- aktif) yapılır. LCD kendisine gelen veriyi alması için veri gönderildikten sonra LCD ekranın 6. bitini (Aktif Sinyal-E) tetiklemek gereklidir. Aksi takdirde LCD veriyi almaz ve ekranda hiçbir şey görünmez. Örneğin; LCD ekranın temizlenmesi isteniyorsa o zaman LCD ekranına “01h” sayısını komut olarak göndermek gerekir. Bunun için ilk önce LCD ekranın 4. biti pasif yapılır ve LCD ,PIC mikro denetleyicisinin hangi portuna bağlanmışsa o porttan bu veri (komut-01h) gönderilir ve LCD’nin 6. biti tetiklenir (yani aktif yapılır) ve ardından LCD’nin 6. biti tekrar pasif duruma getirilir. Böylelikle LCD ekrana bir komut gönderilmiş olur. Aynı işlemler normal veri gönderilirken de yapılır. Yalnız normal veri gönderilirken LCD ekranın 4. biti aktif yapılmalıdır.
2×16 lcd’ler için ccs’nin içerisinde hazır olarak driver yer almaktadır fakat kendi driver’ında ya B portunu yada D portunu bu iş için feda etmemiz gerekiyordu. Burada yer alan esnek driver sayesinde artık yaptığınız tasarımda lcd’nin istenilen bacağını pic’e istediğiniz yerden bağlayabileceksiniz. Aşaığıdaki kodları flexy_lcd.c dosyası olarak kaydedip drivers klasörüne atınız.

// flex_lcd.c yazan:PCM Programmer
// Aşağıdaki pinleri istediğiniz
// gibi devrenize göre değiştirebilirsiniz
#define LCD_DB4 PIN_D0
#define LCD_DB5 PIN_D1
#define LCD_DB6 PIN_D2
#define LCD_DB7 PIN_D3

#define LCD_E PIN_A1
#define LCD_RS PIN_A3
#define LCD_RW PIN_A2
//LCDyi sadece 6 pin ile kullanacaksanız
// R/W pinini şaseye bağlayınız ve
// aşağıdaki satırı siliniz yada devre dışına alınız
#define USE_LCD_RW 1

//========================================

#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 satır bildirimleri
#define lcd_line_two 0x40 // 2. satırın LCD RAM adresi
int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // LCD fonksiyonları: 4-bit, 2 satır, 5x8 nokta
 0xc, // Display on
 1, // Ekran temizle
 6 // kursorü artır
 };

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
//onluk sayıyı ikilik sayı sistemine çevirme
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
//LCD'den byte bilgi okunur.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
//LCD'ye byte bilgi gönderilir.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
 output_high(LCD_RS);
else
 output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
 {
 lcd_send_nibble(0x03);
 delay_ms(5);
 }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
 {
 lcd_send_byte(0, LCD_INIT_STRING[i]);

#ifndef USE_LCD_RW
 delay_ms(5);
 #endif
 }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
 address = lcd_line_two;
else
 address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
 {
 case '\f':
 lcd_send_byte(0,1);
 delay_ms(2);
 break;

 case '\n':
 lcd_gotoxy(1,2);
 break;

 case '\b':
 lcd_send_byte(0,0x10);
 break;

 default:
 lcd_send_byte(1,c);
 break;
 }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif

Bu sürücü için örnek lcd kullanım programı

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

#include "flex_lcd.c"

//==========================
void main()
{
lcd_init(); // lcd kullanılmadan önce bu komut
            // işletilmeli yoksa lcd çalışmaz
lcd_putc("\fMErhaba Dunya\n");
lcd_putc("Satir no 2");

while(1);
}

Bu yazı CCS C Sürücü kategorisine gönderilmiş ve , , , ile etiketlenmiş. Kalıcı bağlantıyı yer imlerinize ekleyin.