2. LCD1602显示两行字符

任务说明

本案例驱动LCD1602液晶模块,在第一行显示“Hello, World!”,第二行显示“LCD1602 Test!”,通过写入指令码实现光标定位(第一行起始地址0x00,第二行起始地址0x40),并验证两行字符正确显示。

硬件连接

LCD1602与单片机(以STC89C52为例)采用4位数据总线模式连接,节省I/O口。连接关系如下表:

LCD1602引脚单片机引脚说明
RSP2.0寄存器选择(0=指令,1=数据)
RWP2.1读写选择(0=写,1=读)
EP2.2使能信号(下降沿锁存)
D4-D7P0.4-P0.74位数据线(接高4位)
VSS/VDD/V0GND/5V/对比度电源与对比度调节
SVG 1 - LCD1602 4线连接与光标定位示意
Hello, World! LCD1602 Test! 0x00 0x40 RS=P2.0 RW=P2.1 E=P2.2 D4=P0.4 D5=P0.5 D6=P0.6 D7=P0.7 STC89C52 P2.0-P2.2 → 控制线 P0.4-P0.7 → 数据线 光标定位:写地址指令 RS,RW,E D4-D7

完整代码实现

以下代码采用4位总线模式,包含延时函数、LCD写指令/写数据函数、初始化函数和主函数。光标定位通过写入0x80+地址实现(第一行地址0x00,第二行地址0x40)。

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

#define LCD_DATA P0

sbit RS = P2^0;   // 寄存器选择
sbit RW = P2^1;   // 读写选择
sbit E  = P2^2;   // 使能信号

// 短延时函数
void delay_us(unsigned int us) {
    while(us--) {
        _nop_();
    }
}

// 延时约1ms
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = ms; i > 0; i--)
        for(j = 120; j > 0; j--);
}

// LCD忙检查(可选,此处用固定延时替代)
void lcd_ready() {
    delay_ms(2);
}

// 向LCD写入一个字节(4位模式,分两次发送高4位和低4位)
void lcd_write_byte(unsigned char dat, unsigned char rs) {
    RS = rs;      // 指令或数据
    RW = 0;       // 写模式

    // 发送高4位
    LCD_DATA = (LCD_DATA & 0x0F) | (dat & 0xF0);
    E = 1;
    delay_us(2);
    E = 0;
    delay_us(2);

    // 发送低4位
    LCD_DATA = (LCD_DATA & 0x0F) | ((dat << 4) & 0xF0);
    E = 1;
    delay_us(2);
    E = 0;
    delay_us(2);

    lcd_ready();
}

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

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

// LCD初始化(4位总线模式)
void lcd_init() {
    delay_ms(15);
    // 复位序列:先发3次0x03,再设4位模式
    lcd_write_byte(0x03, 0);
    delay_ms(5);
    lcd_write_byte(0x03, 0);
    delay_ms(5);
    lcd_write_byte(0x03, 0);
    delay_ms(5);
    lcd_write_byte(0x02, 0);  // 切换到4位模式

    lcd_cmd(0x28);  // 4位总线,2行,5x7点阵
    lcd_cmd(0x0C);  // 显示开,光标关,闪烁关
    lcd_cmd(0x06);  // 写入后地址自动加1
    lcd_cmd(0x01);  // 清屏
    delay_ms(2);
}

// 在指定位置显示字符串
void lcd_show_string(unsigned char row, unsigned char col, char *str) {
    unsigned char addr;
    if(row == 0)
        addr = 0x00 + col;      // 第一行起始地址0x00
    else
        addr = 0x40 + col;      // 第二行起始地址0x40

    lcd_cmd(0x80 | addr);       // 设置DDRAM地址(光标定位)

    while(*str != '\0') {
        lcd_data(*str);
        str++;
    }
}

void main() {
    lcd_init();

    // 第一行显示
    lcd_show_string(0, 0, "Hello, World!");
    // 第二行显示
    lcd_show_string(1, 0, "LCD1602 Test!");

    while(1) {
        // 保持显示
    }
}

编译与烧录

依赖工具:Keil C51(或SDCC)、STC-ISP烧录软件。

  1. 在Keil中新建工程,选择芯片型号STC89C52RC(或AT89C52);
  2. 将上述代码保存为main.c并加入工程;
  3. 编译生成HEX文件(无需额外配置,默认输出即可);
  4. 使用STC-ISP软件将HEX文件烧录到单片机。

硬件接线清单

  • LCD1602的VSS接GND,VDD接+5V,V0经10k电位器接GND(调节对比度);
  • RS→P2.0,RW→P2.1,E→P2.2;
  • D4→P0.4,D5→P0.5,D6→P0.6,D7→P0.7;
  • LED背光正极(15脚)串220Ω电阻接+5V,负极(16脚)接GND。

验证方法与判定标准

验证步骤:

  1. 按上述接线连接电路,确认电源和对比度正常;
  2. 烧录程序后上电复位,观察LCD屏幕;
  3. 检查第一行是否显示Hello, World!,第二行是否显示LCD1602 Test!。

判定标准:

  • 两行字符均完整显示,无乱码、缺字或错位;
  • 第一行字符从第1列开始,第二行字符从第1列开始,位置正确;
  • 若显示异常,先调节V0对比度电位器,再检查接线和延时参数。

预期输出:上电后LCD1602屏幕显示:

Hello, World!
LCD1602 Test!

该输出由代码中写入的固定字符串直接决定,与光标定位指令(0x80|0x00和0x80|0x40)严格对应。