4 Satır LCD Kütüphanesi Hk. ?

Başlatan Nedenler, 28 Şubat 2011, 15:25:55

Nedenler

Kolay gelsin arkadaşlar daha önce Basic ile çalışıyordum yeni yeni CCS C ile pic yazmaya başladım burada lcd ile ilgili bir soru sormak istiyorum. ISISde ki 4x20 lcdler ile çalışıyorum elimde derleyicinin lcd.c 4 satır lcdler için lcd420.c ve aşağıda ki kütüphane dosyaları mevcut. Fakat 4 satırlık lcd'ye veri göndermeye çalıştığımda 2. ve 4. satırlarda hiç işlem yapmıyor. Yani sadece 2 satır yazıyor. Mesela aşağıda ki kütüphane dosyasında 0x28 komutu LCD'ye 2 satır çalışacağını söylüyor 4 satır kullanmak için komut nedir acaba yada ne yapmam gerekir ?

Kütüphane dosyası (2 satır için)
//////////////////////////////////////////////////////////////
//                    benim_LCD.c                           // 
// Bu LCD sürücü dosyası 2x16 HD44780 uyumlu LCD'ler        //
// için yazılmıştır. LCD'ye sadece yazma yapılacağı için    //
// R/W ucu şaseye bağlanmalıdır. LCD bağlantısı aşağıdadır. //
//////////////////////////////////////////////////////////////
// RB0 -> LCD'nin D4 ucuna
// RB1 -> LCD'nin D5 ucuna
// RB2 -> LCD'nin D6 ucuna
// RB3 -> LCD'nin D7 ucuna
// RB4 -> LCD'nin RS ucuna
// RB5 -> LCD'nin E  ucuna
// R/W ucu direkt şaseye bağlanacak

#define e   pin_b5 // LCD'nin E ucu RB5 pinine bağlı
#define rs  pin_b4 // LCD'nin RS ucu RB4 pinine bağlı

//****** LCD'ye Komut Gönderme Fonksiyonu **********
void lcd_komut(byte komut)
{   
   output_b(komut>>4);   // Komutun yüksek değerli 4 bitini gönder
   output_low(rs);       // LCD komut almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle   
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor

   output_b(komut&0x0F); // Komutun düşük değerli 4 bitini gönder
   output_low(rs);      // LCD veri almak için ayarlandı  
   delay_cycles(1);      // 1 komut saykılı bekle      
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor
}

//******* LCD'ye Veri Gönderme Fonksiyonu **********
void lcd_veri(byte veri)
{ 
   output_b(veri>>4);    // Verinin yüksek değerli 4 bitini gönder
   output_high(rs);      // LCD veri almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle    
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor

   output_b(veri&0x0F); // Verinin düşük değerli 4 bitini gönder
   output_high(rs);      // LCD veri almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle    
   output_high(e);      // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);     // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);         // 2 msn gecikme veriliyor
}

//******* LCD'de İmlec Konumlandırma Fonksiyonu ********
void imlec(byte satir, byte sutun)
{
   if (satir==1)      // Eğer satır değişkeni "1" ise
      lcd_komut(0x80|(sutun-1));

   if (satir==2)      // Eğer satır değişkeni "2" ise
      lcd_komut(0x80|(0x40+(sutun-1)));
}

//********* LCD Başlangıç Ayarları Fonksiyonu ******
void lcd_hazirla()
{
   int i=0;
   output_low(rs); // RS ucu lojik-0
   output_low(e);  // E ucu lojik-0
   delay_ms(30);   // LCD enerjlendiğinde LCD'nin hazır olması için beklenen süre
   
   for(i=0;i<=3;i++)    // LCD'ye 3 kez 0x03 komutu gönderiliyor
   {
      lcd_komut(0x03);
      delay_ms(5);      // 5msn gecikme veriliyor
   }
   lcd_komut(0x02); // LCD'ye 4 bit iletişim komutu gönderiliyor
   lcd_komut(0x28); // 4 bit iletişim, 2 satır, 5x8 dot matris seçildi
   lcd_komut(0x08); // Display Kapalı
   lcd_komut(0x0C); // Display açık,imleç alt çizgi ve yanıp sönme yok
   lcd_komut(0x06); // Her veri yazıldığında imleç bir sağa gitsin
   lcd_komut(0x01); // Display sil. İmleç 1.satır 1.sütunda
}

RcALTIN

Şurada verdiğim sürücüyü bir inceleyin...
KİMSEYİ ENGELLEDİĞİM YOK, ÖZEL İLETİ DEVRE DIŞI !

Nedenler

#2
Evet sorun çözülmüştür çok teşekkür ederim dediğim gibi CCS C de yeni yeni yazıyorum bastım printfleri altalta \n'i de koydum sanıyorumki alt satıra geçecek :) imlecin yerini söylemiyorum halbuki şu an elimde çalışan 2 kütüphane oldu teşekkür ederim tekrar :)

