[STC89C52RC]LCD1602液晶屏显示

目录

       一、引脚说明

       二、开发逻辑

显示参考图

LCD1602模块指令

       三、读写时序图

 读操作时序图分析:

 读操作(检查忙操作)的代码实现

 写操作时序图分析:

 写操作的代码实现

        四、显示行字符

LCD1602 初始化过程 (8bit)

五、结果展示


 一、引脚说明

 具体接线请按照原理图接线

二、开发逻辑

显示参考图

 要显示的字符可以用ASCII码来实现或者直接输出字符'xxx'实现

 显示任何字符都需要把最高位置1才能显示,例如:在第一行第5位显示,那么地址为: 0x80+0x04

LCD1602模块指令

三、读写时序图

读操作时序图分析:

 由前面引脚说明可知:RS为寄存器选择,高电平为数据寄存器,低电平为指令寄存器

 假如我们选择数据寄存器,那么RS一开始为高电平,R/W可看作一直为高电平,E使能位刚开始为低电平,经过一段时间变为高电平维持一段时间后变为低电平,DB0 ----DB7是数据位 当E使能位变为高电平后tD时间后开始读取数据

 读操作(检查忙操作)的代码实现

#include "reg52.h"
#include <intrins.h>
#define databuffer P0 
sbit RS = P2^6;
sbit RW = P2^5;
sbit EN = P2^7;

void check_busy()
{
	char temp = 0x80;
	databuffer = 0x80;
	while(temp & 0x80){
		RS = 0;	
		RW = 1;
		EN = 0;
		_nop_();//延时一个机器周期
		EN = 1;
		_nop_();
		_nop_();
		temp = databuffer;
		EN = 0;
		_nop_();
	}
}

代码分析:首先声明一个中间变量temp来存放来自P00-P07的数据,从LCD1602的模块指令可知读忙标志或地址:D7 = BF(BF = 1为检测忙状态,不可输入数据,BF = 0,可以输入数据)temp和databuffer初始化为0x80就是为了令BF = 1为检测状态,检测后数据输入BF不为1,则temp存放来自databuffer的数据,实现读操作

液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符。

 

 写操作时序图分析:

由前面引脚说明可知:RS为寄存器选择,高电平为数据寄存器,低电平为指令寄存器

 假如我们选择数据寄存器,RS一开始为高电平经过一段时间后变为低电平,R/W可以看作先为高电平然后变为低电平或者一直为低电平,E使能位则是一开始为低电平,经过一段时间后变为高电平维持一段时间后再变为低电平,DB0---DB7是数据位,在E使能位变为高电平前的tsp2时间开始写入数据

  写操作的代码实现

#include "reg52.h"
#include <intrins.h>
#define databuffer P0 
sbit RS = P2^6;
sbit RW = P2^5;
sbit EN = P2^7;
//写指令======================
void Write_cmd(unsigned char cmd)
{
	check_busy();
	RS = 0;//选择指令寄存器,写地址
	RW = 0;
	EN = 0;
	_nop_();
	databuffer = cmd;//往P0组写入数据
	_nop_();//tsp2
	EN = 1;
	_nop_();//tpw
	_nop_();//tpw
	EN = 0;
	_nop_();
}
===============================

//写数据=======================
void Write_data(unsigned char dat)
{
	check_busy();
	RS = 1;//选择数据寄存器,写数据
	RW = 0;
	EN = 0;
	_nop_();
	databuffer = dat;//在EN由低变高的时候开始传数据
	_nop_();//tsp2
	EN = 1;
	_nop_();//tpw
	_nop_();//tpw
	EN = 0;
	_nop_();
}
===============================

四、显示行字符

#include "reg52.h"
#include <intrins.h> //其中有nop函数的定义
/*对于延时很短的,要求在us级的,采用“_nop_”函数,
这个函数相当汇编NOP指令,延时几微秒。NOP指令为单周期指令,
可由晶振频率算出延时时间,对于12M晶振,延时1uS。*/
#define databuffer P0 
sbit RS = P2^6;
sbit RW = P2^5;
sbit EN = P2^7;

void Delay15ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 27;
	j = 226;
	do
	{
		while (--j);
	} while (--i);
}

void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 9;
	j = 244;
	do
	{
		while (--j);
	} while (--i);
}




//检查忙操作================
void check_busy()
{
	char temp = 0x80;
	databuffer = 0x80;
	while(temp & 0x80){ //如果最高位BF为1,那么就为忙,不能写入数据
		RS = 0;	
		RW = 1;
		EN = 0;
		_nop_();//延时一个机器周期
		EN = 1;
		_nop_();
		_nop_();
		temp = databuffer;//当databuffer给temp传入一个0,temp & 0x80,BF不为1,则开始写入数据
		EN = 0;
		_nop_();
	}
}
//==========================

//写时序操作================
void Write_cmd(unsigned char cmd)
{
	check_busy();
	RS = 0;//选择指令寄存器,写地址
	RW = 0;
	EN = 0;
	_nop_();
	databuffer = cmd;//往P0组写入数据
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
}

void Write_data(unsigned char dat)
{
	check_busy();
	RS = 1;//选择数据寄存器,写数据
	RW = 0;
	EN = 0;
	_nop_();
	databuffer = dat;//在EN由低变高的时候开始传数据
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
}
//==========================

void shouline(unsigned char row,unsigned char col,char *ptr)
{
	switch(row){
		case 1:
			Write_cmd(0x80+0x00+col);
			while(*ptr !='\0'){
				Write_data(*ptr);
				ptr++;
			}
		break;
		case 2:
			Write_cmd(0x80+0x40+col);
			while(*ptr !='\0'){
				Write_data(*ptr);
				ptr++;
			}
		break;
	}
}

void Init_LCD()
{
	//延时15ms
		Delay15ms();
	//写指令 38H 不检测忙信号
		Write_cmd(0x38);
	//延时5ms
		Delay5ms();
	//以后每次读写操作,均需要检测忙信号
	
	//写指令 38H 显示模式设置
		Write_cmd(0x38);
	//写指令 08H 显示关闭
		Write_cmd(0x08);
	//写指令 01H 显示清屏
		Write_cmd(0x01);
	//写指令 06H 光标移动设置
		Write_cmd(0x06);
	//写指令 0CH 显示开及光标设置
		Write_cmd(0x0C);
}
	


void main()
{
	//char position = 0x80+0x05;//显示位置必须令最高位置1
	//char dat 			= 'c';
	
	Init_LCD();//初始化LCD
	
	//Write_cmd(position);//选择要显示的地址
	//Write_data(dat);//选择要显示的字符
	shouline(1,5,"NO.1");
	shouline(2,2,"wish me luck");
}

LCD1602 初始化过程 (8bit)

1)延时 15ms
(2)写指令 38H( 不检测忙信号 )
(3)延时 5ms
(4)以后每次写指令,读 / 写数据操作均需要检测忙信号
(5)写指令 38H :显示模式设置
(6)写指令 08H :显示关闭
(7)写指令 01H :显示清屏
(8)写指令 06H :显示光标移动设置
(9)写指令 0CH :显示开及光标设置

void Init_LCD()
{
	//延时15ms
		Delay15ms();
	//写指令 38H 不检测忙信号
		Write_cmd(0x38);
	//延时5ms
		Delay5ms();
	//以后每次读写操作,均需要检测忙信号
	
	//写指令 38H 显示模式设置
		Write_cmd(0x38);
	//写指令 08H 显示关闭
		Write_cmd(0x08);
	//写指令 01H 显示清屏
		Write_cmd(0x01);
	//写指令 06H 光标移动设置
		Write_cmd(0x06);
	//写指令 0CH 显示开及光标设置
		Write_cmd(0x0C);
}

 五、结果展示

 

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的代码,这是一个用于控制LCD1602液晶显示屏的程序。程序使用了89C52RC单片机。程序中定义了一些函数和变量来实现LCD的控制和显示。其中,函数Write_Cmd用于写入命令,函数Write_Dat用于写入数据,函数Read_Busy用于检测LCD是否忙碌。程序中还包含了一些设置指令,如设置显示模式、显示关闭、显示清屏等。 根据引用\[3\]的代码,还可以看到一个检查忙操作的函数check_busy,用于检测LCD是否忙碌。 综上所述,这个程序是用于控制LCD1602液晶显示屏的,通过89C52RC单片机来实现。程序中包含了一些函数和指令,用于控制LCD的显示和操作。 #### 引用[.reference_title] - *1* [STC89C52单片机 LCD1602液晶显示屏](https://blog.csdn.net/qq_44989881/article/details/112221217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [[STC89C52RC]LCD1602液晶屏显示](https://blog.csdn.net/weixin_63303786/article/details/128643558)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值