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

 

posted on 2023-12-19 20:56  一郎哥哥  阅读(195)  评论(0编辑  收藏  举报

导航