PDA

View Full Version : Mình thử tìm hiểu về LCD và hàm khởi tạo LCD420.C Trong CCS mình viết lại


buidinhba
24-11-2008, 03:02 PM
Mình thử tìm hiểu về LCD và hàm khởi tạo LCD420.C Trong CCS mình viết lại và chú giải để ai cung có thể hiểu được về các thức set các bit để hiển thị LCD
Tài liệu tham khảo :
http://home.iae.nl/users/pouweha/lcd/lcd0.shtml theo anh Quangnam


////////////////////////////////////////////////////////////////////////////
//// LCD420Tosy.C ////
//// Driver for common 4x20 LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
// B0 enable
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
#define LCD_EN PIN_D4//PIN_B4
#define LCD_RS PIN_D5//PIN_B5
//#define LCD_RW PIN_B1
//#define LCD_UNUSED PIN_B1

#define LCD_D4 PIN_D3//PIN_B3//
#define LCD_D5 PIN_D2//PIN_B2
#define LCD_D6 PIN_D1//PIN_B1//
#define LCD_D7 PIN_D0//PIN_B0

// misc display defines-
//#define Line_1 0x80
//#define Line_2 0xC0
//#define Clear_Scr 0x01

struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;

//#byte lcd = 6 // This puts the entire structure
// on to port B (at address 6)
#IFNDEF LCD_TYPE #DEFINE LCD_TYPE 2 #ENDIF // 0=5x7, 1=5x10, 2=2 lines


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0c, 0x01, 0x06};
// These bytes need to be sent to the LCD
// to start it up.


// The following are used for setting
// the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in


BYTE lcdline;

// prototype statements
#separate BYTE lcd_read_byte();// Doc 1 byte tu LCD
#separate void set_tris_Lcd(struct lcd_pin_map Lcd_State);// Gui lenh cho LCD
#separate void lcd_send_nibble( BYTE n );// ham khoi tao LCD
#separate void lcd_send_byte( BYTE address, BYTE n );// ham khoi tao LCD
#separate void lcd_init();// ham khoi tao LCD

#separate void lcd_gotoxy( BYTE x, BYTE y);// Ham viet1kitu/1chuoi len LCD
#separate void lcd_Clear();
#separate void lcd_putc( char c) ;// Ham gui lenh len LCD
#separate char lcd_getc( BYTE x, BYTE y);// Xung kich hoat
#separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
#separate void LCD_PulseEnable ( void );// Xung kich hoat
#separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data

#separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data

#separate BYTE lcd_read_byte() {
BYTE low,high;

// set_tris_b(LCD_READ);
set_tris_Lcd(LCD_READ);

// output_high( LCD_RW );//lcd.rw = 1;// Gui in hieu nhan du lieu tu LCD
delay_cycles(1);
output_high( LCD_EN );//lcd.enable = 1;
delay_cycles(1);
high = 0;
if (input(LCD_D7)) bit_set(high, 3);
if (input(LCD_D6)) bit_set(high, 2);
if (input(LCD_D5)) bit_set(high, 1);
if (input(LCD_D4)) bit_set(high, 0);//lcd.data;

output_low( LCD_EN );//lcd.enable = 0;
delay_cycles(1);
output_high( LCD_EN );//lcd.enable = 1;
delay_us(1);
low = 0;
if (input(LCD_D7)) bit_set(low, 3);
if (input(LCD_D6)) bit_set(low, 2);
if (input(LCD_D5)) bit_set(low, 1);
if (input(LCD_D4)) bit_set(low, 0);//lcd.data;

output_low( LCD_EN );//lcd.enable = 0;
set_tris_Lcd(LCD_WRITE);//set_tris_b(LCD_WRITE);
return( (high<<4) | low);
}
#separate void set_tris_Lcd(struct lcd_pin_map Lcd_State) {
output_bit ( LCD_EN, Lcd_State.enable);
output_bit ( LCD_RS, Lcd_State.rs );
// output_bit ( LCD_RW, Lcd_State.rw);
// output_bit ( LCD_UNUSED, Lcd_State.unused );

//output_bit ( bit_test (Lcd_State.data, 0) , LCD_D4);//bit_test (var, bit)
output_bit ( LCD_D4, Lcd_State.data&0x1 );
output_bit ( LCD_D5, (Lcd_State.data&0x2));
output_bit ( LCD_D6, (Lcd_State.data&0x4));
output_bit ( LCD_D7, (Lcd_State.data&0x8));

}
#separate void lcd_send_nibble( BYTE n ) {
// lcd.data = n;
// delay_cycles(1);
// lcd.enable = 1;
// delay_us(2);
// lcd.enable = 0;
LCD_SetData ( n );
delay_cycles(1);
output_high ( LCD_EN );// Cho bit LCD_EN from high to low de chip LCD nhan biet la nhan tin hieu vao
delay_us(2);
output_low ( LCD_EN );
delay_ms ( 1 ); // waste 3ms// Phai cho it nhat 3ms de gui het du lieu len LCD
}


