3. LCD1602滚动显示长文本
任务说明
LCD1602单行可显示16个字符,当需要显示超过16字符的文本(如设备状态信息、滚动公告)时,需实现循环滚动显示。本案例将驱动LCD1602在第二行循环滚动显示一条长文本,第一行固定显示标题。
硬件连接
| LCD1602引脚 | 单片机引脚 |
|---|---|
| RS | P2.0 |
| RW | P2.1(接地) |
| EN | P2.2 |
| D4-D7 | P0.4-P0.7 |
| 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软件烧录到单片机。注意在代码开头需包含
验证方法
给电路上电后,观察LCD1602第一行固定显示"System Status:",第二行应每300ms左移一个字符位置,循环显示完整文本内容。判定标准:
- 第二行始终显示16个可见字符,无乱码或闪烁
- 文本从"Welcome to Emb"开始,逐步左移,最终回到起始位置形成无缝循环
- 第一行内容保持不变,不受滚动影响
若滚动速度过快或过慢,可调整delay_10ms(30)中的参数值(范围10~100对应约100ms~1s)。