View Single Post
Old 06-04-2007, 02:36 PM   #15
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Thư viện LCD 16x2 8bit mode.

Mình xin upload thư viện viết cho LCD, ở đây mình dùng 8 bit mode cho LCD 2 line x 16 colum.

Code:
// LCD.h
#ifndef	 LCD_H
#define	LCD_H

# include <pic.h>

//============== Using LCD - 2 line, 16 colum
#define	LCD_MODE_2x16		(TRUE)					// HDM16216H-2, HDM16216H-4, HDM16216H-5, HDM16216H-B, HDM16216H-D, HDM16216L-2, HDM16216L-5, HDM16216L-7, HDM16216L-D, HDM16216L-B, HDM16216H-I

#define	LCD_CURSOR_BLINK					(FALSE)					// Blink/Noblink cursor mode
#define	LCD_CURSOR_ON					(TRUE)						// Cursor visible
#define	LCD_CURSOR_INCREMENT			(TRUE)						// Set left-to-right cursor movement
#define	LCD_CURSOR_SHIFT					(FALSE)					// Shift display on entry

#define	LCD_DISPLAY_ON					(TRUE)					// Turn display on/off

#define	LCD_ALLOW_USER_CHARS			(TRUE)					// Controls whether display uses ASCII for control chars or uses user-defined chars in lcd_putc()
#define	LCD_ENABLE_GETC					(TRUE)					// Save code space by setting to FALSE
#define	LCD_ENABLE_GOTOXY				(TRUE)					//   any functions which you will not
#define	LCD_ENABLE_PRINTF				(TRUE)					//   need in your application.
#define	LCD_ENABLE_UNSCROLL			(TRUE)
#define	LCD_ENABLE_SCROLL				(TRUE)
#define	LCD_ENABLE_CLEAR					(TRUE)

#define LCD_MAXROWS						((unsigned char)(2))
#define	LCD_MAXCOLS						((unsigned char)(16))
# define LCD_MULTI_LINE					(TRUE)

#define LCD_8_BIT_MODE						(TRUE)

//======================= Define LCD_PORT
#define	LCD_DATA_PORT		PORTD					// Port on which LCD data lines are connected
#define	LCD_TRIS_PORT		TRISD					// Need to specify the corresponding TRIS

# define LCD_RS			RA1
# define LCD_RW			RA2
# define LCD_E				RA3

# define LCD_TRIS_E		TRISA1
# define LCD_TRIS_RW		TRISA3
# define	LCD_TRIS_RS		TRISA2

// =======================  Define command code
#define	LCD_COMMAND_CLEAR				((unsigned char)(0x01))	//1.53 ms	// Clear screen, home cursor, unshift display
#define	LCD_COMMAND_HOME				((unsigned char)(0x02))	//1.53 ms	// Home cursor, unshift display
#define	LCD_COMMAND_BACKSPACE		((unsigned char)(0x10))				// Move cursor left one (destructive based on LCD_DESTRUCTIVE_BS)
#define	LCD_COMMAND_FWDSPACE		((unsigned char)(0x14))				// Move cursor right one
#define	LCD_COMMAND_PANLEFT			((unsigned char)(0x18))				// Move screen left one
#define	LCD_COMMAND_PANRIGHT			((unsigned char)(0x1C))			// Move screen right one


// ==================== Declare some functions
void delay_us (unsigned char us);
void delay_ms(unsigned char  ms);
unsigned char LCD_getByte (void);
void LCD_PrByte (unsigned char  c);
void LCD_Command(unsigned char c);
void LCD_PrChar (unsigned char  c);
void LCD_gotoXY(unsigned char row, unsigned char col);
unsigned char  LCD_getChar (void);						// Read character at cursor
void LCD_Init(void);
void LCD_PrString (const char* message); 

#endif
Các bạn sẽ thấy là khi muốn dùng LCD thì đầu tiên các bạn khai báo thông số cho LCD như các chân RS, RW, E, LCD_PORT ở Define LCD_PORT. Mặc định mình khai báo là: LCD_PORT là PortD, RS là RA1, RW là RA2, E là RA3.

Các bước thực hiện:

- Khởi tạo LCD dùng lệnh: LCD_Init();
- Thao tác ghi đọc bình thường, chú ý nhất là các hàm: LCD_gotoXY, LCD_PrString, LCD_PrChar, LCD_Command.

Tiếp theo là file LCD.c là file thực hiện:

Code:
//LCD.c
# include "lcd.h"

