16f877 ve 4*20 lcd 2. ve 4. satır sorun

Başlatan 3ddark, 18 Temmuz 2009, 23:10:08

3ddark

Yazıdığım kodda LCD için kendi programımı yazdım herşey güzel çalışıyor ama 2. ve 4. satırlara gidemiyorum sorun nedir acaba benmi birşeyleri yanlış yazdım anlamadım kaç saattır bak bak iyiçe gözlerim kaydı dogru olanlarıda silip artık deneme yanılmaya gideceğim sonunda.

4-bit modda kullanıyorum

HI-TECH C PRO for the PIC10/12/16 MCU family candidate build 4070 V9.60PL6
Derleyici bu ve 16f877 işlemci

lcd.c Dosyası burada

#include	<pic.h>
#include	"lcd.h"
#include	"delay.h"

void bf_test()
{
/*	unsigned char temp=0;
	RS = 0;		//Komut
	RW = 1;		//Okuma modunda
	LCD_DATA_TRIS = 0XFF;
	LCD_DATA = 0x00;
	EN = 1;
	NOP();
	EN = 0;
a:
	temp = LCD_DATA&0x80;
	if(temp=0x80)
		goto a;
	else
		LCD_DATA_TRIS = 0x00;
		LCD_DATA=0;
*/
	DelayMs(5);
}

void lcd_komut(unsigned char x)
{
#if DATA_MOD==8
	bf_test();
	RS = 0;	// komut
	RW = 0;	// write
	LCD_DATA = (x);
	EN = 1;
	NOP();
	EN = 0;
#endif

#if DATA_MOD==4
	bf_test();
	RS = 0;	// komut
	RW = 0;	// write
	LCD_DATA = ( x & 0xf0 );
	EN = 1;
	NOP();
	EN = 0;
	LCD_DATA = ( (x << 4) & 0xf0 );
	EN = 1;
	NOP();
	EN = 0;
#endif
}

void lcd_sil()
{	lcd_komut(0x01);	}

void lcd_puts(const unsigned char * s)
{
	while(*s)
		lcd_data(*s++);
}

void lcd_data(unsigned char c)
{
#if DATA_MOD==8
	bf_test();
	RS = 1;	// komut
	RW = 0;	// write
	LCD_DATA = (c);
	EN = 1;
	NOP();
	EN = 0;
#endif

#if DATA_MOD==4
	bf_test();
	RS = 1;	// data
	RW = 0;	// write
	LCD_DATA = ( c & 0xf0 );
	EN = 1;
	NOP();
	EN = 0;
	LCD_DATA = ( (c << 4) & 0xf0 );
	EN = 1;
	NOP();
	EN = 0;
#endif
}

void lcd_goto(unsigned char x, unsigned char y)
{	//	lcd_goto(1,1);		 1. satır 1. karakter ekran bası yani
	//x sutun sayısı y satır sayısı
	unsigned char pos;
	bf_test();
	switch(y)
	{
		case 1:		pos = 0x80;		break;
		case 2:		pos = 0xc0;		break;
		case 3:		pos = 0x94;		break;
		case 4:		pos = 0xd4;		break;
	}
	lcd_komut((x+pos)-1);
}

void lcd_kur()
{
	ADCON1 = 0X07;				//Analog OFF dijital ON
	LCD_DATA_TRIS = 0x00;		//LCD Data pinleri çıkış
	LCD_CONT_TRIS = 0X00;		//CONT uçları çıkış
	LCD_CONT = 0x00;			//LCD cont uçları silindi
	LCD_DATA = 0X00;			//LCD data pinleri silindi
	DelayMs(30);				//LCD açılmasını bekle

	LCD_DATA = 0X30;			//LCD resetleme işlemi
	EN = 1;		NOP();		EN = 0;
	DelayMs(15);
	EN = 1;		NOP();		EN = 0;
	DelayUs(100);
	EN = 1;		NOP();		EN = 0;
	DelayUs(100);

#if	DATA_MOD==4
	lcd_komut(0x28);
#endif
#if	DATA_MOD==8
	lcd_komut(0x38);
#endif
	lcd_komut(0x0f);
	lcd_sil();
	lcd_komut(0x06);

}



lcd.h Dosyası burada
#define	LCD_DATA_TRIS	TRISD
#define	LCD_CONT_TRIS	TRISE
#define LCD_DATA		PORTD
#define	LCD_CONT		PORTE

#define	RS RE0		//1 ise veri 0 ise komut
#define	RW RE1		//1 ise oku  0 ise yaz
#define EN RE2		//Düşen kenarda aktif olan veriyi lcd ye alır


#define DATA_MOD 4	//8 bit data için 8 yaz 4 bit için 4 yaz define kısmına
/*
	4 bi data modunda kullanılan portun alt 4 biti ile lcd nin üst 4 biti baglanır.
Örn:	RB0	---	D4
		RB1	---	D5
		RB2	---	D6
		RB3	---	D7
*/

extern void bf_test();
extern void lcd_goto(unsigned char x, unsigned char y);
extern void lcd_data(unsigned char c);
extern void lcd_puts(const unsigned char * s);
extern void lcd_komut(unsigned char x);
extern void lcd_sil();
extern void lcd_kur();


Son ihtimal LCD bozuk onu denemedim elimde olmadığı için

Arkadaşlar son düzeltme olarak yazayım 8 bit modda düzgün çalıştı sorun 4 bit modda oluyor
Yapılacak çok şey var

mihri

Aynı problemi başka bir lcd kütüphanesi ile bende karşılaştım. Yazdığım kodun uzunluğu 2k'yı geçince yapıyordu bu hatayı. Hi-Tech kürekli olmasına rağmen.
"Eppur si muove!"

omergokgoz

void lcd_goto(unsigned char x, unsigned char y)
{   //   lcd_goto(1,1);       1. satır 1. karakter ekran bası yani
  //x sutun sayısı y satır sayısı
  unsigned char pos;
  bf_test();
  switch(y)
  {
     case 1:      pos = 0x80;      break;
     case 2:      pos = 0xc0;      break;
     case 3:      pos = 0x94;      break;
     case 4:      pos = 0xd4;      break;
  }
  //lcd_komut((x+pos)-1);  sorun burada gibi görünüyor
  lcd_data((x+pos)-1);
}

ilk bakışta sorun buradan kaynaklanıyor gibi. Deneyip bana sonucunu iletebilirsen yardımcı olurum. Sıkıntı yaşarsan beni şirkette bir yıl önce yazdığım fonksiyonlardan bir kaçını seninle paylaşabilirim. Kolay gelsin..

3ddark

void lcd_kur()
{
	ADCON1 = 0X07;				//Analog OFF dijital ON
	LCD_DATA_TRIS = 0x00;		//LCD Data pinleri çıkış
	LCD_CONT_TRIS = 0X00;		//CONT uçları çıkış
	LCD_CONT = 0x00;			//LCD cont uçları silindi
	LCD_DATA = 0X00;			//LCD data pinleri silindi
	DelayMs(30);				//LCD açılmasını bekle

	LCD_DATA = 0X30;			//LCD resetleme işlemi
	EN = 1;		NOP();		EN = 0;
	DelayMs(15);
	EN = 1;		NOP();		EN = 0;
	DelayUs(100);
	EN = 1;		NOP();		EN = 0;
	DelayUs(100);

#if	DATA_MOD==4
	lcd_komut(0x20);
	lcd_komut(0x28);
#endif
#if	DATA_MOD==8
	lcd_komut(0x38);
#endif
	lcd_komut(0x0f);
	lcd_sil();
	lcd_komut(0x06);

}


Arkadaşlar olayı çözdüm akşam yatarken aklıma geldi ilk iş olarak sabah deneyeyim dedim :D biraz garip oldu ama o kadar çok ugraştım ki takıntı oldu. Neyse sonuca gelelim.
lcd_komut(0x20);
	lcd_komut(0x28);

yazınca ilk olarak 4 bit olunca üst bitlerin gönderiyor arada alt bitleri kaçırıyor galiba o yüzden ilk seferde 4 bit data oluyor sonra tekrar aynı kod olunca datayı kaçırmıyor bu sefer 2 satır seçimi gerçekleşiyor.
Bu işlemde 8 bit olunca sorun çıkmıyor zaten bütün datalar aynı anda gidiyor sürekli.
Herkeze kolay gelsin.
Yapılacak çok şey var