LCD'ye bişey yazdıramadım

Başlatan trigger, 24 Mayıs 2005, 16:05:27

trigger

Merhaba arkadaşlar,
pic 16F84A + 2x16 LCD(HD44780) kullanıyorum.
HI-TECH'in kendi delay,lcd,pic vs include dosyalarını kullanıyorum.
PIC--LCD
RB0--11(D4)
RB1--12(D5)
RB2--13(D6)
RB3--14(D7)
RA2--4(RS)
RA3--6(E)
LCD : 1(Vss)--GND
        5(R/W)--GND
Beslemeler vs tamam.
Aşagıdaki kodu yuklesem de ekranda sadece ust satır komple yanıyor.
Sonra başka bişey yazmıyor.Bir arkadaşım reset olmuyor diyor.Sorun nerede?HI-TECH'ın lcd.c dosyası ya da DelayUs ve DelayMs fonksiyonları mı düzgün çalışmıyor?
#define	XTAL_FREQ	4MHZ

#include <pic.h>
#include <lcd.c>
#include <delay.c>
#include <stdio.h>
main(void)
{
	unsigned char display[]="Temp= ";
	TRISB=0;
	TRISA=0;	
	
	DelayMs(250);
	lcd_init();
	lcd_clear();
	

	for(;;)
	{
		lcd_puts(display);

		DelayMs(250);
		lcd_clear();
	}
}

Şimdilik sadece ekrana Temp= yazdırmak istiyorum bunu bile yapmıyor.Daha ileride sıcaklık ölçüp yazdıracam:)

ayban

/* en iyisi bunu deneyin konfigürasyon sözcügüde dahil LCD ye karakter gonderme*/

__CONFIG(WDTDIS & XT & UNPROTECT & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS);

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

