UAV2101-2105编程训练LCD1602液晶显示控制
字符型液晶显示器LCD 1602,LCD1602百度百科参考链接
https://baike.baidu.com/item/LCD1602/6014393?fr=ge_ala
Proteus
所需器件
元件名称 | Proteus关键字 |
51单片机 | AT89C51 |
复位按钮 | BUTTON |
电容 | CAP |
电解电容 | CAP-ELEC |
晶体振荡器 | CRYSTAL |
字符型LCD 1602显示器 | LM016L |
滑动变阻器 | POT-HG |
电阻 | RES |
排阻 | RESPACK-8 |
LCD1602的“16”表示液晶显示模块每行可显示16个字符,“02”表示显示2行。
LCD 1602的命令字
命令 | RS | R/~W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
清屏 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
光标返回 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | X |
显示模式设置 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S |
显示开/关及光标设置 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B |
光标或字符移位 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | X | X |
功能设置 | 0 | 0 | 0 | 0 | 1 | DL | N | F | X | X |
CGROM地址设置 | 0 | 0 | 0 | 1 | 字符库ROM地址 | |||||
DDRAM地址设置 | 0 | 0 | 1 | 显示数据RAM地址 | ||||||
读忙标志或地址 | 0 | 1 | BF | 计数器地址 | ||||||
写数据 | 1 | 0 | 要写的数据 | |||||||
读数据 | 1 | 1 | 读出的数据 |
LCD 1602的读写操作规定如下
单片机发给LCD 1602 的控制信号 | LCD 1602 的输出 | |
读状态 | RS=0,R/~W=1,E=1 | D0~D7=状态字 |
写命令 | RS=0,R/~W=0,D0~D7=命令,E=正脉冲 | 无 |
读数据 | RS=1,R/~W=1,E=1 | D0~D7=数据 |
写数据 | RS=1,R/~W=0,D0~D7=数据,E=正脉冲 | 无 |
我这里取消了光标右移,是直接打印出来的.
第一行字符的地址为80H~8FH
第二行字符的地址为C0H~CFH
参考例子001、显示UAV2101-2105
//例子01、LCD1602液晶显示任意字符串 #include <reg52.h> typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; typedef unsigned long u32; u8 code Tab1[]="Welcome everyone"; u8 code Tab2[]="UAV2101--UAV2105"; //管脚定义 sbit LCD1602_RS=P2^6;//数据命令选择 sbit LCD1602_RW=P2^5;//读写选择 sbit LCD1602_E=P2^7; //使能信号 void delay_ms(u16 ms)//晶振11.0592MHz { u16 i,j; for(i=ms;i>0;i--) for(j=112;j>0;j--); } void lcd1602_write_cmd(u8 cmd)//LCD1602写命令 { LCD1602_RS=0;//选择命令 LCD1602_RW=0;//选择写 LCD1602_E=0; P0 = cmd; //准备命令 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } void lcd1602_write_data(u8 dat) //LCD1602写数据 { LCD1602_RS=1;//选择数据 LCD1602_RW=0;//选择写 LCD1602_E=0; P0 = dat; //准备数据 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } void lcd1602_init(void) //LCD1602初始化函数 { lcd1602_write_cmd(0x38);//数据总线8位,显示2行,5*7点阵/字符 lcd1602_write_cmd(0x0c);//显示功能开,无光标,光标闪烁 lcd1602_write_cmd(0x06);//写入新数据后光标右移,显示屏不移动 lcd1602_write_cmd(0x01);//LCD1602清屏 } void main() { u8 i; lcd1602_init();//LCD1602初始化 while(1) { lcd1602_write_cmd(0x80);//第一行显示地址设置 for(i=0;i<16;i++) { lcd1602_write_data(Tab1[i]); } lcd1602_write_cmd(0x40+0x80);//第二行显示地址设置 for(i=0;i<16;i++) { lcd1602_write_data(Tab2[i]); } } }
参考例子002、输出显示字符串,包含读忙操作
#include<reg52.h> #include<intrins.h> //包含_nop_()空函数指令的头文件 #define uchar unsigned char #define uint unsigned int #define out P0 sbit RS=P2^6;//位变量 sbit RW=P2^5;//位变量 sbit E=P2^7;//位变量 //函数声明部分 void lcd_initial(void);//LCD初始化函数 void check_busy(void);//检查忙标志位函数 void write_command(uchar com);//写命令函数 void write_data(uchar dat);//写数据函数 void string(uchar ad,uchar *s);//显示字符串 void delay(uint);//延时 void main(void) { lcd_initial();//对LCD初始化 while(1) { string(0x83,"I LOVE YOU");//显示第一行的字符 string(0xC4,"FOREVER");//显示第二行的字符 delay(100);//延时 write_command(0x01);//清屏 delay(100);//延时 } } //延时j=100,精确延迟100ms,晶振11.0592MHz void delay(uint j) { uchar i=227; for(;j>0;j--)
{ while(--i); i=227; while(--i); i=227; } } //检查忙标志 void check_busy(void) { uchar dt; do{ dt=0xff;//dt为变量单元,初值为0xff //RS=0,E=1时才可以读忙标志位 E=0; RS=0; RW=1; E=1; dt=out;//out为P0口,P0口的状态送入dt中 }while(dt&0x80);//如果忙标志位BF=1,继续循环检测,等待BF=0 E=0;//BF=0,LCD 1602不忙,结束检测 } //写命令 void write_command(uchar com) { check_busy(); //按规定RS和E同时为0时,才可以写命令 E=0; RS=0; RW=0; out=com;//将命令com写入P0口 E=1;//写命令时,E应为正脉冲,即正跳变,所以前面先置E=0 _nop_();//空操作1个机器周期,等待硬件反应 E=0;//E由高电平变为低电平,LCD 1602开始执行命令 delay(1);//延时,等待硬件反应 } //写数据 void write_data(uchar dat) { check_busy();//检测忙标志位BF=1则等待,若BF=0,则可对LCD 1602写入命令 E=0;//按规定写数据时,E应为正脉冲,所以先置E=0 //按规定RS=1和RW=0时,才可以写入数据 RS=1; RW=0; out=dat;//将数据”dat“从P0口输出,即写入LCD 1602 E=1;//E产生正跳变 _nop_();//空操作1个机器周期,等待硬件反应 E=0;//E由高电平变为低电平,写数据操作结束 delay(1); } //液晶显示器初始化函数 void lcd_initial(void) { write_command(0x38);//8位两行显示,5*7点阵字符 _nop_();//空操作1个机器周期,等待硬件反应 write_command(0x0C);//开整体显示,光标关,无闪烁 _nop_();//空操作1个机器周期,等待硬件反应 //write_command(0x05);//光标右移 _nop_();//空操作1个机器周期,等待硬件反应 write_command(0x01);//清屏 delay(1); } //输出显示字符串 void string(uchar ad,uchar *s) { write_command(ad); while(*s>0){ write_data(*s++);//输出字符串,且指针增1 delay(100); } }
参考链接
Proteus-51单片机-LCD1602液晶显示DS1302实时时钟_51单片机lcd1602显示时间_爱上电路设计的博客-CSDN博客
https://blog.csdn.net/liht_1634/article/details/131524016
51单片机 使用Proteus掌握LCD1602显示屏的使用(仿真及代码)_51单片机1602显示汉字-CSDN博客
https://blog.csdn.net/m0_47235364/article/details/128294254
STC89C51基础及项目第10天:LCD显示字符(非标协议外设)-CSDN博客
https://blog.csdn.net/Jaci133/article/details/133429036
[89C51单片机]LCD1602静态显示-CSDN博客
https://blog.csdn.net/zitech/article/details/9200203
【精选】【常用传感器】LCD1602液晶工作原理详解及例程代码_lcd1602工作原理-CSDN博客
https://blog.csdn.net/as480133937/article/details/113148712