LCD kullanımı ile ilgili

Başlatan psiko, 01 Mayıs 2005, 21:56:51

psiko

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

main()
{
   unsigned char goster[]="SICAKLIK ";

   TRISA=0;
   TRISB=0;

   lcd_init();
   lcd_clear();

   for(;;)
   {
           lcd_puts(goster);

      DelayMs(250);
      lcd_clear();
   }
}


PORTB 0-3 bitleri LCD'nin 4-7 pinlerine bağlı.
PORTA bit 2 -> LCD RS
PORTA bit 3 -> LCD E

bağlantılar bu şekilde.

acaba bu kodda hata nerde?

psiko

ISIS'de simülasyon yapıyorum. kursör sadece yanıp sönerek ilk satırın başından sonuna kadar gidiyor. o kadar. başka hiçbir şey olmuyor. yazı falan da çıkmıyor. sorun sizce nerde olabilir?

psiko

bununla ilgili birşeyler bilen hiç kimse yok mu ya???

arslan74

Merhaba,

Hangi PIC'i kullandığını yazmanışsın. Eğer 16F877 gibi Analog girişleri var ise, önce Analog girişleri Dijitale cevirmen gerek. Senin programda PortA'yı Dijital'e ceviren bir yer yok. Eğer dediğim gibi ise Programın çalışacaktır.

Başarılar,

Hasan ARSLAN

psiko

evet PIC16F877 kullanıyorum.

A ve B portları programda da görüldüğü gibi giriş değil çıkış olarak ayarlandı. giriş olarak ayarlamaya da zaten gerek yok diye düşünüyorum.

arslan74

Giriş yada cıkış önemli değil. Dijital olarak kullanacaksan dijitale cevirmen gerek. Aksi takdirde yanlız giriş ve analog olarak kullanabilirsin.

psiko

TRISB=0;

komutu ile B portunun tüm pinleri çıkış olarak ayarlanır ve analog çıkış gibi bir özellik yoktur. digital olur. yani RB0=0 veya RB0=1 diyebilirsin. 0 0V'a 1 ise 5V'a (beslemenin 5V olduğunu düşünürsek) karşı gelir.

ben böyle biliyorum. eğer sen başka birşey biliyorsan söylersen sevinirim. özellikle nasıl yapılacağını anlatırsan daha iyi olur. çünkü ilk defa bu söylediğin gibi birşey duydum.

arslan74

Merhaba,

Sen 16F877'in datasheetini bir incele ve ayrıca yazdıkarımı dikkatli oku.
Alıntı YapSenin programda PortA'yı Dijital'e ceviren bir yer yok.

Demişim.

Yani datasheetini incelersen ADC yanlız ProtA ve PortE girişlerinde var. Oysan sen PortB den bahs ediyorsun.

Veli B.

Arkadaşlar pinlerden ziyade yazılıma yoğunlaşın.Hi-tec hakkında bilgim olmadığı için bu konuda yorum yapamıyorum ama eğer kursör blink veya kayma yapıyorsa, sorun pinlerle ilgili değil demektir.Komut gönderiyorsun ama data gönderemiyorsun.Muhtemelen code içerisinde bir sorun var.

arslan74

Sen 16F877 Datasheetin yanında HD44780 Chip'in datasheetini incele sonra program yazmaya calış.

RS, RW, E, D0-7 ucların ne işe yaradığını öğrenmen gerek.

Sana kısaca anlatayım istersen:

RS: Gelen bilginin Komutu mu yoksa data mı olduğunu belirtir. RS=1 ise D0-7 uclarında ki bilgi Data'dır.

RW: LCD bilgi yazma ve okuma modunu belirler RW=0 ise Yazma modunda dır.

E: LCD bilgi giriş veya çıkışını aktif yapar.

D0-7: İse gelen veya gönderilen data veya komutlar için kullanılır. 8 bit veya 4 bit olarak bilgi gönderme seceneği vardır.

Başarılar,

SpeedyX

Programda ufak değişiklikler yaptım.
pin bağlantılarım kesinlikle doğrudur diyorsanız, "#include <lcd.h>" kısmını kaldırın yada lcd.h içerisini pin bağlantılarına göre ayarlayın.

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

#define b 40

main()
{
   unsigned char *goster[]="SICAKLIK ";

   TRISA=0;
   TRISB=0;

   lcd_init();
   lcd_cmd(0x1); //lcd clear
   DelayMs(b);

   while(1)
   {
      lcd_puts(goster);
      DelayMs(250);
      lcd_cmd(0x1); //lcd clear
      DelayMs(b);
   }
}

psiko

lcd.c dosyasının içeriği şöyle:

