Hướng dẫn viết thư viện LCD16x2 cho PIC

Giới thiệu

Thiết bị hiển thị LCD (Liquid Crystal Display) được sử dụng trong rất nhiều các ứng dụng của Vi điều khiển. LCD có rất nhiều ưu điểm so với các dạng hiển thị khác: Nó có khả năng hiển thị kí tự đa dạng, trực quan (chữ, số và kí tự đồ họa), dễ dàng đưa vào mạch ứng dụng theo nhiều giao thức giao tiếp khác nhau, tốn rất ít tài nguyên hệ thống và giá thành rẻ.

Để hiển thị được LCD thì vi điều khiển phải thông qua con chip chuyên dùng thống thường đó là chip HD44780 của Hitachi. Khi sản xuất LCD, nhà sản xuất đã tích hợp chíp điều khiển (HD44780) bên trong lớp vỏ và chỉ đưa các chân giao tiếp cần thiết.

Hình 1. Sơ đồ chân của LCD

Bảng 1. Các chân trên module LCD và chức năng của chúng

Vss

Chân nối đất cho LCD, khi thiết kế mạch ta nối chân này với GND của mạch điều khiển.

Vdd

Chân cấp nguồn cho LCD, khi thiết kế mạch ta nối chân này với Vcc = 5V của mạch điều khiển.

Vee

Chân này dùng để điều chỉnh độ tương phản của LCD. Thông thường điện áp Vee được thay đổi bằng biến trở.

RS

Chân chọn thanh ghi (Register Select). Nối chân RS với logic “0” (GND) hoặc logic “1” (VCC) để chọn thanh ghi.

+ Logic “0”: Bus DB0-DB7 sẽnối với thanh ghi lệnh IR của LCD (ở chế độ”ghi” - write) hoặc nối với bộ đếm địa chỉ của LCD (ởchế độ”đọc” - read)

+ Logic “1”: Bus DB0-DB7 sẽ nối với thanh ghi dữ liệu DR bên trong LCD.

R/W

Chân chọn chế độ đọc/ghi (Read/Write).

+ Logic “0”: LCD hoạt động ởchế độ ghi.

+ Logic “1”: LCD ở chế độ đọc.

E

Chân cho phép (Enable). Sau khi các tín hiệu được đặt lên bus DB0-DB7, các lệnh chỉ được chấp nhận khi có 1 xung cho phép của chân E.

+ Ở chế độ ghi: Dữ liệu ở bus sẽ được LCD chuyển vào(chấp nhận) thanh ghi bên trong nó khi phát hiện một xung (high-to-low transition) của tín hiệu chân E.

+ Ở chế độ đọc: Dữ liệu sẽ được LCD xuất ra DB0-DB7 khi phát hiện cạnh lên (low to-high transition) ởchân E và được LCD giữ ở bus đến khi nào chân E xuống mức thấp

DB0 -DB7

Tám đường của bus dữ liệu dùng để trao đổi thông tin với MPU. Có 2 chế độ sử dụng 8 đường bus này :

+ Chế độ 8 bit : Dữ liệu được truyền trên cả 8 đường, với bit MSB là bit DB7.

+ Chế độ 4 bit : Dữ liệu được truyền trên 4 đường từ DB4 tới DB7, bit MSB là DB7

Thông thường sẽ dùng chế độ giao tiếp 4bit để tiết kiệm số lượng chân.

Hình 2. Sơ đồ kết nối LCD và Vi điều khiển PIC16F877A kiểu 4bit

Giao tiếp với HD44780.

Tiếp theo mình xin hướng dẫn chế độ giao tiếp 4 bit để hiển thị LCD dùng chip HD44780. Theo datasheet HD44780 thì đầu tiên phải cài đặt thông số ban đầu cho LCD trước khi cho nó làm việc, trình tự các bước như sau:

Bảng 2. Khởi tạo thông số ban đầu cho LCD

Bước

Công việc

0

Cấp điện cho LCD

1

Delay tối thiểu 15ms để điện áp cấp cho LCD lên 4.5V

2

Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 1 1

3

Delay tối thiêu 5ms

4

Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 1 1

5

Delay tối thiểu 100us

7

Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 1 1

8

Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 1 0

9

1 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 1 1

2 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 N F * *

10

1 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 0 0

2 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 1 0 0 0

11

1 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 0 0

2 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 0 1

12

1 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 0 0 0

2 - Set các bit tương ứng với mức logic:

RS R/W DB7 DB6 DB5 DB4

0 0 0 1 I/D S

Kết thúc khởi tạo LCD

Lưu ý:

  • N = 0; 1 hàng
  • F = 0; 5 × 8 dot font.
  • I/D =1 : Tăng
  • S=0 : Không dịch.

Thư viện LCD16x2 cho PIC

Thư viện LCD 16x2 đươc viết gồm 2 phần:

  • File LCD.h: là file header dùng để khai báo chân LCD sử dụng.
  • File LCD_Functions.c: là file chưa các hàm LCD.