#separate void lcd_send_byte( BYTE address, BYTE n ) { // address = 0; Gui command lenh dieu khien LCD, 1 gui tin hieu hien thi ky tu ;
// n byte tuong ung voi ky tu can hien thi trong bang ASCII
// lcd.rs = 0;
// while ( bit_test(lcd_read_byte(),7) ) ;
// lcd.rs = address;
// delay_cycles(1);
// lcd.rw = 0;
// delay_cycles(1);
// lcd.enable = 0;
// lcd_send_nibble(n >> 4);
// lcd_send_nibble(n & 0xf);
// output_low ( LCD_RS );
// while ( bit_test(lcd_read_byte(),7) ) ;
// output_bit ( address&0x1 , LCD_RS);
// delay_cycles(1);
// output_bit ( 0 , LCD_RW);
//
output_bit (LCD_RS, address&0x1 );// 0 Gui gia tri; 1 la gui lenh Command Reset, Gotoxy or many thing
delay_cycles(1);
// if (address>0) output_high ( LCD_RS );
output_low ( LCD_EN );
delay_cycles(1);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
output_low ( LCD_RS );// Chuyen sang gia tri gui tin hieu

}

//khoi tao LCD**********************************************
#separate void lcd_init() {
// BYTE i;
//
// //set_tris_b(LCD_WRITE);
// set_tris_Lcd(LCD_WRITE);
// // output_low ( LCD_RS );//lcd.rs = 0;
// // output_low ( LCD_RW );//lcd.rw = 0;
// // output_low ( LCD_EN );//lcd.enable = 0;
// delay_ms(15);
// for(i=1;i<=3;++i) {
// lcd_send_nibble(3);/* init with specific nibbles to start 4-bit mode */
// delay_ms(5);
// }
// lcd_send_nibble(2);
// for(i=0;i<=3;++i)
// lcd_send_byte(0, LCD_INIT_STRING[i]);
LCD_SetData ( 0x00 );
// output_low ( LCD_RW );// che do gui lenh
delay_ms(20); /* wait enough time after Vdd rise >> 15ms */
output_low ( LCD_RS );// che do gui lenh command Khi Rs xuong 0 , cho nhan du lieu
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();// Gui 1 suon xung tu cao xuong thap tren Enable de LCD biet nhan du lieu ve tu cac chan da duoc set o lenh LCD_SetData
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
// LCD_PutCmd ( 0b00011000 );/*bit 3,2 function set (Dislay Shift/ Cursormove, Right/ Left shift) */
LCD_PutCmd ( 0b00101000 );/*bit 4,3,2 function set (10/4- bit mode, 2/1 lines, 5x10 /5x7 characters) */
LCD_PutCmd ( 0b00001111 ); /* bit 2,1,0 display on/ off, cursor on/ off, blink on/ off */
LCD_PutCmd ( 0b00000110 ); /* bit 1,0 entry mode set, increment/ decrement, dislay Shift on/off */
LCD_PutCmd ( 0x01 ); /* clear display */
}


#separate void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
address=0x80;
switch(y) {
case 1 : address=0x80;break;
case 2 : address=0xc0;break;
case 3 : address=0x94;break;
case 4 : address=0xd4;break;
}
address+=x-1;
lcd_send_byte(0,address);// LCD_PutCmd ( address );
}
#separate void lcd_Clear() {
/* this subroutine works specifically for 4-bit Port A */
lcd_send_byte(0,1);
lcdline=1;
delay_ms(1);// Ham dung de chac chan gui du lieu ban co the de hoac khong can

}
#separate void lcd_putc( char c) {
/* this subroutine works specifically for 4-bit Port A */
switch (c) {
case '\f' : lcd_send_byte(0,1);
lcdline=1;
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,++lcdline); break;
case '\b' : lcd_send_byte(0,0x10); break;// Send command
default : lcd_send_byte(1,c); break;// Send data
}
}
#separate void LCD_PutString ( char m_strTg[] )
{
int8 i=0;
for (i=0; i<strlen(m_strTg); i++)
lcd_putc(m_strTg[i]);
}
#separate void LCD_PutChar ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
output_high ( LCD_RS );
LCD_PutCmd( cX );
output_low ( LCD_RS );
}
#separate char lcd_getc( BYTE x, BYTE y) {
char value;