main(void)
{
	TRISA=0;
	TRISB=0;
	lcd_init();
	lcd_clear();
	lcd_puts("PIC PROJE");
	for(;;)
	{
		}
{
"Tek kitap okuyandan kork!"

trigger

Alıntı yapılan: "ayban"/* en iyisi bunu deneyin konfigürasyon sözcügüde dahil LCD ye karakter gonderme*/

__CONFIG(WDTDIS & XT & UNPROTECT & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS);

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

main(void)
{
	TRISA=0;
	TRISB=0;
	lcd_init();
	lcd_clear();
	lcd_puts("PIC PROJE");
	for(;;)
	{
		}
{
en yukarıdaki config satırında derleyici hata veriyor:
) expected
function body expected
unreachable code(warning)
expression syntax
unexpected EOF

psiko

2 tane alt çizgi değil sadece 1 tane alt çizgi olacak o satırın başında. hata ondandır...

trigger


trigger

Alıntı yapılan: "psiko"2 tane alt çizgi değil sadece 1 tane alt çizgi olacak o satırın başında. hata ondandır...
Ondan da değilmiş.tek çizgi yaptım yine de hata verdi.O satırda:
" ) expected " diye hata veriyo.Bir de " function body expected " diyor..Bana gonderdıgın kodu kontrol edip tekrar yazar mısın hata varsa?
İnternette aynı tür sorunu olan bayagı bir kişi var.Onlar da sorunlarına yanıt alamamışlar.Üst satır komple blok halinde çalışıyor.Alt satır boş.Galiba bu tipik bir lcd test ekranıymış.Galiba lcd_init() oluyo ama lcd_clear() çalışmıyor.Ne yapmak lazım lcd.c deki delayleri mi değiştirecez?Bunu da denedim bazılarını arttırdım biraz yine bişey değişmedi.

psiko

ben sorunun lcd_init ile ilgili olduğunu tahmin ediyorum. LCD başlatılamıyor olabilir. lcd_init fonksiyonu aşağıdaki gibi:
void
lcd_init(void)
{
	LCD_RS = 0;	// write control bytes
	DelayMs(15);	// power on delay
	PORTB = 0x3;	// attention!
	LCD_STROBE;
	DelayMs(5);
	LCD_STROBE;
	DelayUs(100);
	LCD_STROBE;
	DelayMs(5);
	PORTB = 0x2;	// set 4 bit mode
	LCD_STROBE;
	DelayUs(40);
	lcd_write(0x28);	// 4 bit mode, 1/16 duty, 5x8 font
	lcd_write(0x08);	// display off
	lcd_write(0x0F);	// display on, blink curson on
	lcd_write(0x06);	// entry mode
}


benim burda sormak istediğim şey sondaki 4 komutun arka arkaya gelmesi normal mi? acaba bunların arasına gecikme koymak gerekir mi?

SpeedyX

Alıntı yapılan: "psiko"benim burda sormak istediğim şey sondaki 4 komutun arka arkaya gelmesi normal mi? acaba bunların arasına gecikme koymak gerekir mi?
lcd_write fonksiyonunda Busy flag kontrol ediliyor mu?
lcd_write fonksiyonunuda yazınız.

psiko

void
lcd_write(unsigned char c)
{
	PORTB = (PORTB & 0xF0) |  (c >> 4);
	LCD_STROBE;
	PORTB = (PORTB & 0xF0) |  (c & 0x0F);
	LCD_STROBE;
	DelayUs(40);
}


işte lcd_write fonksiyonu. busy flag kontrolü yok heralde. zaten devre busy flag kontrol etmeye uygun değil. yani R/W bacağı toprağa kısa devre yapılmış. böylece sadece yazma oluyor ve LCD'den durum okuması yapılmıyor. 4 bitlik çalışmada busy flag kontrolüne gerek yokmuş sanırım. yoksa var mı? sence sorun bundan mı kaynaklanıyor? düzeltmek için ne tavsiye edersin? şimdiden sağol :)

trigger

Benim bildiğim kadarıyla 4 bitte busy flag kontrolü olmaz diye bişey yok.R/W bacagını topraklamayıp pice baglarsan busy olup olmadıgını kontrol edebilirsin.BU HI-TECH'in compiler ve/veya include dosyaları pek iyi değil herhalde.Kitapta örnek var aynısını yapıyorum.Donanım hatası olmadığını da biliyorum yine de olmuyor.Üstelik bu sorunla karşılaşan bayagı biri var.

psiko

bu lcd.c dosyasıyla yapılmış programın Proteus'ta normal çalışması bir sorun olmadığını gösterir bence.

ayrıca internette başka lcd.c ve lcd.h dosyaları var. istersen onları da deneyebilirsin. ama becnce sorun donanımsal. mesela sen bir porta 4 led bağlayıp sırayla hepsini yakmayı denedin mi? bu tip birşey normal çalışıyor mu?

SpeedyX

Evet mühendis hocam, önce o pic e bir led yaktır bakalım oluyor mu.
(lcd.c normal görünüyor, tavsiyem ccs ye geçin :lol: )

trigger

Tamam m.y.o hocam sorunu hallettim.Arkadaştan aldığım başka bir lcd dosyasını kullandım ve ekrana istediğimi yazdırabildim.Yalnız 2 farklı lcdden 1 tanesi çalıştı.Diğerinin üst satır aynı yine.Galiba lcdnin mikroişlemcisine de bağlı biraz olay.Ya da belki diğeri bozuk olabilir yeni aldım ama.Aşağıda da ieteyenler için LCD_MAIN.c dosyası.Portları vs kendi donanımınıza göre ayarlayınız.
/*
		     USER'S ROUTINES DESCRIPTION:			
									
LCD_INIT() ----------->	initilalize the LCD. 				
			You must call it the first time you use the LCD	
			and before any other LCD routines.		
									
LCD_CLEAR() ---------->	Clears and Home LCD.			
									
LCD_CMD('char')	------>	Send a command to the LCD.			
			See LCD datasheet for the complete
			list of commands.
			
LCD_GOTO(line,pos) --->	Set the Cursor to a specified Line and position.
			Lines available are from 1 to 4. Pos available 
			starts from 1 to max available on your LCD.
			
LCD_PUTCH('char') ---->	Write a character on LCD (ASCII representation).

LCD_PUTS("string") --->	Write a string on LCD.

LCD_PUTUN(number)  --->	Write an Unsigned Number on LCD.
			It works both with INT (16bit) and CHAR (8bit).
			
LCD_PUTSN(number)  --->	Write a Signed Number on LCD (with Sign if <0).
			It works both with INT (16bit) and CHAR (8bit).


/************************************************************************/
/* 									*/
/* 			   !!! ATTENTION !!!				*/
/* 	Follow these simple instructions to configure your LCD module	*/
/*									*/
/*	1) check your hardware to determine which lines to use		*/
/*	   (you need 6 output lines).					*/
/*	2) set properly TRIS registers in your main code to configure	*/
/*	   the 6 lines as outputs.					*/
/*	3) In the next step use the defines to set the 6 lines as your	*/
/*	   hardware requires.						*/
/*	4) Set LCD Rows and Columns number using the define as shown	*/
/*	5) You are ready...your LCD will work!!! :)			*/
/* 									*/
/************************************************************************/


/************************************************************************/
/* Use this includes if these files are not included in your main code	*/
/************************************************************************/
/*#include	<pic.h>
/*#include	"delay.c"


/************************************************************************/
/* Use the following defines to set the lines as your hardware requires	*/
/* ...you can use ANY output line of the MCU, even on several ports :)	*/
/************************************************************************/

#define	LCD_RS		RA2		// Register select
#define	LCD_EN		RA3 	        // Enable
#define	LCD_D4		RB0		// LCD data 4
#define	LCD_D5		RB1   		// LCD data 5
#define	LCD_D6		RB2		// LCD data 6
#define	LCD_D7		RB3		// LCD data 7



/************************************************************************/
/*	Now you have only to write LCD Rows and Columns number	 	*/
/************************************************************************/

#define LCD_ROWS	2	// valid numbers are: 1,2 
				// (set to 2 for 2 or more rows)
#define LCD_COLS	16	// valid numbers are: 8,16,20				

/************************************************************************/
/*	Use the following defines to send fast command			*/
/*	 to the LCD							*/
/*	EX: LCD_CMD(LCD_line2); will set the cursor on line 2		*/
/*		 You can add fast command of your own!!!		*/
/************************************************************************/
/* 									*/
/* 				!!! NOTE !!!				*/
/*		DON'T CHANGE THE DEFINES WITHIN #if-#endif		*/
/* 									*/
/************************************************************************/

#define LCD_CLR		0x01 // Clear Display
#define LCD_HOME		0x02 // Cursor to Home position

/************************************************************************/
#if (LCD_COLS==20)
	#define LCD_line1	0x80 // Line 1 position 1
	#define LCD_line2	0xC0 // Line 2 position 1
	#define LCD_line3	0x94 // Line 3 position 1 (20 char LCD)
	#define LCD_line4	0xD4 // Line 4 position 1 (20 char LCD)
#else
	#define LCD_line1	0x80 // Line 1 position 1
	#define LCD_line2	0xC0 // Line 2 position 1
	#define LCD_line3	0x90 // Line 3 position 1 (16 char LCD)
	#define LCD_line4	0xD0 // Line 4 position 1 (16 char LCD)
#endif
/************************************************************************/
void LCD_STROBE(void);
void LCD_NIBBLE_OUT(unsigned char);
void LCD_WRITE(unsigned char);
void LCD_CMD(char);
void LCD_GOTO(char,char);
void LCD_CLEAR(void);
void LCD_PUTCH(char);
void LCD_PUTUN(unsigned int);
void LCD_PUTSN(signed int);
void LCD_PUTS(const char *);
void LCD_INIT(void);
void saniye(int);


void saniye(int i)
{
	int a;
	
	for(a=1000*i;a>0;a--)
		DelayMs(1);
}
				

/****************************************/
/* 	 Enable LCD to read data	*/
/****************************************/
void LCD_STROBE (void)
{
LCD_EN = 1;
DelayUs(1);
LCD_EN=0;
}	

      
/****************************************/
/* 	Write a nibble to the LCD	*/
/****************************************/
void LCD_NIBBLE_OUT (unsigned char c )
{
if ( c & 0b10000000 ) 
        LCD_D7=1;
else LCD_D7=0;
if ( c & 0b01000000 ) 
        LCD_D6=1;
else LCD_D6=0;
if ( c & 0b00100000 ) 
        LCD_D5=1;
else LCD_D5=0;
if ( c & 0b00010000 ) 
        LCD_D4=1;
else LCD_D4=0;
LCD_STROBE();
}


/****************************************/
/* Write a byte to the LCD (4 bit mode) */
/****************************************/
void LCD_WRITE (unsigned char c)
{
LCD_NIBBLE_OUT(c);
c <<= 4;
LCD_NIBBLE_OUT(c);
DelayUs(50);
}


/****************************************/
/*       send a command to the LCD      */
/****************************************/
void LCD_CMD (char c)
{
LCD_RS = 0;	// write command
LCD_WRITE(c);
}


/****************************************/
/*  GoTO specified line and position    */
/****************************************/
void LCD_GOTO (char line,char pos)
{
switch(line)
	{
	case 1: LCD_CMD((LCD_line1-1)+pos);
		break;
	case 2: LCD_CMD((LCD_line2-1)+pos);
		break;
	case 3: LCD_CMD((LCD_line3-1)+pos);
		break;
	case 4: LCD_CMD((LCD_line4-1)+pos);
	}
}


/****************************************/
/*           Clear and Home LCD         */
/****************************************/
void LCD_CLEAR (void)
{
LCD_CMD(LCD_CLR);
DelayMs(3);
}


/****************************************/
/*     Write one character to the LCD   */
/****************************************/
void LCD_PUTCH (char c)
{
LCD_RS = 1;	// write characters
LCD_WRITE(c);
}


/****************************************/
/*        Write numbers to the LCD      */
/****************************************/
void LCD_PUTUN (unsigned int c)
{
unsigned char t1,i,wrote;
unsigned int k;

wrote=0;
for (i=4;i>=1;i--)
	{
	switch(i){
	case 4: k=10000;
		break;
	case 3: k=1000;
		break;
	case 2: k=100;
		break;
	case 1: k=10;
	}
	t1=c/k;
	if((wrote)||(t1!=0))
		{
		LCD_PUTCH(t1+'0');
		wrote=1;
		}
	c-=(t1*k);
	}
LCD_PUTCH(c+'0');
}
/****************************************/
void LCD_PUTSN (signed int c)
{
if(c<0)
	{ 
	LCD_PUTCH('-');
	c*=(-1);
	}
LCD_PUTUN(c);
}


/****************************************/
/*       Write a string to the LCD      */
/****************************************/
void LCD_PUTS (const char * s)
{
LCD_RS = 1;	// write characters
while(*s)
	LCD_WRITE(*s++);
}


/****************************************/
/*             Initialize LCD           */
/****************************************/	
void LCD_INIT (void)
{
LCD_RS = 0;		// write control bytes
DelayMs(15);		// power on delay
LCD_D4=1;
LCD_D5=1;
LCD_D6=0;
LCD_D7=0;
LCD_STROBE();
DelayMs(5);
LCD_STROBE();
DelayUs(100);
LCD_STROBE();
DelayMs(5);
LCD_D4=0;		// set 4 bit mode
LCD_STROBE();
DelayUs(40);

#if (LCD_ROWS==1)
LCD_WRITE(0b00100000);	// 4 bit mode, 1 line, 5x8 font
#else
LCD_WRITE(0b00101000);	// 4 bit mode, 2 or more lines, 5x8 font
#endif

LCD_WRITE(0b00001000);	// display off
LCD_WRITE(0b00001100);	// display on, curson off, blink off
LCD_WRITE(0b00000110);	// shift entry mode, display not shifted
}