Đăng vào

MPLAB XC8: Lập trình LCD

Giới thiệu

Trong bài hướng dẫn này, chúng ta sẽ học cách lập trình hiển thị LCD 16x2 bằng PIC 16F877A trên MPLAB X IDE dùng MPLAB XC8. LCD 16x2 là một thiết bị hiển thị cơ bản thường được dùng để giao tiếp với người dùng thông qua việc hiển thị. LCD 16x2 gồm 2 dòng, mỗi dòng có thể hiển thị được 16 ký tự, ngoài ra còn có nhiều loại LCD khác nhau như 16x1, 16x4… với LCD này mỗi ký tự được hiển thị bởi một ma trận điểm 5x8 hoặc 5x10.

Để điều khiển được LCD chúng ta cần biết được cấu trúc phần cứng của LCD. Các loại LCD thông thường dùng IC HD44780 để quản lý việc hiển thị. Các bạn có thể xem thêm datasheet của con HD44780 để hiểu nguyên lý làm việc của nó. Ở bài hướng dẫn này sẽ cung cấp thư viện LCD bao gồm các lệnh cơ bản giúp việc lập trình trở nên thuận tiện và đơn giản hơn, vì vậy các bạn không nhất thiết phải tự viết thư viện cho mình.

Như ở hình trên, chân GND và VCC chính là chân đất và chân nguồn dương cấp cho LCD. Chân thứ 3 – VEE dùng để điều chỉnh độ sáng cho LCD, thông thường chân này được nối với một biến trở để cho phép điều chỉnh độ sáng của LCD. Vi điều khiển cần truyền dữ liệu cho LCD để nó có thể hiển thị, dữ liệu truyền xuống gồm 2 phần:

  • Data: là mã ASCII của ký tự cần hiển thị lên màn hình LCD
  • Command: Lệnh yêu cầu LCD thực thi, ví dụ như xóa màn hình, dịch màn hình, vị trí hiển thị…

Lệnh được truyền xuống LCD qua chân dữ liệu (DB0 – DB7) và được điều khiển bằng chân RS (Register Select). Khi chân RS ở mức 1 LCD hiển thị Data nhận được từ chân DB0 – DB7, ngược lại nếu chân RS ở mức 0, LCD nhận Command từ chân DB0 – DB7. Chân EN (Enable) ở mức 1 (5V) cho phép LCD hoạt động, nếu ở mức 0 (GND) thì LCD không hoạt động. Chân R/W (Read/Write) dùng để cài đặt chế độ đọc (hoặc ghi) dữ liệu của LCD. Thông thường chúng ta chỉ ghi dữ liệu vào LCD nên chân R/W được nối đát

Giao tiếp với LCD gồm có 2 kiểu truyền: truyền một lúc 8bit hoặc truyền thành từng phần, mỗi phần có 4bit dữ liệu. Ở chế độ truyền 8 bit, chúng ta sử dụng 8 chân của LCD DB0-DB7, dữ liệu truyền xuống gồm 4 bit data và 4 bit commands. Ở chế độ truyền 4 bit chỉ sử dụng 4 chân của LCD và mỗi lần truyền xuống chỉ có 4 bit dữ liệu, do chỉ dùng 4 chân tín hiệu nên chế độ này thường được sử dụng nhằm tiết kiệm chân của vi điều khiển. Chế độ truyền 4 bit sẽ chậm hơn so với truyền 8 bit nhưng do tốc độ thực thi của LCD thấp hơn so với tốc độ xử lý của vi điều khiển (tầm MHz) và mắt thường của chúng ta chỉ xử lý được 24 hình/s nên sự khác biệt về tốc độ đó không ảnh hưởng đến việc hiển thị lên LCD.

Sơ đồ mạch điện

LCD Library

  • Lcd_Init() : Hàm này cấu hình các thông số ban đầu để có thể sử dụng thư viện LCD
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7
  • Lcd_Clear() : Hàm này xóa màn hình LCD
  • Lcd_Set_Cursor(int row, int column) : Hàm này dùng để di chuyển con trỏ hiển thị đến vị trí mong muốn với row – hàng và column – cột.
  • Lcd_Write_Char(char) : Hàm này dùng để ghi một ký tự lên LCD.
  • Lcd_Write_String(char *string) : Hàm này dùng để ghi một chuỗi lên LCD.
  • Lcd_Shift_Right() : Hàm này dùng để dịch dữ liệu hiển thị trên LCD sàng bên phải khi dữ liệu hiển thị dài hơn 16 ký tự
  • Lcd_Shift_Left() : Hàm này dùng để dịch dữ liệu hiển thị trên LCD sàng bên trái khi dữ liệu hiển thị dài hơn 16 ký tự

Note : The Pins to which LCD is connecting should be configured as Output Pins by writing to TRIS Register.

MPLAB XC8 Code

#define _XTAL_FREQ 8000000

#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7

#include "lcd.h";

// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG

int main()
{
    unsigned int a;
    TRISD = 0x00;
    Lcd_Init();
    while(1)
    {
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("LCD Library for");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("MPLAB XC8");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("Developed By");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("nvtienanh");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("https://bmshop.vn");

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Left();
        }

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Right();
        }

        Lcd_Clear();
        Lcd_Set_Cursor(2,1);
        Lcd_Write_Char('e');
        Lcd_Write_Char('S');
        __delay_ms(2000);
    }
    return 0;
}

Cách dùng hàm sprintf()

Hàm sprintf() dùng để ghi giá trị của một biến ra kiểu chuỗi (string). Hàm này được dùng trong thư viện LCD để hiển thị một số dạng interger, float… trên LCD một cách đơn giản

Cú pháp

sprintf(char * str, const char * format, ...);

Trong đó:

  • str là con trỏ kiểu char dùng để lưu chuỗi cần hiển thị.
  • format là một ký tự cho biết kiểu dữ liệu của biến cần chuyển sang kiểu string.
  • … (additional arguments) là các cài đặt thêm cho các trường hợp khác

Các kiểu biến dùng cho hàm sprintf()

Ví dụ:

....
float f = 1.414;
int a = 56;
char s[20];
....

....
sprintf(s, "Float = %f", f);
Lcd_Set_Cursor(1,1);
Lcd_Write_String(s);
sprintf(s, "Integer = %d", a);
Lcd_Set_Cursor(2,1);
Lcd_Write_String(s);

Kết quả thu được