LCD.h

Các chân của LCD được kết nối với chân nào của vi điều khiển thì khai báo trong file header này. Ví dụ: Chân E được kết nói với PIN_B5 của PIC…

ifndef LCD

define LCD

define LCDRS PINB3

define LCDRW PINB4

define LCDEN PINB5

define LCDD4 PIND4

define LCDD5 PIND5

define LCDD6 PIND6

define LCDD7 PIND7

endif

LCD_Fucntions.c

Trong file này chứa các hàm:

  • void LCD_Enable(void): Tạo xung Enable để giao tiếp với LCD.
  • void LCD_Send4Bit( unsigned char Data ): Truyền 4bit dữ liệu xuống LCD.
  • void LCD_SendCommand (unsigned char command ): Gửi 1 lệnh xuống LCD (Một lệnh thì có 8 bit dữ liệu)
  • void LCD_Init (void): Khởi tạo ban đầu cho LCD.
  • void LCD_PutChar ( unsigned char Data ): Hiển thị 1 ký tự lên LCD.
  • void LCD_Puts (char *s): Hiển thị một chuỗi lên LCD.
  • void LCD_Clear(): Xóa màn hình LCD
  • void LCD_Gotoxy(unsigned char row, unsigned char col): hiển thị bắt đầu tại vị trí hàng row, cột col

void LCD_Enable(void)

void LCDEnable(void) { outputhigh(LCDEN); delayus(3); outputlow(LCDEN); delay_us(50); }

void LCD_Send4Bit( unsigned char Data )

void LCDSend4Bit( unsigned char Data ) { outputbit(LCDD4,Data&0x01); outputbit(LCDD5,(Data>>1)&1); outputbit(LCDD6,(Data>>2)&1); outputbit(LCD_D7,(Data>>3)&1); }

void LCD_SendCommand (unsigned char command )

void LCDSendCommand (unsigned char command ) { LCDSend4Bit ( command >>4 );/* Gui 4 bit cao / LCDEnable () ; LCDSend4Bit ( command ); / Gui 4 bit thap*/ LCD_Enable () ; }

void LCD_Init (void)

void LCDInit (void) { outputlow(LCDRS); outputlow(LCDRW); delayms(20); LCDSend4Bit(0x03); LCDEnable(); delayms(10); LCDSend4Bit(0x03); LCDEnable(); delayms(10); LCDSend4Bit(0x03); LCDEnable(); delayms(10); LCDSend4Bit(0x02); LCDEnable(); delayms(10); LCDSendCommand( 0x28 ); // giao thuc 4 bit, hien thi 2 hang, ki tu 5x8
//Function Set: 8-bit, 1 Line, 5x7 Dots 0x30 //Function Set: 8-bit, 2 Line, 5x7 Dots 0x38 //Function Set: 4-bit, 1 Line, 5x7 Dots 0x20 //Function Set: 4-bit, 2 Line, 5x7 Dots 0x28 LCD
SendCommand( 0x0C); //Display on Cursor on: 0x0E 0x0F //Display on Cursor off: 0x0C //Display on Cursor blinking: 0x0F LCDSendCommand( 0x06 ); // tang ID, khong dich khung hinh Entry Mode LCDSendCommand( 0x01 ); // Clear Display (also clear DDRAM content) }

void LCD_PutChar ( unsigned char Data )

void LCDPutChar ( unsigned char Data ) { outputhigh(LCDRS); LCDSendCommand( Data ); outputlow(LCDRS); }

void LCD_Puts (char *s)

void LCDPuts (char s) { while (s) { LCDPutChar(*s); s++; } }

void LCD_Clear():

void LCDClear() { LCDSendCommand(0x01);
delay_ms(10); }

void LCD_Gotoxy(unsigned char row, unsigned char col)

void LCDGotoxy(unsigned char row, unsigned char col) { unsigned char address; if(!row) address = (0x80 + col); else address = (0xC0 + col); delayus(500); LCDSendCommand(address); delayus(50); }

Mô phỏng Proteus

Hình 3. Sơ đồ mô phỏng trong Proteus

Đoạn code demo

/* https://bmshop.vn Demo LCD for PIC16F877A */

include <16f877A.h>

device *=16 adc=10

fuses hs, nowdt, noprotect, nolvp, put, brownout

use delay(clock=20000000)

include #include // 4-Bits Interface

void main() { unsigned char line1[16], line2[16]; LCDInit(); delayms(10); sprintf(line1,” DEMO LCD 16x2 ”); sprintf(line2,” nvtienanh.com ”); while(TRUE) { LCDGotoxy(0,0); LCDPuts(line1); LCDGotoxy(1,0); LCDPuts(line2); delay_ms(500); }
}


Đăng bởi@nvtienanh
Không gì là không thể.

GitHubTwitterFacebookLinkedIn