Giao tiếp với LCD là phần ứng dụng quan trọng trong lập trình với PIC
Có 2 chế độ làm việc với LCD
- Chế độ 8 bit
- Chế độ 4 bit : ta thường làm cách này để tiết kiệm chân cho VĐK. Nhược điểm : tốc độ chậm hơn so với chế độ 8 bit.
LCD có 3 đường điều khiển:
Đường E cho phép hay không việc giao tiếp với LCD.
Nếu E=1 cho phép, sau đó kiểm tra trạng thái chân RS và RW.
Nếu E=0 cấm.
E khởi tạo quá trình truyền dữ liệu từ VĐK tới LCD.
Đường RS qui định dữ liệu/ lệnh được gửi tới LCD.
RS=1 Dữ liệu (kí tự) đang được viết lên LCD
RS=0 Lệnh đang được viết lên LCD
Đường RW - Qui định hướng truyền dữ liệu giữa LCD và VĐK.
Nếu RW=0 VĐK viết dữ liệu lên LCD.
RW=1 VĐK đọc dữ liệu từ LCD.
Để viết dữ liệu lên LCD cần thực hiện các bước theo trình tự như sau:
1.Kéo dây R/W =0
2.Đặt RS=0 hay RS=1 tùy mục đích gửi lệnh hay dữ liệu.
3.Đặt dữ liệu vào bus dữ liệu (RB4-RB7) (Nếu là quá trình viết).
4.Kéo E lên 1.
5.Kéo E xuống 0.
6.Đọc dữ liệu tại Bus dữ liệu (nếu là quá trình đọc).
Việc đọc dữ liệu từ LCD thực hiện tương tự như trên (Trường hợp này ít dùng).
Các kí tự được hiển thị trên LCD được lưu trong DDRAM (Display Data RAM).
Địa chỉ của các kí tự
Ta có thể định nghĩa các kí tự, các kí tự này được lưu trong CG RAM (Character
Generated RAM). CGRAM 64 bytes. Mỗi kí tự 8 bytes--> ta định nghĩa được
tối đa 8 kí tự.
Việc đọc/viết kí tự lên LCD tốn khoảng 40 us đến 120us. Trong khoảng thời gian này LCD "bận" , VĐK bó tay!
Do vậy trong chương trình ta cần thực hiện delay để LCD thực hiện công việc của mình.
Khởi tạo làm việc với LCD theo chế độ 4 bit.
1. Đợi 15ms sau khi cấp nguồn.
2. Viết 0x03 vào LCD và đợi 5ms để hoàn thành việc viết lệnh.
3. Viết 0x03 vào LCD và đợi 160us
4. Viết 0x03 vào LCD và đợi 160us.
5. Viết 0x02 vào LCD để chọn chế độ 4 bit.
Viết set interface length
Viết 0x010 để tắt hiển thị.
Viết 0x001 để xóa màn hình.
Đặt chế độ làm việc cho con trỏ(tùy bạn)
Để viết kí tự lên LCD các bạn cần có driver cho LCD. Ghi file này lcd_lib.c
[code:1]
#define LCD_RS PIN_A1
#define LCD_EN PIN_A0
#define LCD_D4 PIN_B4
#define LCD_D5 PIN_B5
#define LCD_D6 PIN_B6
#define LCD_D7 PIN_B7
// misc display defines-
#define Line_1 0x00
#define Line_2 0x40
#define Clear_Scr 0x01
// prototype statements
#separate void LCD_Init ( void );// ham khoi tao LCD
#separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
#separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
#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
// D/n Cong
#use standard_io ( B )
#use standard_io (A)
//khoi tao LCD**********************************************
#separate void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms(200); /* wait enough time after Vdd rise >> 15ms */
output_low ( LCD_RS );// che do gui lenh
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x01 ); /* clear display */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment & scroll left */
}
#separate void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
#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 void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}
#separate void LCD_PulseEnable ( void )
{
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 )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}
[/code:1]
Sơ đồ:
[code:1]
//************************************************** ***
//CHUONG TRINH HIEN THI CHU LEN LCD
//date:29/07/2005
//typewriter:noisepic@gmail.com
//status: Hien thi chu len LCD+OK
//Mo ta:A1 noi voi RS
// A0 noi voi Enable
// B4,B5,B6,B7 noi voi D4,D5,D6,D7 tuong ung
//************************************************** ****
#include<16f84a.h>
#use delay(clock=4000000)
#fuses NOWDT,PUT,HS,NOPROTECT
#include<lcd_lib.c>
main()
{
lcd_init();
while(1)
{
lcd_PutCmd(Clear_Scr);
lcd_setposition(LINE_1+3);
printf(lcd_putchar,"noisepic");
lcd_SetPosition(LINE_2+1);
printf(lcd_PutChar,"PICVIETNAM") ;
}
}
//*************************************************
[/code:1]
Xung giao tiếp giữa LCD và PIC trong chế độ 4 bit
Phần này noisepic không hiểu lắm!
Có 2 chế độ làm việc với LCD
- Chế độ 8 bit
- Chế độ 4 bit : ta thường làm cách này để tiết kiệm chân cho VĐK. Nhược điểm : tốc độ chậm hơn so với chế độ 8 bit.
LCD có 3 đường điều khiển:
Đường E cho phép hay không việc giao tiếp với LCD.
Nếu E=1 cho phép, sau đó kiểm tra trạng thái chân RS và RW.
Nếu E=0 cấm.
E khởi tạo quá trình truyền dữ liệu từ VĐK tới LCD.
Đường RS qui định dữ liệu/ lệnh được gửi tới LCD.
RS=1 Dữ liệu (kí tự) đang được viết lên LCD
RS=0 Lệnh đang được viết lên LCD
Đường RW - Qui định hướng truyền dữ liệu giữa LCD và VĐK.
Nếu RW=0 VĐK viết dữ liệu lên LCD.
RW=1 VĐK đọc dữ liệu từ LCD.
Để viết dữ liệu lên LCD cần thực hiện các bước theo trình tự như sau:
1.Kéo dây R/W =0
2.Đặt RS=0 hay RS=1 tùy mục đích gửi lệnh hay dữ liệu.
3.Đặt dữ liệu vào bus dữ liệu (RB4-RB7) (Nếu là quá trình viết).
4.Kéo E lên 1.
5.Kéo E xuống 0.
6.Đọc dữ liệu tại Bus dữ liệu (nếu là quá trình đọc).
Việc đọc dữ liệu từ LCD thực hiện tương tự như trên (Trường hợp này ít dùng).
Các kí tự được hiển thị trên LCD được lưu trong DDRAM (Display Data RAM).
Địa chỉ của các kí tự
Ta có thể định nghĩa các kí tự, các kí tự này được lưu trong CG RAM (Character
Generated RAM). CGRAM 64 bytes. Mỗi kí tự 8 bytes--> ta định nghĩa được
tối đa 8 kí tự.
Việc đọc/viết kí tự lên LCD tốn khoảng 40 us đến 120us. Trong khoảng thời gian này LCD "bận" , VĐK bó tay!
Do vậy trong chương trình ta cần thực hiện delay để LCD thực hiện công việc của mình.
Khởi tạo làm việc với LCD theo chế độ 4 bit.
1. Đợi 15ms sau khi cấp nguồn.
2. Viết 0x03 vào LCD và đợi 5ms để hoàn thành việc viết lệnh.
3. Viết 0x03 vào LCD và đợi 160us
4. Viết 0x03 vào LCD và đợi 160us.
5. Viết 0x02 vào LCD để chọn chế độ 4 bit.
Viết set interface length
Viết 0x010 để tắt hiển thị.
Viết 0x001 để xóa màn hình.
Đặt chế độ làm việc cho con trỏ(tùy bạn)
Để viết kí tự lên LCD các bạn cần có driver cho LCD. Ghi file này lcd_lib.c
[code:1]
#define LCD_RS PIN_A1
#define LCD_EN PIN_A0
#define LCD_D4 PIN_B4
#define LCD_D5 PIN_B5
#define LCD_D6 PIN_B6
#define LCD_D7 PIN_B7
// misc display defines-
#define Line_1 0x00
#define Line_2 0x40
#define Clear_Scr 0x01
// prototype statements
#separate void LCD_Init ( void );// ham khoi tao LCD
#separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
#separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
#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
// D/n Cong
#use standard_io ( B )
#use standard_io (A)
//khoi tao LCD**********************************************
#separate void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms(200); /* wait enough time after Vdd rise >> 15ms */
output_low ( LCD_RS );// che do gui lenh
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x01 ); /* clear display */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment & scroll left */
}
#separate void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
#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 void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}
#separate void LCD_PulseEnable ( void )
{
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 )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}
[/code:1]
Sơ đồ:
[code:1]
//************************************************** ***
//CHUONG TRINH HIEN THI CHU LEN LCD
//date:29/07/2005
//typewriter:noisepic@gmail.com
//status: Hien thi chu len LCD+OK
//Mo ta:A1 noi voi RS
// A0 noi voi Enable
// B4,B5,B6,B7 noi voi D4,D5,D6,D7 tuong ung
//************************************************** ****
#include<16f84a.h>
#use delay(clock=4000000)
#fuses NOWDT,PUT,HS,NOPROTECT
#include<lcd_lib.c>
main()
{
lcd_init();
while(1)
{
lcd_PutCmd(Clear_Scr);
lcd_setposition(LINE_1+3);
printf(lcd_putchar,"noisepic");
lcd_SetPosition(LINE_2+1);
printf(lcd_PutChar,"PICVIETNAM") ;
}
}
//*************************************************
[/code:1]
Xung giao tiếp giữa LCD và PIC trong chế độ 4 bit
Phần này noisepic không hiểu lắm!
Comment