[STC89C52RC]LCD1602液晶屏显示

目录

       一、引脚说明

       二、开发逻辑

显示参考图

LCD1602模块指令

       三、读写时序图

 读操作时序图分析:

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

 写操作时序图分析:

 写操作的代码实现

        四、显示行字符

LCD1602 初始化过程 (8bit)

五、结果展示


 一、引脚说明

[STC89C52RC]LCD1602液晶屏显示_第1张图片

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

二、开发逻辑

[STC89C52RC]LCD1602液晶屏显示_第2张图片

显示参考图

[STC89C52RC]LCD1602液晶屏显示_第3张图片

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

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

LCD1602模块指令

[STC89C52RC]LCD1602液晶屏显示_第4张图片

三、读写时序图

[STC89C52RC]LCD1602液晶屏显示_第5张图片

读操作时序图分析:

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

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

[STC89C52RC]LCD1602液晶屏显示_第6张图片

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

#include "reg52.h"
#include 
#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的数据,实现读操作

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

 [STC89C52RC]LCD1602液晶屏显示_第7张图片

 写操作时序图分析:

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

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

  写操作的代码实现

#include "reg52.h"
#include 
#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  //其中有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);
}

 五、结果展示

 [STC89C52RC]LCD1602液晶屏显示_第8张图片

你可能感兴趣的:(单片机,嵌入式硬件)