• Display Custom Characters on 16x2 LCD using PIC Microcontroller and XC8 - Hiển thị các ký tự tùy chỉnh trên màn hình LCD 16x2 bằng Vi điều khiển PIC và XC8

QC

Display Custom Characters on 16x2 LCD using PIC Microcontroller and XC8 - Hiển thị các ký tự tùy chỉnh trên màn hình LCD 16x2 bằng Vi điều khiển PIC và XC8

 


Trong hướng dẫn trước của chúng tôi, chúng ta đã học Cách giao diện màn hình LCD 16 * 2 với Vi điều khiển PIC. Chúng tôi khuyên bạn nên xem qua nó trước khi tiếp tục, nếu bạn là người mới bắt đầu sử dụng vi điều khiển PIC. Trước đây chúng ta cũng đã tìm hiểu những kiến ​​thức cơ bản về PIC sử dụng Chương trình nhấp nháy LED và Bộ định thời trong Vi điều khiển PIC. Bạn có thể xem ở đây tất cả các hướng dẫn về Học vi điều khiển PIC bằng trình biên dịch MPLABX và XC8.


Trong hướng dẫn này, hãy để chúng tôi làm cho nó thú vị hơn bằng cách tạo các ký tự tùy chỉnh của riêng chúng tôi và hiển thị chúng trên màn hình LCD của chúng tôi bằng Vi điều khiển PIC PIC16F877A. Ngoài ra, có một số ký tự tùy chỉnh được sử dụng chủ yếu được xác định trước do chính vi mạch HD44780A đưa ra, chúng tôi cũng sẽ xem cách chúng tôi có thể sử dụng chúng. Như đã giải thích trong hướng dẫn trước của chúng tôi, màn hình LCD của chúng tôi có bộ điều khiển Hitachi HD44780 được nhúng trên đó giúp chúng tôi hiển thị các ký tự. Mỗi ký tự mà chúng tôi hiển thị đã được xác định trước bên trong ROM của HD44780 IC. Chúng ta sẽ tìm hiểu về IC điều khiển LCD HD44780, trước khi hiển thị ký tự trên LCD.

16x2 Dot Matrix LCD Controller IC HD44780:

Để hiển thị một ký tự tùy chỉnh, bằng cách nào đó chúng ta phải nói với IC rằng ký tự tùy chỉnh sẽ trông như thế nào. Để làm được điều đó, chúng ta nên biết về Ba loại Ký ức hiện diện bên trong IC điều khiển LCD HD44780:

Bộ tạo ký tự ROM (CGROM): Nó là bộ nhớ chỉ đọc, như đã nói ở trên, chứa tất cả các mẫu của các ký tự được xác định trước bên trong nó. ROM này sẽ khác nhau tùy theo từng loại IC giao diện và một số có thể có một số ký tự tùy chỉnh được xác định trước với chúng.

Display Data RAM (DDRAM): Đây là bộ nhớ truy cập ngẫu nhiên. Mỗi khi chúng ta hiển thị một ký tự, mẫu của nó sẽ được lấy từ CGROM và chuyển sang DDRAM và sau đó sẽ được đưa lên màn hình. Nói một cách đơn giản, DDRAM sẽ có các mẫu của tất cả các ký tự hiện đang được hiển thị trên Màn hình LCD. Bằng cách này cho mỗi chu kỳ, vi mạch không cần lấy dữ liệu từ CGROM và giúp nhận được tần suất cập nhật ngắn

Bộ tạo ký tự RAM (CGRAM): Đây cũng là bộ nhớ truy cập ngẫu nhiên, vì vậy chúng ta có thể ghi và đọc dữ liệu từ nó. Như tên của nó, bộ nhớ này sẽ là bộ nhớ có thể được sử dụng để tạo ký tự tùy chỉnh. Chúng ta phải tạo một mẫu cho ký tự và viết nó trong CGRAM, mẫu này có thể được đọc và hiển thị trên Màn hình khi được yêu cầu.

Bây giờ, chúng ta đã hiểu cơ bản về các loại Bộ nhớ có trong IC giao diện HD44780. Hãy để chúng tôi xem qua biểu dữ liệu của nó để hiểu thêm một chút.