lcd_gotoxy(x,y);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
#separate void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */// Gui 4 bit cao cua cX
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */// Gui 4 bit thap cua cX
LCD_PulseEnable();
}
#separate void LCD_PulseEnable ( void )// Keo bit LCD_En tu cao xuong thap de LCD biet de nhan du lieu
{
output_high ( LCD_EN );
delay_us ( 3 ); // was 10
output_low ( LCD_EN );
delay_ms ( 3 ); // was 5
}

#separate void LCD_SetData ( unsigned int cX )// set cac chan LCD theo 4bit cua cX
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}
#separate void lcd_LoadCGRAM() {// Load cac ky tu Graphic do nguoi dung dinh nghia vao bo nho cua LCD
//nhung no se mat di khi LCD reset hoac mat dien
/* this subroutine works specifically for 4-bit Port A */
// Define your Character 0 Hinh nguoi
lcd_send_byte( 0, 0x40 );// send command to User define Graphic CGRAM Character 0
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 1 Hinh ngoi sao
// lcd_send_byte( 0, 0x48 );// send command to User define Graphic CGRAM Character 1
lcd_send_byte( 1, 0b00000100 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00000000 );
lcd_send_byte( 1, 0b00000001 );
// Define your Character 2 My signature
// lcd_send_byte( 0, 0x50 );// send command to User define Graphic CGRAM Character 2
lcd_send_byte( 1, 0b00001100 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010010 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00001100 );
lcd_send_byte( 1, 0b00000101 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 3
// lcd_send_byte( 0, 0x58 );// send command to User define Graphic CGRAM Character 3
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 4
// lcd_send_byte( 0, 0x60 );// send command to User define Graphic CGRAM Character 4
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 5
// lcd_send_byte( 0, 0x68 );// send command to User define Graphic CGRAM Character 5
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 6
// lcd_send_byte( 0, 0x70 );// send command to User define Graphic CGRAM Character 6
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
// Define your Character 7
// lcd_send_byte( 0, 0x78 );// send command to User define Graphic CGRAM Character 7
lcd_send_byte( 1, 0b00001110 );// send 8 byte date for per line
lcd_send_byte( 1, 0b00010001 );
lcd_send_byte( 1, 0b00001110 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00011111 );
lcd_send_byte( 1, 0b00000100 );
lcd_send_byte( 1, 0b00001010 );
lcd_send_byte( 1, 0b00010001 );
}

Để sử dụng hàm khởi tạo này bạ chỉ cần thay địa chỉ chân LCD tương ứng theo khai báo ở trên .

Tạo 1 project trong CCS và thêm
#include "LCD420Tosy.C "
Trong hàm main

lcd_init();
lcd_clear();// Xoa man hinh
Lcd_gotoxy(1,3); // Cột 1 hàng 3
printf(lcd_putc,"Conecting ");// Gui 1 xau ra LCD
// Các bạn có thể sử dụng thư viện này vì khi thiết kế bạn có thể tùy biến thay đổi chân LCD nối với mạch giúp mạch đi dây dễ dàng và sử dụng hợp lý các chân VDK

dientudong
24-11-2008, 09:32 PM
// As defined in the following structure the pin connection is as follows:
// B0 enable
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
#define LCD_EN PIN_D4//PIN_B4
#define LCD_RS PIN_D5//PIN_B5
//#define LCD_RW PIN_B1
//#define LCD_UNUSED PIN_B1

#define LCD_D4 PIN_D3//PIN_B3//
#define LCD_D5 PIN_D2//PIN_B2
#define LCD_D6 PIN_D1//PIN_B1//
#define LCD_D7 PIN_D0//PIN_B0

Bạn cho mình hỏi chỗ này sao tùm lum kho hiểu vạy bạn:B5 rồi D5 gì tùm lum vậy, có nhầm lẫn gì không vậy

dientudong
24-11-2008, 09:42 PM
ở trên đã bảo là B1 rs , vậy ở dưới còn#define LCD_D6 PIN_D1//PIN_B1//.khó hiểu quá

dientudong
24-11-2008, 09:44 PM
Mình còn dốt quá nên mong các bạn giúp đỡ .rất cảm ơn.

ketxanh
24-11-2008, 11:42 PM
Mình còn dốt quá nên mong các bạn giúp đỡ .rất cảm ơn.

bạn ơi! khi phía trước có // có nghĩa là dó chỉ là chú thích, không có ý nghĩa trong mã lệnh. còn #define... sau đó là định nghĩa.

dientudong
26-11-2008, 12:34 AM
Bạn à ,vấn đề mình hỏi là sao chú thích gì mà lộn xộn vậy, hơi khó hiểu.