Kullandığım diğer kütüphane dosyasını da vereyim arkadaşlara lazım olur. Aşağıda ki kodlar Serdar Çiçek'in CCS C ile PIC Programlama kitabından alınıp değiştirilmiştir. 
Evet sorun çözülmüştür çok teşekkür ederim dediğim gibi CCS C de yeni yeni yazıyorum bastım printfleri altalta \n'i de koydum sanıyorumki alt satıra geçecek :) imlecin yerini söylemiyorum halbuki şu an elimde çalışan 2 kütüphane oldu teşekkür ederim tekrar :) 

Kullandığım diğer kütüphane dosyasını da vereyim arkadaşlara lazım olur. [i]Aşağıda ki kodlar Serdar Çiçek'in CCS C ile PIC Programlama kitabından alınıp değiştirilmiştir.  [/i]
[code]
//////////////////////////////////////////////////////////////////////////////
//                    benim_LCD.c                                                     // 
// Bu LCD sürücü dosyası 4x20 LCD'ler                                   //
// için yazılmıştır. LCD'ye sadece yazma yapılacağı için           //
// R/W ucu şaseye bağlanmalıdır. LCD bağlantısı aşağıdadır. //
/////////////////////////////////////////////////////////////////////////////
// RD0 -> LCD'nin D4 ucuna
// RD1 -> LCD'nin D5 ucuna
// RD2 -> LCD'nin D6 ucuna
// RD3 -> LCD'nin D7 ucuna
// RD4 -> LCD'nin RS ucuna
// RD5 -> LCD'nin E  ucuna
// R/W ucu direkt şaseye bağlanacak

#define e   pin_d5 // LCD'nin E ucu RB5 pinine bağlı
#define rs  pin_d4 // LCD'nin RS ucu RB4 pinine bağlı

//****** LCD'ye Komut Gönderme Fonksiyonu **********
void lcd_komut(byte komut)
{   
   output_d(komut>>4);   // Komutun yüksek değerli 4 bitini gönder
   output_low(rs);       // LCD komut almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle   
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor

   output_d(komut&0x0F); // Komutun düşük değerli 4 bitini gönder
   output_low(rs);      // LCD veri almak için ayarlandı  
   delay_cycles(1);      // 1 komut saykılı bekle      
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor
}

//******* LCD'ye Veri Gönderme Fonksiyonu **********
void lcd_veri(byte veri)
{ 
   output_d(veri>>4);    // Verinin yüksek değerli 4 bitini gönder
   output_high(rs);      // LCD veri almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle    
   output_high(e);       // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);      // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);          // 2 msn gecikme veriliyor

   output_d(veri&0x0F); // Verinin düşük değerli 4 bitini gönder
   output_high(rs);      // LCD veri almak için ayarlandı
   delay_cycles(1);      // 1 komut saykılı bekle    
   output_high(e);      // E ucu lojik-1'den lojik-0'a çekiliyor
   delay_cycles(1);     // 1 komut saykılı bekle
   output_low(e);
   delay_ms(2);         // 2 msn gecikme veriliyor
}

//******* LCD'de İmlec Konumlandırma Fonksiyonu ********
void imlec(byte satir, byte sutun)
{
   if (satir==1)      // Eğer satır değişkeni "1" ise
      lcd_komut(0x80|(sutun-1));

   if (satir==2)      // Eğer satır değişkeni "2" ise
      lcd_komut(0x80|(0x40+(sutun-1)));
      
   if (satir==3)
      lcd_komut(0x80|(0x14+(sutun-1)));
      
   if (satir==4)
      lcd_komut(0x80|(0x54+(sutun-1)));
}

//********* LCD Başlangıç Ayarları Fonksiyonu ******
void lcd_hazirla()
{
   int i=0;
   output_low(rs); // RS ucu lojik-0
   output_low(e);  // E ucu lojik-0
   delay_ms(30);   // LCD enerjlendiğinde LCD'nin hazır olması için beklenen süre
   
   for(i=0;i<=3;i++)    // LCD'ye 3 kez 0x03 komutu gönderiliyor
   {
      lcd_komut(0x03);
      delay_ms(5);      // 5msn gecikme veriliyor
   }
   lcd_komut(0x02); // LCD'ye 4 bit iletişim komutu gönderiliyor
   lcd_komut(0x28); // 4 bit iletişim, 2 satır, 5x8 dot matris seçildi
   lcd_komut(0x08); // Display Kapalı
   lcd_komut(0x0C); // Display açık,imleç alt çizgi ve yanıp sönme yok
   lcd_komut(0x06); // Her veri yazıldığında imleç bir sağa gitsin
   lcd_komut(0x01); // Display sil. İmleç 1.satır 1.sütunda
}

[/code]

omereliusuk

#3
serdar çiçekten değiştirerek alınmıştır.

//******* LCD'de İmlec Konumlandırma Fonksiyonu ********
void imlec(byte satir, byte sutun)
{
      if (satir==1)      // Eğer satır değişkeni "1" ise
            lcd_komut(0x80|(sutun-1));
      if (satir==2)      // Eğer satır değişkeni "2" ise
            lcd_komut(0xc0+(sutun-1));
   if (satir==3)      // Eğer satır değişkeni "3" ise
            lcd_komut(0x94+(sutun-1));
   if (satir==4)      // Eğer satır değişkeni "4" ise
            lcd_komut(0xd4+(sutun-1));
}
bu da benim_lcd nin düzenlenmiş hali...:)

Nedenler

#4
Arkadaşlar yine bir sorun yaşadım. CCS C driveri dosyaları içinde ki LCD kütüphanesini Serdar Çiçek'in kitabında ki örnekle harmanlayarak yeni bir kütüphane dosyası oluşturdum. Proteusda sorunsuz çalışmakta. Fakat devrede uyguladığımda şu şekilde oluyor;

printf(lcd_veri,"Bu sayı %d dir.",sayi);   // Sorun yok çalışıyor.


lcd_veri("Deneme Deneme");                 // Sorun yok çalışıyor.


printf(lcd_veri,"Bu sayı %ddir       ",sayi);   // dir den sonra 5-6 boşluk bıraktım burada lcd saçmalıyor.


Üçüncü verdiğim kod satırında son yazdığım harfden sonra x kadar boşluk bırakıyorum lcd bu komutu gördüğü anda ekrana rastgele karakterler basmaya başlıyor ekranın tamamı yanıp sönüyor rastgele karakterler gösteriyor. Bu boşluğu bırakmamın sebebi de şu; bu sayı %ddir diyorum. Ekrana bu sayı 3dir yazıyor. Daha sonra sayı negatif olduysa başına - koyduğu için ekran çıktısı "bu sayi -2dirr" oluyor. Bilmem anlatabildim mi.

Kütüphane dosyası;
#define rs pin_d4
#define e  pin_d5

BYTE lcd_satir=1;

void lcd_komut(byte komut)
{
   //output_low(rs);
   output_d(komut>>4);
   output_low(rs);
   delay_cycles(1);
   output_high(e);
   delay_cycles(1);
   output_low(e);
   delay_ms(2);
   
   output_d(komut&0x0F);
   output_low(rs);
   delay_cycles(1);
   output_high(e);
   delay_cycles(1);
   output_low(e);
   delay_ms(2);
}


void lcd_imlec(byte satir, byte sutun)
{
   switch(satir)
   {
      case 1: lcd_komut(0x80+sutun-1);   break;
      case 2: lcd_komut(0xc0+(sutun-1)); break;
      case 3: lcd_komut(0x94+(sutun-1)); break;
      case 4: lcd_komut(0xd4+(sutun-1)); break;
   }
   
}

void lcd_gonder (char veri)
{   
   output_d(veri>>4);
   output_high(rs);
   delay_cycles(1);
   output_high(e);
   delay_cycles(1);
   output_low(e);
   delay_ms(2);
   
   output_d(veri&0x0F);
   output_high(rs);
   delay_cycles(1);
   output_high(e);
   delay_cycles(1);
   output_low(e);
   delay_ms(2);
}

void lcd_veri(char c)
{
   switch (c)
   {
      case '\f': lcd_komut(0x01);
                 lcd_satir=1;
                 delay_ms(2); break;
                 
      case '\n': lcd_imlec(++lcd_satir,1); break;
                 
      default  : lcd_gonder(c);   break;
   }
}   

void lcd_hazirla()
{
   int i;
   output_low(rs);
   output_low(e);
   delay_ms(30);
   
   for (i=0;i<4;i++)
   {
      lcd_komut(0x03);
      delay_ms(5);
   }
   
   lcd_komut(0x02);
   lcd_komut(0x28);
   lcd_komut(0x08);
   lcd_komut(0x0C);
   lcd_komut(0x06);
   lcd_komut(0x01);
}


Ayrıca 0x01 ekranı temizleme komutundada sapıtıyor. Kullandığım LCD PCM2004D ve S6A0069 sürücüsünü kullanıyor.

Düzenleme: Kodlarda hiçbir sorun yok gıcır gıcır çalışıyorlarmış sorun devrenin karışıklığından, kirliliğinden kaynaklanıyormuş. Devreyi başka bir kart üzerinde yeniden oluşturunca sorunsuz çalıştı. İşine yarayacak arkadaşlara duyrulur.