/*
 *	LCD interface example
 *	Uses routines from delay.c
 *	This code will interface to a standard LCD controller
 *	like the Hitachi HD44780. It uses it in 4 bit mode, with
 *	the hardware connected as follows (the standard 14 pin 
 *	LCD connector is used):
 *	
 *	PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
 *	PORTA bit 2 is connected to the LCD RS input (register select)
 *	PORTA bit 3 is connected to the LCD EN bit (enable)
 *	
 *	To use these routines, set up the port I/O (TRISA, TRISB) then
 *	call lcd_init(), then other routines as required.
 *	
 */

#include	<pic.h>
#include	"lcd.h"
#include	"delay.h"
 
static bit LCD_RS	@ ((unsigned)&PORTA*8+2);	// Register select
static bit LCD_EN	@ ((unsigned)&PORTA*8+3);	// Enable

#define	LCD_STROBE	((LCD_EN = 1),(LCD_EN=0))


/* write a byte to the LCD in 4 bit mode */

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

/*
 * 	Clear and home the LCD
 */

void
lcd_clear(void)
{
	LCD_RS = 0;
	lcd_write(0x1);
	DelayMs(2);
}

/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
	LCD_RS = 1;	// write characters
	while(*s)
		lcd_write(*s++);
}

/* write one character to the LCD */

void
lcd_putch(char c)
{
	LCD_RS = 1;	// write characters
	PORTB = (PORTB & 0xF0) |  (c >> 4);
	LCD_STROBE;
	PORTB = (PORTB & 0xF0) |  (c & 0x0F);
	LCD_STROBE;
	DelayUs(40);
}


/*
 * Go to the specified position
 */

void
lcd_goto(unsigned char pos)
{
	LCD_RS = 0;
	lcd_write(0x80+pos);
}
	
/* initialise the LCD - put into 4 bit mode */

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
}


bu da lcd.h dosyası:

/*
 *	LCD interface header file
 *	See lcd.c for more info
 */

/* write a byte to the LCD in 4 bit mode */

extern void lcd_write(unsigned char);

/* Clear and home the LCD */

extern void lcd_clear(void);

/* write a string of characters to the LCD */

extern void lcd_puts(const char * s);

/* Go to the specified position */

extern void lcd_goto(unsigned char pos);
	
/* intialize the LCD - call before anything else */

extern void lcd_init(void);

extern void lcd_putch(char);

/*	Set the cursor position */

#define	lcd_cursor(x)	lcd_write(((x)&0x7F)|0x80)



SpeedyX senin programındaki lcd_cmd() diye birşey tanımlı değil lcd.c dosyasında. ayrıca lcd.c dosyasına bakarsan lcd_clear() fonsiyonunun sanırım senin yapmak istediğin şeyi yaptığını görürsün.

SpeedyX

Bendeki lcd.c :
#include	<pic18.h>
#include	"lcd.h"
#include	"delay.h"
 

static bit fourbit;		// four or eight bit mode?

#ifdef CHECKBUSY

unsigned char 
lcd_read_cmd_nowait(void)
{
	unsigned char c, readc;

	LCD_DATA_TRIS	 = INPUT_DATA;

	LCD_RW = 1; // Read LCD
	asm("nop"); // short propagation delay
	asm("nop"); // short propagation delay

	if (fourbit)
	{
		LCD_STROBE_READ(readc); // Read high nibble
		// Move 4 bits to high nibble while zeroing low nibble
		c = ( ( readc << 4 ) & 0xF0 ); 
		LCD_STROBE_READ(readc); // Read low nibble
    		c |= ( readc & 0x0F ); // Or in 4 more bits to low nibble
	}
	else
	{
		LCD_STROBE_READ(readc); 
		c = readc;
	}
	LCD_RW = 0; // Return to default mode of writing LCD
	LCD_DATA_TRIS	 = OUTPUT_DATA; // Return to default mode of writing LCD

	return(c);
}

void
lcd_check_busy(void) // Return when the LCD is no longer busy, or we've waiting long enough!
{
	// To avoid hanging forever in event there's a bad or 
	// missing LCD on hardware.  Will just run SLOW, but still run.
	unsigned int retry; 
	unsigned char c;

	for (retry=1000; retry-- > 0; ) {
		c = lcd_read_cmd_nowait();
		if (0==(c&0x80)) break; // Check busy bit.  If zero, no longer busy
	}
}

#endif

/* send a command to the LCD */
void
lcd_cmd(unsigned char c)
{
	LCD_WAIT; // may check LCD busy flag, or just delay a little, depending on lcd.h

	if (fourbit)
	{
		LCD_DATA = ( ( c >> 4 ) & 0x0F );
		LCD_STROBE();
    		LCD_DATA = ( c & 0x0F );
		LCD_STROBE();
	}
	else
	{
		LCD_DATA = c;
		LCD_STROBE();
	}
}

