【Protues仿真】基于AT89C52单片机的LCD液晶显示屏显示控制

目录

[1 LM016L液晶显示模块](#1 LM016L液晶显示模块)

[1.1 基本参数](#1.1 基本参数)

[1.2 引脚定义](#1.2 引脚定义)

1.3硬件连接示例(AT89C52)

[1.4 常用指令集(HD44780 子集)](#1.4 常用指令集(HD44780 子集))

[1.5 常见问题与注意事项](#1.5 常见问题与注意事项)

[1.8 结论](#1.8 结论)

[2 LM016L液晶显示模块控制电路原理图](#2 LM016L液晶显示模块控制电路原理图)

[3 LM016L液晶显示模块控制程序](#3 LM016L液晶显示模块控制程序)

[4 常用16进制数的ASCLL字符对照表](#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 液晶显示模块控制程序能够实现显示屏显示两行字符串数据,控制程序如下所示。

objectivec 复制代码
//头文件与位定义
#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 方式 1
    TH0  = 0xFC;        // 1 ms
    TL0  = 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();  	// 初始化LCD1602
   while(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 |