Như, biểu dữ liệu ngụ ý, HD44780 IC đã cung cấp 8 Vị trí để lưu trữ các mẫu tùy chỉnh của chúng tôi trong CGRAM, ngoài ra ở bên phải chúng ta có thể thấy rằng có một số ký tự được xác định trước cũng có thể được hiển thị trên Màn hình LCD của chúng tôi. Hãy để chúng tôi xem chúng tôi có thể làm điều đó như thế nào.

Displaying a Custom Character on 16x2 LCD:

Để hiển thị một ký tự tùy chỉnh, trước tiên chúng ta phải tạo một mẫu cho nó và sau đó lưu nó vào CGRAM. Vì chúng ta đã có sẵn các hàm thư viện nên sẽ dễ dàng thực hiện việc này bằng một số lệnh đơn giản. Đây là Thư viện cho các hàm LCD, nhưng ở đây chúng tôi đã sao chép dán tất cả các hàm Thư viện trong chính chương trình, vì vậy không cần đưa tệp tiêu đề này vào chương trình của chúng tôi. Ngoài ra, hãy kiểm tra bài viết này để biết LCD cơ bản hoạt động và các sơ đồ chân của nó.

Bước đầu tiên là tạo một mẫu hoặc ký tự tùy chỉnh. Như chúng ta đã biết, mỗi ký tự là sự kết hợp của 5 * 8 dấu chấm. Chúng tôi phải chọn điểm (pixel) nào nên tăng cao và điểm nào nên ở mức thấp. Đơn giản chỉ cần vẽ một hộp như bên dưới và tô bóng các vùng dựa trên nhân vật của bạn. Nhân vật của tôi ở đây là một người đàn ông dính (hy vọng nó giống như một). Sau khi được tô bóng, hãy ghi giá trị nhị phân tương đương của mỗi byte như hình dưới đây.

Chỉ cần đặt ‘1’ trên vùng được tô bóng và ‘0’ trên vùng không được tô bóng cho mỗi byte, và đó là mẫu tùy chỉnh của chúng tôi đã sẵn sàng. Tương tự, tôi đã tạo 8 mã mẫu tùy chỉnh cho 8 không gian bộ nhớ của chúng tôi, trình bày nó là CGROM. Chúng được liệt kê trong bảng dưới đây.


Programming and Working Explanation:

Bây giờ mã mẫu của chúng ta đã sẵn sàng, chúng ta chỉ cần tải chúng vào CGRAM của LCD và hiển thị chúng bằng vi điều khiển PIC. Để tải chúng vào CGRAM, chúng ta có thể tạo một mảng 5 * 8 các phần tử và tải từng byte bằng cách sử dụng "vòng lặp for". Dãy mã mẫu được hiển thị bên dưới:


const unsigned short Custom_Char5x8[] = {
  0b01110,0b01110,0b00100,0b01110,0b10101,0b00100,0b01010,0b01010, // Code for CGRAM memory space 1
  0b00000,0b00000,0b01010,0b00100,0b00100,0b10001,0b01110,0b00000, // Code for CGRAM memory space 2
  0b00100,0b01110,0b11111,0b11111,0b01110,0b01110,0b01010,0b01010, // Code for CGRAM memory space 3
  0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111,0b00000, // Code for CGRAM memory space 4
  0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111,0b00000, // Code for CGRAM memory space 5
  0b00000,0b10001,0b01010,0b10001,0b00100,0b01110,0b10001,0b00000, // Code for CGRAM memory space 6
  0b00000,0b00000,0b01010,0b10101,0b10001,0b01110,0b00100,0b00000, // Code for CGRAM memory space 7
  0b11111,0b11111,0b10101,0b11011,0b11011,0b11111,0b10001,0b11111  // Code for CGRAM memory space 8
};

Mỗi không gian bộ nhớ được tải với mẫu ký tự được tôn trọng của nó. Để tải mẫu này vào HD44780 IC, bảng dữ liệu của HD44780 phải được tham chiếu, nhưng nó chỉ là các dòng lệnh có thể được sử dụng để đặt địa chỉ của CGRAM



