Thiết kế ứng dụng sử dụng hình tinh thể lỏng (LCD) Nguyên tắc hiển thị ký tự LCD LCD hình gồm nhiều điểm ảnh Có nhiều loại LCD, chúng tìm hiểu loại LCD 16×2 thiết kế dựa điều khiển HD44780 Hitachi Loại LCD 16x2 gồm hàng, hàng có 16 vị trí cho phép hiển thị 16 ký tự Mỗi vị trí có cột x hàng = 35 điểm ảnh (pixel) Hiển thị ký tự khác thực chất làm cho điểm ảnh sáng/tắt tạo thành hình tương ứng (do điều khiển HD44780 thực hiện) LCD gồm 14 chân, ý nghĩa chân sau: Bảng Chức chân LCD 16x2 ký tự Chân số Ký hiệu Mức logic I/O Vss Vcc Vee RS 0/1 I I RW 0/1 I 10 11 12 13 14 E D0 D1 D2 D3 D4 D5 D6 D7 1->0 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 I I/O I/O I/O I/O I/O I/O I/O I/O Chức Nguồn cung cấp (GND) Nguồn cung cấp (+5V) Điện áp vào để điều chỉnh độ tương phản Lựa chọn ghi = Thanh ghi lệnh = Thanh ghi liệu = Ghi vào LCD module = Đọc từ LCD module Tín hiệu cho phép ghi/đọc Bus liệu, bit (LSB) Bus liệu, bit Bus liệu, bit Bus liệu, bit Bus liệu, bit Bus liệu, bit Bus liệu, bit Bus liệu, bit (MSB) Điều khiển hiển thị ký tự LCD thực chất gửi mã lệnh, gửi byte liệu chứa mã ký tự cần hiển thị tới điều khiển HD44780, mã lệnh liệt kê Bảng Bảng Các mã lệnh LCD 16x2 ký tự Mã lệnh 0x01 0x02 0x06 0x0C 0x0E 0x80 0xC0 0x38 0x28 Chức Xóa hình Đưa trỏ đầu dịng Tự động đưa trỏ đến vị trí (theo thứ tự từ trái sang phải) để hiển thị ký tự VĐK gửi cho LCD ký tự để hiển thị, gọi hiển thị dịch Bật hiển thị, tắt trỏ Bật hiển thị, bật trỏ Đưa trỏ đầu dòng thứ Đưa trỏ đầu dòng thứ hai Giao tiếp với VĐK chân (D0-D7) Giao tiếp với VĐK chân (D4-D7) Thời gian thực 1.52 ms 1.52 ms 37µs 37µs 37µs 37µs 37µs 37µs 37µs 1.1 Trình tự ghi lệnh Ghi lệnh, cụ thể gửi lệnh cho LCD (bản chất gửi cho chip HD44780) thực theo trình tự sau: (1) Đặt chân RW mức thấp (“0”) để chọn chế độ ghi (2) Đặt chân RS mức thấp (“0”) để chọn ghi lệnh (3) Đặt chân E mức cao (“1”) để chuẩn bị tạo chuyển mức logic từ “1” sang “0” nhằm tạo tín hiệu cho phép ghi (4) Gửi byte mã lệnh từ VĐK tới chân liệu D0-D7 LCD (5) Đặt chân E mức thấp (“0”) để hoàn tất tạo chuyển mức logic từ “1” sang “0” (6) Trễ khoảng thời gian (bảng 2) Vì cần xuất Byte liệu nên cần sử dụng hàm LCD_DATA void LCD_DATA(unsigned char data) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7, } data&0x01); (data>>1)&0x01); (data>>2)&0x01); (data>>3)&0x01); (data>>4)&0x01); (data>>5)&0x01); (data>>6)&0x01); (data>>7)&0x01); Vì cần ghi nhiều lệnh trình hiển thị nên cần viết hàm ghi lệnh Ví dụ với mạch điện hình 1, chân RS, RW, E, D0-D7(bus liệu) kết nối với PORT B Và hàm ghi lệnh viết sau: void Lcd_Ghi_Lenh (char command) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);//RS=0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//LCD_RW=0; HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);//LCD_EN = 1; LCD_DATA(command); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);//LCD_EN=0; HAL_Delay(10); //10ms } Sau có hàm Lcd_Ghi_Lenh, muốn xóa LCD viết: Lcd_Ghi_Lenh (0x01); 1.2 Trình tự ghi liệu Ghi liệu, cụ thể gửi byte chữa mã ký tự cần hiển thị cho LCD (bản chất gửi cho chip HD44780) thực theo trình tự sau: (1) Đặt chân RW mức thấp (“0”) để chọn chế độ ghi (2) Đặt chân RS mức cao (“1”) để chọn ghi liệu (3) Đặt chân E mức cao (“1”) để chuẩn bị tạo chuyển mức logic từ “1” sang “0” nhằm tạo tín hiệu cho phép ghi (4) Gửi byte chứa mã ký tự cần hiển thị từ VĐK tới chân liệu D0-D7 LCD (5) Đặt chân E mức thấp (“0”) để hoàn tất tạo chuyển mức logic từ “1” sang “0” (6) Trễ khoảng thời gian (bảng 2) Vì cần hiển thị nhiều ký tự nên cần viết hàm ghi liệu, ví dụ: void Lcd_Ghi_Dulieu (char data) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);//RS=1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//LCD_RW=0; HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);// LCD_EN= 1; LCD_DATA(data); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);//LCD_EN= 0; HAL_Delay(10); //10ms } Mã ký tự liệt kê bảng Ví dụ mã ký tự “A” 0b01000001=0x41, muốn hiển thị “A” viết: Lcd_Ghi_Dulieu (0x41); Lcd_Ghi_Dulieu (‘A’); Bảng Mã ký tự LCD Lập trình tự hiển thị LCD 2.1 Các bước lập trình hiển thị LCD Một chương trình hiển thị ký tự LCD gồm bước sau: Khởi tạo LCD Ví dụ: void Lcd_Cauhinh (void) { Lcd_Ghi_Lenh(0x38);// Giao tiếp với VĐK chân Lcd_Ghi_Lenh(0x06);/* Tự động đưa trỏ đến vị trí (hiển thị dịch)*/ Lcd_Ghi_Lenh(0x0c);// Bật hiển thị, tắt trỏ Lcd_Ghi_Lenh(0x01); // Xóa hình } Đặt vị trí trỏ (vị trí cần hiển thị) Ví dụ: Lcd_Ghi_Lenh (0x81); /*vị trí thứ (từ trái sang), dịng thứ nhất*/ Hiển thị ký tự Ví dụ: Lcd_Ghi_Dulieu(0x61); //hiển thị “a” Hoặc Lcd_Ghi_Dulieu(‘a’); //hiển thị “a” Chú ý: - Các bước 2, lặp lại nhiều lần cần hiển thị nhiều ký tự - Chế độ hiển thị mặc định hiển thị dịch, vị trí trỏ mặc định đầu dòng thứ 2.2 Các ví dụ lập trình điều khiển hiển thị LCD Ví dụ 1: Cho sơ đồ mạch điện hình Viết chương trình hiển ký tự AA dòng thứ nhất, ký tự “aa” dịng thứ hai LCD Hình Sơ đồ mạch điện mô điều khiển hiển thị LCD 16x2 Hình Sơ đồ mạch điện điều khiển hiển thị LCD 16x2 Gợi ý thực : - Chọn chiều số cho PORTB - Xây dựng hàm “Lcd_Ghi_Lenh” hàm “Lcd_Ghi_Dulieu” (mục 1) - Xây dựng hàm “Lcd_Cauhinh” để khởi tạo cho LCD (mục 2.1) Chương trình tham khảo: #include "main.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); void void void void { Lcd_Cauhinh(void);//KHOI TAO LCD Lcd_Ghi_Lenh(char lenh);//GHI LENH Lcd_Ghi_Dulieu(char data);//GHI DATA LCD_DATA(unsigned char data) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6, HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7, data&0x01); (data>>1)&0x01); (data>>2)&0x01); (data>>3)&0x01); (data>>4)&0x01); (data>>5)&0x01); (data>>6)&0x01); (data>>7)&0x01); } void Lcd_Cauhinh (void) { Lcd_Ghi_Lenh(0x03); Lcd_Ghi_Lenh(0x38); Lcd_Ghi_Lenh(0x06); Lcd_Ghi_Lenh(0x0c); Lcd_Ghi_Lenh(0x01); } void Lcd_Ghi_Lenh (char lenh) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);//RS=0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//LCD_RW=0; HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);//LCD_EN= 1; LCD_DATA(lenh); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);//LCD_EN= 0; HAL_Delay(10); //10ms } void Lcd_Ghi_Dulieu (char data) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);//RS=1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//LCD_RW=0; HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);// LCD_EN=1; LCD_DATA(data); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);//LCD_EN = 0; HAL_Delay(10); //10ms } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); Lcd_Cauhinh(); while (1) { Lcd_Ghi_Lenh(0X80);//dau dong Lcd_Ghi_Dulieu(0x41); Lcd_Ghi_Dulieu('A'); Lcd_Ghi_Lenh(0XC0);//dau dong Lcd_Ghi_Dulieu(0x61); Lcd_Ghi_Dulieu('a'); } } Ví dụ 2: Viết chương trình hiển thị chuỗi ký tự “KHOA DIEN TU” dòng thứ nhất; HAUI dòng thứ Gợi ý thực : - Các bước thực ví dụ - Một số điểm cần lưu ý: + Sử dụng hàm Lcd_Ghi_chuoi hiển thị chuỗi ký tự LCD (đọc lại kiến thức trỏ C) Dưới số điểm cần lưu ý chương trình: #include "main.h" … … void Lcd_Ghi_Chuoi (char *str) { while(*str) { Lcd_Ghi_Dulieu(*str); str++; } } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); Lcd_Cauhinh(); while (1) { Lcd_Ghi_Lenh(0X80);//dau dong Lcd_Ghi_Chuoi("KHOA DIEN TU"); Lcd_Ghi_Lenh(0XC0);//dau dong Lcd_Ghi_Chuoi("HAUI"); } } Ví dụ 3: Viết chương trình hiển thị số nguyên, số thực LCD Gợi ý thực : - Các bước thực ví dụ - Một số điểm cần lưu ý: + Sử dụng hàm sprintf khai báo mảng char M[16]; + Khai báo biến số nguyên, biến số thực Dưới số điểm cần lưu ý chương trình: char M[16]; unsigned int i,j; float f; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); Lcd_Cauhinh(); i=10; j=12; f=3.14; while (1) { Lcd_Ghi_Lenh(0X80); sprintf(&M[0],"i=%d",i);//hiển thị số nguyên Lcd_Ghi_Chuoi(&M[0]); Lcd_Ghi_Lenh(0X89); sprintf(&M[0],"j=%d",j); Lcd_Ghi_Chuoi(&M[0]); Lcd_Ghi_Lenh(0XC0); sprintf(&M[0],"f=%.2f",f);/*hiển thị số thực sau dấu phảy số*/ } } Lcd_Ghi_Chuoi(&M[0]); Bài tập Cho sơ đồ mạch điện hình dưới, viết chương trình mơ đếm sản phẩm 02 dây chuyền hiển thị số sản phẩm dòng LCD Giả thiết sản phẩm qua cảm biến tạo thay đổi “1”->”0” PB0 PB1 tương tự nhấn PB1, PB2 ... SystemClock_Config(void); static void MX_GPIO_Init(void); void void void void { Lcd_ Cauhinh(void);//KHOI TAO LCD Lcd_Ghi_Lenh(char lenh);//GHI LENH Lcd_ Ghi_Dulieu(char data);//GHI DATA LCD_ DATA(unsigned char data)... trình hiển ký tự AA dòng th? ?? nhất, ký tự “aa” dịng th? ?? hai LCD Hình Sơ đồ mạch điện mô điều khiển hiển th? ?? LCD 16x2 Hình Sơ đồ mạch điện điều khiển hiển th? ?? LCD 16x2 Gợi ý th? ??c : - Chọn chiều số... viết: Lcd_ Ghi_Dulieu (0x41); Lcd_ Ghi_Dulieu (‘A’); Bảng Mã ký tự LCD Lập trình tự hiển th? ?? LCD 2.1 Các bước lập trình hiển th? ?? LCD Một chương trình hiển th? ?? ký tự LCD gồm bước sau: Khởi tạo LCD