/* send data to the LCD */
void
lcd_data(unsigned char c)
{
	LCD_WAIT; // may check LCD busy flag, or just delay a little, depending on lcd.h

	LCD_DATA = 0;
	LCD_RS = 1;
	if (fourbit)
	{
    		LCD_DATA |= ( ( c >> 4 ) & 0x0F );      
		LCD_STROBE();
		LCD_DATA &= 0xF0;
		LCD_DATA |= ( c & 0x0F ); 
		LCD_STROBE();
	}
	else
	{
		LCD_DATA = c;
		LCD_STROBE();
	}
	LCD_RS = 0;
}

/* write a string of chars to the LCD */

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

/* initialize the LCD */
void
lcd_init(unsigned char mode)
{
	char init_value;

	fourbit		= 0;
	if (mode == FOURBIT_MODE){
		fourbit = 1;
		init_value = 0x3;
	}else{
		init_value = 0x3F;
	}
	LCD_RS = 0;
	LCD_EN = 0;
	LCD_RW = 0;
	LCD_RS_TRIS	 = OUTPUT_PIN;
	LCD_EN_TRIS	 = OUTPUT_PIN;
	LCD_RW_TRIS	 = OUTPUT_PIN;
	LCD_DATA_TRIS	 = OUTPUT_DATA;
	DelayMs(15);
	LCD_DATA	 = init_value;
	LCD_STROBE();
	DelayMs(5);
	LCD_DATA	 = init_value;
	LCD_STROBE();
	DelayUs(200);
	LCD_DATA	 = init_value;
	LCD_STROBE();
	
	if (fourbit){
		LCD_WAIT; //may check LCD busy flag, or just delay a little, depending on lcd.h
		LCD_DATA = 0x2; // Set 4-bit mode
		LCD_STROBE();

		lcd_cmd(0x28); // Function Set
	}else{
		lcd_cmd(0x38);
	}
	lcd_cmd(0xF); //Display On, Cursor On, Cursor Blink
	lcd_cmd(0x1); //Display Clear
	lcd_cmd(0x6); //Entry Mode
	lcd_cmd(0x80); //Initialize DDRAM address to zero
}


Bendeki lcd.h :
#ifndef _LCD_H_
#define _LCD_H_

// #define CHECKBUSY	1

#ifdef CHECKBUSY
	#define	LCD_WAIT lcd_check_busy()
#else
	#define LCD_WAIT DelayMs(5)

#endif

#define MESSAGE_LINE		0x0

#define LCD_RS	LA3
#define LCD_EN	LA1
#define LCD_RW	LA2 
#define LCD_DATA	LATD
#define LCD_DATA_PORT	PORTD 
#define LCD_RS_TRIS	TRISA3
#define LCD_EN_TRIS	TRISA1
#define LCD_RW_TRIS	TRISA2 
#define LCD_DATA_TRIS	TRISD

#define FOURBIT_MODE	0x0
#define EIGHTBIT_MODE	0x1
#define OUTPUT_PIN      0x0	
#define INPUT_PIN       0x1	
#define OUTPUT_DATA     0x0	
#define INPUT_DATA      0x0F	

#define LCD_STROBE()	LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

#define LCD_STROBE_READ(value)	LCD_EN = 1; \
				asm("nop"); asm("nop"); \
				value=LCD_DATA_PORT; \
				LCD_EN = 0; 

#define	lcd_cursor(x)			lcd_cmd(((x)&0x7F)|0x80)
#define lcd_clear()			lcd_cmd(0x1)
#define lcd_putch(x)			lcd_data(x)
#define lcd_goto(x)			lcd_cmd(0x80+(x));
#define lcd_cursor_right()		lcd_cmd(0x14)
#define lcd_cursor_left()		lcd_cmd(0x10)
#define lcd_display_shift()		lcd_cmd(0x1C)
#define lcd_home()			lcd_cmd(0x2)

extern void lcd_cmd(unsigned char);
extern void lcd_data(unsigned char);
extern void lcd_puts(const char * s);
extern void lcd_init(unsigned char);

#endif


Aslında senin denemen gereken "unsigned char *goster[]="SICAKLIK ";" kısmıdır. pin bağlantılarından eminsen pointer şeklinde kullanarak belki bir çözüm bulabilirsin.

psiko

senin lcd.c dosyasında

#include   <pic18.h>


diye birşey var. bu ne alâka acaba? benim include klasörümde pic18.h diye bir dosya yok.

SpeedyX

arkadaşım unsigned char *goster[]="SICAKLIK "; şeklinde dene demiştim,
denemeden mi bu soruyu sordun?

driver dosyalarımızın farklı olduğunu göstermek için yazdım onu oraya.
sen pic18.h yazmada pic.h yaz, biraz dene birşeyler, adım adım soru sorma.
az daha uğraşırsan proteusta yapıp yollayacağım.