// ==== Some constants for LCD 16x2
const unsigned char  const LCD_ROW_ADDRESS[] =					// Row/Column information for LCD_gotoxy()
	{
	0x00,		// Line 1
	0x40		// Line 2
	};

const unsigned char  const LCD_INIT_STRING [] =					// LCD Init String on powerup
	{
	0b00000001,							//	Clear display
	0b00000010,							//	Home cursor
};

//==========================================================================================
void delay_us (unsigned char us){
	while(us--){
		asm("nop");
		asm("nop");
	};
}

//==========================================================================================
void delay_ms(unsigned char  ms){
	unsigned char	i, j;
	while(ms--){
		for (i = 0; i < 20; i++)
			for (j = 0; j < 100; j++)
				asm("nop");
		};
}
// ============================================================================================
unsigned char LCD_getByte (void){
	unsigned char retval; 									// Return value
	LCD_TRIS_PORT = 0xFF;								// Set port to all input
	LCD_RW = 1;											// Tell LCD we want to read
	delay_us(2);
	LCD_E = 1;												// Do the read
	delay_us(2);
	retval = LCD_DATA_PORT;
	LCD_E = 0;
	LCD_TRIS_PORT = 0x00;								// Set port back to outputs
	return (retval);
}
//====================================================================================================
void LCD_PrByte (unsigned char  c){						// Write byte to port in current RS mode
	unsigned char RS_Status;
	RS_Status = LCD_RS;									// Get old pin state
	LCD_RS = 0;											// Force into command mode to read state
	while (LCD_getByte () & 0x80);							// Wait for read state
	if (RS_Status)
		LCD_RS = 1;										// Restore RS to old state
	delay_us (1);
	LCD_RW = 0;											// Set to write mode
	delay_us (1);
	LCD_DATA_PORT = c;									// Send the character out
	LCD_E = 1;
	delay_us(1);
	LCD_E = 0;	
}
//================================================================================================
/*Ham yeu cau goi lenh dieu khien LCD*/
void LCD_Command(unsigned char c){						// Send command to LCD port
	LCD_RS = 0;
	LCD_PrByte(c);	
}
//================================================================================================
/*Ham yeu cau goi du lieu hien thi len LCD*/
void LCD_PrChar (unsigned char  c){						// Write character to LCD
	LCD_RS = 1 ;
	LCD_PrByte(c);
}
//=================================================================================================
void LCD_gotoXY(unsigned char row, unsigned char col){
	if (row > LCD_MAXROWS)						// Range limit
		row = LCD_MAXROWS;
	if (col > LCD_MAXCOLS)
		col = LCD_MAXCOLS;
	
	row = LCD_ROW_ADDRESS[row-1];					// Get address of first byte on desired row
	row += col - 1;
	LCD_Command (0x80 | row);							// Write new cursor address
}
//  ===================================================================================== 
unsigned char  LCD_getChar (void)							// Read character at cursor
	{
	unsigned char 	retval;										// Return value
	LCD_RS = 1;
	retval = LCD_getByte ();
	LCD_RS = 0;
	return (retval);
	}

//=======================================================================================
void LCD_Init(void){
	unsigned char i;	

	 LCD_TRIS_PORT 	=	0x00;
	 LCD_TRIS_E 	= 	0;
	 LCD_TRIS_RW 	=	0;
	 LCD_TRIS_RS 	=	0;

	LCD_E = 0 ;
	LCD_RS = 0;
	LCD_RW = 0; 
	 
	 //delay_ms(100); 							  //   Tao tre 100ms cho LCD khoi dong
	
	LCD_PrByte (0b00111000); 		//Function set  ; DL = 1(8 bits) , N = 1 (2 lines), F = 0 (5x8 dots)
	LCD_PrByte (0b00001100);		// Display on/off control 
	LCD_PrByte (0b00000110);		// Entry mode set

	LCD_PrByte(LCD_COMMAND_CLEAR);
	LCD_PrByte(LCD_COMMAND_HOME);
}

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

void LCD_PrString (const char* message){					// Write message to LCD (C string type)

	while (*message)						//	Look for end of string
		LCD_PrChar (*message++);					//	Show and bump
}
Các bạn thêm 2 file này vào trong Project của mình và nhớ include file LCD.h vào chỗ đầu file chứa hàm Main nhé.

Các bạn có thể mô phỏng bằng Proteus chạy rất ok. Lúc nào gửi tiếp mấy cái đã test.

Chúc các bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn