【Protues仿真】基于AT89C52单片机的LCD液晶显示屏显示控制
目录
1 LM016L液晶显示模块
1.1 基本参数
1.2 引脚定义
1.3硬件连接示例(AT89C52)
1.4 常用指令集(HD44780 子集)
1.5 常见问题与注意事项
1.8 结论
2 LM016L液晶显示模块控制电路原理图
3 LM016L液晶显示模块控制程序
4 常用16进制数的ASCLL字符对照表
摘要:LM016L是一款基于HD44780控制器的16×2字符型液晶显示模块,具有5×8点阵显示、5V工作电压和并行接口。文章详细介绍了其引脚定义、硬件连接示例(以AT89C52为例)、常用指令集及常见问题解决方案。同时提供了完整的控制程序代码,包括初始化、字符串显示和数值显示功能。该模块兼容性强,适合与各类微控制器配合使用,是嵌入式系统开发的经典显示解决方案。文中还附有ASCII字符对照表供参考。
1 LM016L液晶显示模块
LM016L 是一款基于 Hitachi HD44780 控制器或其兼容芯片的 16×2 字符型液晶显示模块(LCD Module),能够显示两行、每行 16 个 ASCII 字符(或自定义符号)。
1.1 基本参数
项目 | 典型值 / 说明 |
显示容量 | 16 字符 × 2 行 |
字符点阵 | 5 × 8 点阵(可显示 5 × 10) |
外形尺寸 | 80.0 mm × 36.0 mm(常见公模) |
视域尺寸 | 64.5 mm × 16.0 mm |
工作电压 | 4.7 V – 5.3 V(大多 5 V 单电源) |
背光类型 | 黄绿 LED(可带或不带背光) |
接口方式 | 并行 8 位/4 位可选 |
控制器 | HD44780 或兼容(KS0066、ST7066 等) |
工作温度 | −20 °C – +70 °C |
储存温度 | −30 °C – +80 °C |
1.2 引脚定义
LM016L 采用 单排 16-pin(2.54 mm 间距) 直插排针,常见引脚排列如下:
引脚 | 符号 | 功能说明 |
1 | VSS | 电源地(GND) |
2 | VDD | 正电源 +5 V |
3 | VEE | 对比度调节电压(0 – 5 V,通常接 10 kΩ 电位器) |
4 | RS | 寄存器选择(0:指令寄存器;1:数据寄存器) |
5 | R/W | 读/写选择(0:写;1:读;常直接接地做“只写”) |
6 | E | 使能端(下降沿触发) |
7 – 14 | D0 – D7 | 8 位并行数据总线 |
15 | A/LED+ | 背光阳极(若带背光) |
16 | K/LED– | 背光阴极 |
提示:如果只需 4 位模式,D0–D3 可悬空或接地,只接 D4–D7 即可节省 MCU IO。
1.3硬件连接示例(AT89C52)
LCD 引脚 | 连接AT89C52 |
VSS | GND |
VDD | +5 V |
VEE | GND |
RS | P0.2 |
R/W | P0.1 |
E | P0.0 |
D4 – D7 | P0.4\P0.5\P0.6\P0.7(4位模式) |
1.4 常用指令集(HD44780 子集)
指令 | 二进制 | HEX | 功能 |
清屏 | 0000 0001 | 0x01 | 清屏并把光标移到左上角 |
光标归位 | 0000 0010 | 0x02 | 光标返回原点,DDRAM 地址清零 |
输入模式 | 0000 01 I/D S | 0x06 | 设置光标移动方向、是否整体移位 |
显示开关 | 0000 1 D C B | 0x0C | D=显示,C=光标,B=光标闪烁 |
功能设定 | 001 DL N F – | 0x28 | DL=8/4 位,N=行数,F=点阵 |
1.5 常见问题与注意事项
对比度无显示:调节 V0 电位器,或检查背光是否亮。
显示方块、乱码:通常是初始化时序不对或电源/地线接触不良。
背光过暗/过亮:在 A 与 K 之间串联 100 Ω 左右电阻限流。
3.3 V 系统驱动:HD44780 需 5 V 供电,但输入高电平需 ≥0.7 VDD ≈ 3.5 V,故 3.3 V MCU 需电平转换或选用 3.3 V 兼容型号(如 SPLC780D1)。
I²C 转接板:市面上常把 LM016L 与 PCF8574T I²C 转接板焊成一体,可节省 IO,仅需 2 根信号线(SDA/SCL)。
1.8 结论
LM016L = 经典的 16×2 字符 LCD,与 HD44780 指令完全兼容,资料丰富、社区生态完善。无论是拿 Arduino、STM32、Raspberry Pi Pico 还是 8051,都能快速上手。
2 LM016L液晶显示模块控制电路原理图
如上图所示,LM016L液晶显示模块控制电路由AT89C52单片机、上拉排阻、LM016L液晶显示屏和晶振与复位电路,能够实现字符、数字等数据的显示。
3 LM016L液晶显示模块控制程序
如上图所示,LM016L液晶显示模块控制程序能够实现显示屏显示两行字符串数据,控制程序如下所示。
//头文件与位定义
#include <reg52.h>
#include <string.h>typedef unsigned char uchar;
typedef unsigned int uint;sbit EN = P0^0;//使能端
sbit RW = P0^1;//读0写1选择
sbit RS = P0^2;//寄存器选择0:指令1:数据int time=1314; //time:占空比(0~10)
int freq=6666;void Write_Cmd(uchar cmd); //写指令函数
void Write_Dat(uchar dat); //写入数据
void LCD1602_Init(); //LCD初始化
void PrintStr(char *str); // LCD输出字符串
void DisplayNum(int m); // LCD显示数值
void delayms(unsigned int xms); //微秒级延时函数
void delay(unsigned int x);/*****************主函数***********************/
void inittimer()
{TMOD = 0x01; // T0 方式 1TH0 = 0xFC; // 1 msTL0 = 0x18;TR0 = 1; ET0 = 1; EA = 1;//中断设置值
}
void delay(unsigned int ms)
{unsigned int i;for (i = 0; i < ms; i++){while (!TF0); // 等待定时器T0溢出TF0 = 0; // 清除溢出标志}
}//中断服务函数
void Timer0_ISR() interrupt 1
{TH0 = 0xFC; TL0 = 0x18;}void main()
{inittimer();LCD1602_Init(); // 初始化LCD1602while(1){Write_Cmd(0x80 | 0x00); //显示地址,0x80是第一行的的首地址。0x80|0x06表示数据从第一行第1个字符位置开始显示PrintStr("CSDN:");DisplayNum(freq);PrintStr("!");Write_Cmd(0xc0| 0x00); // 显示第二行PrintStr("STUDY:");DisplayNum(time);Write_Dat('!');}
}
void Write_Cmd(uchar cmd) //写指令函数
{P1 = cmd; //写入十六进制形式的指令(command)RS = 0;//指令寄存器EN = 0;delay(1);EN = 1; //写指令的操作时序:RS=0,RW=0,EN=高脉冲delay(1);EN = 0; //获得高脉冲后使能端重新置零
}
void Write_Dat(uchar dat) //写入数据
{P1 = dat; //P0口写入数据RS = 1;//数据寄存器EN = 0;delay(1);EN = 1; //写数据操作时序:RS=0,RW=0,EN=高脉冲delay(1);EN = 0; //获得高脉冲后使能端重新置零
}void LCD1602_Init()
{RW = 0;//读Write_Cmd(0x38);//设置16*2显示delay(8);Write_Cmd(0x0f);//开显示 显示光标,光标闪烁delay(8);Write_Cmd(0x01);//清屏delay(8);Write_Cmd(0x06);//地址指针移位命令delay(8);//Write_Cmd(0x80 | 0x00);//显示地址,0x80是第一行的的首地址。0x80|0x06表示数据从第一行第7个字符位置开始显示}
// 打印字符串的函数,使用到了strlen函数,需要引入string.h头文件
void PrintStr(char *str) // LCD输出字符串
{char i,len;len = strlen(str); // 获取字符串长度for(i=0;i<len;i++){Write_Dat(*str);str++;}
}void DisplayNum(int m) // LCD显示数值
{int disdata[4]; //数值disdata[0] = m/1000+0x30;disdata[1] = m%1000/100+0x30;disdata[2] = m%100/10+0x30;disdata[3] = m%10+0x30;if(disdata[0]==0x30) //如果千位为0,让LCD不显示{disdata[0]=0x20;if( disdata[1]==0x30) //如果百位为0,让LCD不显示{disdata[1]=0x20;if( disdata[2]==0x30) //如果百位为0,让LCD不显示{disdata[2]=0x20;}}}Write_Dat(disdata[0]);delay(4);Write_Dat(disdata[1]);delay(4);Write_Dat(disdata[2]);delay(4);Write_Dat(disdata[3]);delay(4);}
4 常用16进制数的ASCLL字符对照表
下面给出常用的十六进制数 → ASCII 字符 对照表(仅列 0x00–0x7F 的标准 7-bit ASCII)。
HEX | Char | HEX | Char | HEX | Char | HEX | Char |
0x00 | NUL | 0x20 | (空格) | 0x40 | @ | 0x60 | ` |
0x01 | SOH | 0x21 | ! | 0x41 | A | 0x61 | a |
0x02 | STX | 0x22 | " | 0x42 | B | 0x62 | b |
0x03 | ETX | 0x23 | # | 0x43 | C | 0x63 | c |
0x04 | EOT | 0x24 | $ | 0x44 | D | 0x64 | d |
0x05 | ENQ | 0x25 | % | 0x45 | E | 0x65 | e |
0x06 | ACK | 0x26 | & | 0x46 | F | 0x66 | f |
0x07 | BEL | 0x27 | ' | 0x47 | G | 0x67 | g |
0x08 | BS | 0x28 | ( | 0x48 | H | 0x68 | h |
0x09 | HT | 0x29 | ) | 0x49 | I | 0x69 | i |
0x0A | LF | 0x2A | * | 0x4A | J | 0x6A | j |
0x0B | VT | 0x2B | + | 0x4B | K | 0x6B | k |
0x0C | FF | 0x2C | , | 0x4C | L | 0x6C | l |
0x0D | CR | 0x2D | - | 0x4D | M | 0x6D | m |
0x0E | SO | 0x2E | . | 0x4E | N | 0x6E | n |
0x0F | SI | 0x2F | / | 0x4F | O | 0x6F | o |
HEX | Char | HEX | Char | HEX | Char | HEX | Char |
0x10 | DLE | 0x30 | 0 | 0x50 | P | 0x70 | p |
0x11 | DC1 | 0x31 | 1 | 0x51 | Q | 0x71 | q |
0x12 | DC2 | 0x32 | 2 | 0x52 | R | 0x72 | r |
0x13 | DC3 | 0x33 | 3 | 0x53 | S | 0x73 | s |
0x14 | DC4 | 0x34 | 4 | 0x54 | T | 0x74 | t |
0x15 | NAK | 0x35 | 5 | 0x55 | U | 0x75 | u |
0x16 | SYN | 0x36 | 6 | 0x56 | V | 0x76 | v |
0x17 | ETB | 0x37 | 7 | 0x57 | W | 0x77 | w |
0x18 | CAN | 0x38 | 8 | 0x58 | X | 0x78 | x |
0x19 | EM | 0x39 | 9 | 0x59 | Y | 0x79 | y |
0x1A | SUB | 0x3A | : | 0x5A | Z | 0x7A | z |
0x1B | ESC | 0x3B | ; | 0x5B | [ | 0x7B | { |
0x1C | FS | 0x3C | < | 0x5C | \ | 0x7C | | |
0x1D | GS | 0x3D | = | 0x5D | ] | 0x7D | } |
0x1E | RS | 0x3E | > | 0x5E | ^ | 0x7E | ~ |
0x1F | US | 0x3F | ? | 0x5F | _ | 0x7F | DEL |