• LCD Interfacing with PIC Microcontroller using MPLABX and XC8 - Giao diện LCD với Vi điều khiển PIC sử dụng MPLABX và XC8

QC

LCD Interfacing with PIC Microcontroller using MPLABX and XC8 - Giao diện LCD với Vi điều khiển PIC sử dụng MPLABX và XC8

 Đây là hướng dẫn thứ sáu của chúng tôi trong Loạt bài Hướng dẫn về PIC, trong hướng dẫn này, chúng tôi tìm hiểu Giao diện của LCD 16x2 với Vi điều khiển PIC. Trong các hướng dẫn trước đây của chúng tôi, chúng tôi đã học những kiến thức cơ bản về PIC bằng cách sử dụng một số Chương trình nhấp nháy đèn LED và cũng đã học Cách sử dụng Bộ hẹn giờ 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.


Hướng dẫn này sẽ rất thú vị vì chúng ta sẽ học Cách giao diện màn hình LCD 16 × 2 với PIC16F877A, hãy xem Video chi tiết ở cuối hướng dẫn này. Đã qua rồi cái thời chúng ta sử dụng đèn LED cho các chỉ dẫn của người dùng. Hãy để chúng tôi xem cách chúng tôi có thể làm cho các dự án của mình trông thú vị và hữu ích hơn bằng cách sử dụng màn hình LCD. Ngoài ra, hãy xem các bài viết trước của chúng tôi về Giao diện LCD với 8051, với Arduino, với Raspberry Pi, với AVR.


Functions for Interfacing LCD with PIC Microcontroller:

Để giúp mọi thứ dễ dàng hơn, chúng tôi đã tạo một thư viện nhỏ có thể giúp mọi thứ trở nên dễ dàng khi sử dụng màn hình LCD này với PIC16F877A của chúng tôi. Tệp tiêu đề "MyLCD.h" được cung cấp tại đây để tải xuống, tệp này chứa tất cả các chức năng cần thiết để điều khiển màn hình LCD sử dụng PIC MCU. Mã thư viện được giải thích rõ ràng bằng các dòng bình luận nhưng nếu bạn vẫn còn nghi ngờ, hãy liên hệ với chúng tôi qua phần bình luận. 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ó.

Lưu ý: Bạn nên biết điều gì đang thực sự xảy ra bên trong tệp tiêu đề của mình vì nó sẽ giúp bạn gỡ lỗi hoặc trong khi thay đổi MCU.

Bây giờ, có hai cách để thêm mã này vào chương trình của bạn. Bạn có thể sao chép tất cả các dòng mã trên trong MyLCD.h và dán chúng trước void main (). Hoặc bạn có thể tải xuống tệp tiêu đề bằng liên kết và thêm chúng vào tệp tiêu đề của dự án của bạn (#include "MyLCD.h";). Điều này có thể được thực hiện bằng cách nhấp chuột phải vào tệp tiêu đề và chọn Thêm mục hiện có và duyệt đến tệp tiêu đề này.

Ở đây tôi đã sao chép và dán mã tệp tiêu đề vào tệp C chính của mình. Vì vậy, nếu bạn đang sử dụng mã của chúng tôi, thì bạn không cần tải xuống và thêm tệp tiêu đề vào chương trình của mình, chỉ cần sử dụng Mã hoàn chỉnh được cung cấp ở cuối Hướng dẫn này. Cũng lưu ý rằng thư viện này sẽ chỉ hỗ trợ Vi điều khiển PIC dòng PIC16F.

Ở đây tôi giải thích từng chức năng bên trong tệp tiêu đề của chúng tôi bên dưới:

void Lcd_Start (): Hàm này phải là hàm đầu tiên phải được gọi để bắt đầu hoạt động với màn hình LCD của chúng ta. Chúng ta chỉ nên gọi hàm này một lần duy nhất để tránh tình trạng chương trình bị lag.


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);
}


Lcd_Clear (): Hàm này xóa màn hình LCD và có thể được sử dụng bên trong các vòng lặp để xóa sự xuất hiện của dữ liệu trước đó.


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


void Lcd_Set_Cursor (x pos, y pos): Sau khi khởi động, màn hình LCD của chúng ta đã sẵn sàng thực hiện các lệnh, chúng ta có thể hướng dẫn màn hình LCD đặt con trỏ của nó ở vị trí ưa thích của bạn bằng cách sử dụng chức năng này. Giả sử nếu, chúng ta cần con trỏ ở ký tự thứ 5 của hàng thứ nhất. Sau đó, hàm sẽ là void Lcd_Set_Cursor (1, 5)

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 cursor
        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_Print_Char (char data): Sau khi con trỏ được đặt, chúng ta có thể viết một ký tự vào vị trí của nó bằng cách gọi hàm này một cách đơn giản.


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): Nếu một nhóm ký tự được hiển thị, thì hàm chuỗi có thể được sử dụng.


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 
}


Mỗi khi Lcd_Print_Char (dữ liệu ký tự) được gọi, các giá trị ký tự tương ứng của nó được gửi đến các dòng dữ liệu của màn hình LCD. Các ký tự này đạt đến HD44780U ở dạng bit. Bây giờ vi mạch này liên hệ các bit với ký tự được hiển thị bằng cách sử dụng bộ nhớ ROM của nó như bảng dưới đây. Bạn có thể tìm thấy các bit cho tất cả các ký tự trong biểu dữ liệu của Bộ điều khiển LCD HD44780U.




Bây giờ, vì chúng tôi hài lòng với tệp tiêu đề của mình, chúng ta hãy xây dựng mạch và thử nghiệm chương trình. Cũng kiểm tra tệp tiêu đề hoàn chỉnh được cung cấp trong liên kết được cung cấp ở trên.

Circuit Diagram and Testing:



Tôi đã không hiển thị nguồn điện hoặc kết nối ICSP trong mạch trên, vì chúng tôi đang sử dụng cùng một bảng mà chúng tôi đã sử dụng trong hướng dẫn trước, hãy kiểm tra tại đây.



Một điều quan trọng cần lưu ý trong chương trình là định nghĩa chân của LCD:

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


Các định nghĩa chân này có thể được thay đổi tùy theo thiết lập phần cứng của người lập trình. Hãy nhớ thay đổi cấu hình cổng được tôn trọng trong chức năng chính nếu bạn thay đổi ở đây.


Phần cứng cho dự án này rất đơn giản. Chúng tôi sẽ sử dụng lại cùng một mô-đun PIC mà chúng tôi đã sử dụng lần trước và kết nối mô-đun LCD với PIC của chúng tôi bằng dây nhảy.


Kết nối có thể được hiểu theo bảng sau:

LCD Pin No.LCD Pin NameMCU Pin NameMCU Pin No.
1GroundGround12
2VCC+5V11
3VEEGround12
4Register SelectRD221
5Read/WriteGround12
6EnableRD322
7Data Bit 0NC-
8Data Bit 1NC-
9Data Bit 2NC-
10Data Bit 3NC-
11Data Bit 4RD427
12Data Bit 5RD528
13Data Bit 6RD629
14Data Bit 7RD730
15LED Positive+5V11
16LED NegativeGround12

Bây giờ chúng ta chỉ cần tạo kết nối, kết xuất mã vào MCU của chúng ta và xác minh kết quả đầu ra.


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.
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 
}

int main()
{
    unsigned int a;
    TRISD = 0x00;
    Lcd_Start();
    while(1)
    {
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Print_String("Circuit Digest");
        Lcd_Set_Cursor(2,1);
        Lcd_Print_String("WORKING!!");
        __delay_ms(2000);
    }
    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/...