3. LCD1602滚动显示长文本

LCD1602滚动显示长文本 学习卡片

任务说明

LCD1602单行可显示16个字符,当需要显示超过16字符的文本(如设备状态信息、滚动公告)时,需实现循环滚动显示。本案例将驱动LCD1602在第二行循环滚动显示一条长文本,第一行固定显示标题。

硬件连接

LCD1602引脚单片机引脚
RSP2.0
RWP2.1(接地)
ENP2.2
D4-D7P0.4-P0.7
V010k电位器中点(对比度)
STC89C52 P2.0 RS P2.2 EN P0.4-P0.7 LCD1602 RS RW EN D4 D5 D6 D7 V0 对比度 VSS VDD RS EN D4-D7 V0 10k

实现原理

滚动显示的核心思路:将长文本存入数组,每次取16个字符写入LCD第二行,然后通过延时和循环变量递增实现左移效果。当显示窗口到达文本末尾时,回到开头形成循环。

完整代码


#include <reg52.h>
#include <string.h>

#define LCD_DATA P0
sbit RS = P2^0;
sbit EN  = P2^2;

// 长文本(共48字符,超过一行16字符)
unsigned char code msg[] = "Welcome to Embedded LCD Tutorial - 51 MCU ";

// 向LCD发送字节
void lcd_write(unsigned char dat, bit rs) {
    RS = rs;
    LCD_DATA = (LCD_DATA & 0x0F) | (dat & 0xF0);  // 高4位
    EN = 1; _nop_(); EN = 0;
    LCD_DATA = (LCD_DATA & 0x0F) | ((dat << 4) & 0xF0); // 低4位
    EN = 1; _nop_(); EN = 0;
    if (rs == 0) {          // 命令模式需等待
        LCD_DATA = 0xFF;    // 释放总线
        RS = 0;
        EN = 1; _nop_(); EN = 0;
    }
}

// 初始化LCD
void lcd_init() {
    LCD_DATA = 0x00;
    EN = 0;
    lcd_write(0x33, 0);  // 初始化序列
    lcd_write(0x32, 0);
    lcd_write(0x28, 0);  // 4线、2行、5x7
    lcd_write(0x0C, 0);  // 显示开、光标关
    lcd_write(0x01, 0);  // 清屏
    lcd_write(0x06, 0);  // 光标右移
}

// 在指定位置显示字符串
void lcd_show(unsigned char row, unsigned char col, unsigned char *str) {
    unsigned char addr = (row == 0) ? 0x80 + col : 0xC0 + col;
    lcd_write(addr, 0);
    while (*str) {
        lcd_write(*str++, 1);
    }
}

// 延时约10ms
void delay_10ms(unsigned int n) {
    unsigned int i, j;
    for (i = 0; i < n; i++)
        for (j = 0; j < 120; j++);
}

void main() {
    unsigned int len, pos = 0;
    unsigned char display_buf[17];  // 16字符+结束符

    lcd_init();
    len = strlen(msg);

    while (1) {
        // 从pos位置截取16字符
        unsigned char i;
        for (i = 0; i < 16; i++) {
            display_buf[i] = msg[(pos + i) % len];
        }
        display_buf[16] = '\0';

        lcd_show(0, 0, "System Status:");
        lcd_show(1, 0, display_buf);

        delay_10ms(30);  // 约300ms滚动一次
        pos++;
        if (pos >= len) pos = 0;  // 循环
    }
}

编译与烧录

使用Keil C51创建工程,选择AT89C52或STC89C52芯片,将上述代码保存为main.c并加入工程。编译生成HEX文件后,通过STC-ISP软件烧录到单片机。注意在代码开头需包含头文件以使用_nop_()函数。

验证方法

给电路上电后,观察LCD1602第一行固定显示"System Status:",第二行应每300ms左移一个字符位置,循环显示完整文本内容。判定标准:

  • 第二行始终显示16个可见字符,无乱码或闪烁
  • 文本从"Welcome to Emb"开始,逐步左移,最终回到起始位置形成无缝循环
  • 第一行内容保持不变,不受滚动影响

若滚动速度过快或过慢,可调整delay_10ms(30)中的参数值(范围10~100对应约100ms~1s)。