//*** Load custom char into the CGROM***//////
  Lcd_Cmd(0x04);   // Set CGRAM Address
  Lcd_Cmd(0x00);   // .. set CGRAM Address
  for (i = 0; i <= 63 ; i++)
    Lcd_Print_Char(Custom_Char5x8[i]);
  Lcd_Cmd(0);      // Return to Home
  Lcd_Cmd(2);      // .. return to Home
  //*** Loading custom char complete***//////

Ở đây, bên trong ‘vòng lặp for’ mỗi giá trị nhị phân được tải vào CGROM. Sau khi mẫu được tải, các ký tự tùy chỉnh có thể được hiển thị bằng cách chỉ cần gọi vị trí của mẫu bằng cách sử dụng hàm void Lcd_Print_Char (char data) như hình bên dưới. Lcd_Print_Char(0); // Display Custom Character 0

    Lcd_Print_Char(1); // Display Custom Character 1
    Lcd_Print_Char(2); // Display Custom Character 2
    Lcd_Print_Char(3); // Display Custom Character 3
    Lcd_Print_Char(4); // Display Custom Character 4
    Lcd_Print_Char(5); // Display Custom Character 5
    Lcd_Print_Char(6); // Display Custom Character 6
    Lcd_Print_Char(7); // Display Custom Character 7


Print Predefined Special Character:


IC HD44780 có một số ký tự đặc biệt được xác định trước được lưu trữ trong DDROM. Các ký tự này có thể được in trực tiếp lên màn hình bằng cách tham chiếu đến giá trị nhị phân của nó trong biểu dữ liệu.

Ví dụ: Giá trị nhị phân của ký tự "ALPHA" là 0b11100000. Làm thế nào để có được điều này có thể được hiểu trong hình dưới đây, tương tự như vậy bạn có thể nhận được giá trị cho bất kỳ ký tự đặc biệt nào được xác định trước trong IC.



Sau khi biết giá trị nhị phân, ký tự tương ứng có thể được in ra màn hình bằng cách sử dụng hàm void Lcd_Print_Char (char data) như hình dưới đây,

Lcd_Print_Char(0b11100000); //binary value of alpha from data-sheet
Mã hoàn chỉnh của dự án này được đưa ra bên dưới trong phần Mã, hãy xem phần giải thích Video chi tiết ở cuối hướng dẫn này.


Circuit Connections and Testing:

Dự án này không có bất kỳ yêu cầu phần cứng bổ sung nào, chúng tôi chỉ sử dụng các kết nối tương tự từ hướng dẫn giao diện LCD trước đó và sử dụng cùng một bảng mà chúng tôi đã tạo trong Hướng dẫn nhấp nháy đèn LED. Như mọi khi, chúng ta hãy mô phỏng chương trình bằng Proteus để xác minh đầu ra của chúng tôi.







CODE :

#define _XTAL_FREQ 20000000

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

#include <xc.h>

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#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)

//LCD Functions Developed by Circuit Digest.

/*******START OF LCD FUNCTIONS*********/
void Lcd_SetBit(char data_bit) //Based on the Hex value Set the Bits of the Data Lines
{
    if(data_bit& 1) 
        D4 = 1;
    else
        D4 = 0;

    if(data_bit& 2)
        D5 = 1;
    else
        D5 = 0;

    if(data_bit& 4)
        D6 = 1;
    else
        D6 = 0;

    if(data_bit& 8) 
        D7 = 1;
    else
        D7 = 0;
}

void Lcd_Cmd(char a)
{
    RS = 0;           
    Lcd_SetBit(a); //Incoming Hex value
    EN  = 1;         
        __delay_ms(4);
        EN  = 0;         
}

Lcd_Clear()
{
    Lcd_Cmd(0); //Clear the LCD
    Lcd_Cmd(1); //Move the curser to first position
}

void Lcd_Set_Cursor(char a, char b)
{
    char temp,z,y;
    if(a== 1)
    {
      temp = 0x80 + b - 1; //80H is used to move the curser
        z = temp>>4; //Lower 8-bits
        y = temp & 0x0F; //Upper 8-bits
        Lcd_Cmd(z); //Set Row
        Lcd_Cmd(y); //Set Column
    }
    else if(a== 2)
    {
        temp = 0xC0 + b - 1;
        z = temp>>4; //Lower 8-bits
        y = temp & 0x0F; //Upper 8-bits
        Lcd_Cmd(z); //Set Row
        Lcd_Cmd(y); //Set Column
    }
}

