1. 点亮LCD1602并显示固定字符

点亮LCD1602并显示固定字符 学习卡片

任务说明

本案例要求驱动LCD1602字符型液晶模块,完成初始化后在第一行显示固定字符串“Hello”。LCD1602为16引脚并行接口,采用HD44780控制器,需通过4位数据总线模式进行通信以节省I/O资源。完成本案例后,应能在屏幕第一行清晰看到“Hello”字样,以此验证驱动时序与初始化流程正确。

硬件连接

使用STC89C52单片机(12MHz晶振)控制LCD1602,连接关系如下表所示。4位模式仅需连接高4位数据线DB4~DB7。

LCD1602引脚单片机引脚功能
RSP2.0寄存器选择(0=指令,1=数据)
RWP2.1读写选择(0=写,1=读)
EP2.2使能脉冲
DB4~DB7P0.4~P0.74位数据总线
VSS/VDD/V0GND/+5V/对比度电位器电源与对比度调节
LEDA/LEDK+5V/GND(串电阻)背光
接线要点:P0口需外接10kΩ上拉电阻排;V0接10kΩ电位器中间抽头,两端接VCC与GND,用于调节对比度;E引脚每次操作需产生下降沿锁存数据。

驱动实现

LCD1602初始化需严格遵循HD44780时序:上电等待15ms以上,发送3次0x03(8位模式指令),再切换为4位模式,随后设置显示参数并清屏。本代码完整实现4线驱动,包含延时函数、指令/数据写入函数及初始化流程。


#include <reg52.h>
#include <intrins.h>

#define LCD_DATA P0

sbit RS = P2^0;
sbit RW = P2^1;
sbit E  = P2^2;

/* 简易延时:约1ms @12MHz */
void delay_ms(unsigned int n) {
    unsigned int i, j;
    for (i = 0; i < n; i++)
        for (j = 0; j < 120; j++);
}

/* 向LCD写入4位数据(高4位有效) */
void lcd_write_nibble(unsigned char dat) {
    LCD_DATA = (LCD_DATA & 0x0F) | (dat & 0xF0);  // 仅更新高4位
    E = 1;
    _nop_();
    E = 0;          // 下降沿锁存
    delay_ms(1);
}

/* 写入一个字节:先高4位,后低4位 */
void lcd_write_byte(unsigned char dat, unsigned char rs) {
    RS = rs;
    RW = 0;
    lcd_write_nibble(dat);      // 高4位
    lcd_write_nibble(dat << 4); // 低4位移至高4位位置
}

/* 写指令 */
void lcd_cmd(unsigned char cmd) {
    lcd_write_byte(cmd, 0);
}

/* 写数据 */
void lcd_data(unsigned char dat) {
    lcd_write_byte(dat, 1);
}

/* LCD1602初始化(4位模式) */
void lcd_init(void) {
    delay_ms(20);               // 上电等待
    lcd_write_nibble(0x30);     // 8位模式指令
    delay_ms(5);
    lcd_write_nibble(0x30);
    delay_ms(1);
    lcd_write_nibble(0x30);
    delay_ms(1);
    lcd_write_nibble(0x20);     // 切换为4位模式
    delay_ms(1);
    
    lcd_cmd(0x28);  // 4位总线,2行,5x7点阵
    lcd_cmd(0x0C);  // 显示开,光标关,闪烁关
    lcd_cmd(0x01);  // 清屏
    delay_ms(2);
    lcd_cmd(0x06);  // 写入后地址自动加1
}

/* 在指定位置显示字符串 */
void lcd_show_string(unsigned char row, unsigned char col, char *str) {
    unsigned char addr;
    if (row == 0)
        addr = 0x00 + col;
    else
        addr = 0x40 + col;
    lcd_cmd(0x80 | addr);   // 设置DDRAM地址
    
    while (*str != '\0') {
        lcd_data(*str++);
    }
}

void main(void) {
    lcd_init();
    lcd_show_string(0, 0, "Hello");
    while (1);
}

编译与烧录

使用Keil C51创建工程,选择芯片AT89C52,将上述代码保存为main.c加入工程。编译生成HEX文件后,通过STC-ISP软件烧录至单片机。晶振频率需设置为12MHz,烧录时选择正确的串口与芯片型号。

验证方法

按上述接线图连接电路,调节V0对比度电位器至屏幕出现黑色字符。烧录程序后观察LCD第一行起始位置是否显示“Hello”。若屏幕无显示,依次检查:

  • 对比度电位器是否调节到合适位置(V0电压约0.5V~1V)
  • P0口上拉电阻是否安装
  • E引脚脉冲时序是否正常(可用示波器观察)
  • 初始化延时是否满足HD44780上电要求

判定标准:LCD第一行从左起第1个字符位置清晰显示“Hello”五个字符,无乱码、无闪烁,背光正常点亮,即判定驱动成功。

预期输出

代码逻辑确定,在硬件正常的前提下,屏幕第一行显示内容为:

Hello

第二行保持空白(未写入数据)。该结果由代码中lcd_show_string(0, 0, "Hello")直接决定,地址0x00对应第一行第一列。

LCD1602 4位模式驱动时序与数据流 STC89C52 P2.0 → RS P2.1 → RW P2.2 → E P0.4~P0.7 → DB4~DB7 (P0口外接10kΩ上拉) RS RW E DB4~DB7 (4位) LCD1602 HD44780控制器 Hello 第一行 DDRAM 0x00~0x0F 第二行(未使用) 10kΩ电位器 V0对比度调节 V0 VDD=+5V VSS=GND 初始化时序(4位模式) 0x03×3 → 0x02 → 0x28 → 0x0C → 0x01 → 0x06 → 0x80 控制信号

关键说明

本案例采用4位总线模式,每次传输8位数据需分两次发送(先高4位后低4位)。初始化时先以8位模式发送0x03三次,确保控制器同步,再发送0x02切换为4位模式。后续所有指令均通过lcd_write_byte完成高低位拆分。显示“Hello”时,先通过lcd_cmd(0x80)将DDRAM地址设为第一行起始位置,再连续写入5个字符的ASCII码,控制器自动递增地址,字符依次排列。