void Lcd_Start()
{
  Lcd_SetBit(0x00);
  for(int i=1065244; i<=0; i--)  NOP();  
  Lcd_Cmd(0x03);
    __delay_ms(5);
  Lcd_Cmd(0x03);
    __delay_ms(11);
  Lcd_Cmd(0x03); 
  Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
  Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
  Lcd_Cmd(0x08); //Select Row 1
  Lcd_Cmd(0x00); //Clear Row 1 Display
  Lcd_Cmd(0x0C); //Select Row 2
  Lcd_Cmd(0x00); //Clear Row 2 Display
  Lcd_Cmd(0x06);
}

void Lcd_Print_Char(char data)  //Send 8-bits through 4-bit mode
{
   char Lower_Nibble,Upper_Nibble;
   Lower_Nibble = data&0x0F;
   Upper_Nibble = data&0xF0;
   RS = 1;             // => RS = 1
   Lcd_SetBit(Upper_Nibble>>4);             //Send upper half by shifting by 4
   EN = 1;
   for(int i=2130483; i<=0; i--)  NOP(); 
   EN = 0;
   Lcd_SetBit(Lower_Nibble); //Send Lower half
   EN = 1;
   for(int i=2130483; i<=0; i--)  NOP();
   EN = 0;
}

void Lcd_Print_String(char *a)
{
    int i;
    for(i=0;a[i]!='\0';i++)
       Lcd_Print_Char(a[i]);  //Split the string using pointers and call the Char function 
}

/*******END OF LCD FUNCTIONS*********/
const unsigned short Custom_Char5x8[] = {
  0b01110,0b01110,0b00100,0b01110,0b10101,0b00100,0b01010,0b01010, // Code for CGRAM memory space 1
  0b00000,0b00000,0b01010,0b00100,0b00100,0b10001,0b01110,0b00000, // Code for CGRAM memory space 2
  0b00100,0b01110,0b11111,0b11111,0b01110,0b01110,0b01010,0b01010, // Code for CGRAM memory space 3
  0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111,0b00000, // Code for CGRAM memory space 4
  0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111,0b00000, // Code for CGRAM memory space 5
  0b00000,0b10001,0b01010,0b10001,0b00100,0b01110,0b10001,0b00000, // Code for CGRAM memory space 6
  0b00000,0b00000,0b01010,0b10101,0b10001,0b01110,0b00100,0b00000, // Code for CGRAM memory space 7
  0b11111,0b11111,0b10101,0b11011,0b11011,0b11111,0b10001,0b11111  // Code for CGRAM memory space 8
};

int main()
{
    unsigned int a;char i;
    TRISD = 0x00;
    Lcd_Start();
   
    //*** Load custom char into the CGROM***//////
  Lcd_Cmd(0x04);   // Set CGRAM Address
  Lcd_Cmd(0x00);   // .. set CGRAM Address
  for (i = 0; i <= 63 ; i++)
    Lcd_Print_Char(Custom_Char5x8[i]);
  Lcd_Cmd(0);      // Return to Home
  Lcd_Cmd(2);      // .. return to Home
  //*** Loading custom char complete***//////
  
    while(1)
    {
        Lcd_Clear();
        //Print all Custom characters// 
    Lcd_Set_Cursor(1,1);
    Lcd_Print_Char(0); // Display Custom Character 0
    Lcd_Print_Char(1); // Display Custom Character 1
    Lcd_Print_Char(2); // Display Custom Character 2
    Lcd_Print_Char(3); // Display Custom Character 3
    Lcd_Print_Char(4); // Display Custom Character 4
    Lcd_Print_Char(5); // Display Custom Character 5
    Lcd_Print_Char(6); // Display Custom Character 6
    Lcd_Print_Char(7); // Display Custom Character 7
    
    //Print predefined special character//
    Lcd_Set_Cursor(2,1);
    Lcd_Print_Char(0b11100000); //binary value of alpha from data-sheet
    __delay_ms(1000);
    }
    return 0;
}














Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...