单片机C51-笔记6-STC89C51RC/RD-LCD1602篇

一、概述

        LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 16×02 即 32 字符(16列两 行)

 引脚说明

 第 1 脚: VSS 为电源地

第 2 脚: VDD 接 5V 正电源

第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度 过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度。

第 4 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第 5 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 R/W 共 同为低电平时可以写入指令或者显示地址,当 RS 为低电平 R/W 为高电平时可以读忙信号, 当 RS 为高电平 R/W 为低电平时可以写入数据。

第 6 脚:E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。

第 7-14 脚:D0~D7 为 8 位双向数据线。

第 15 脚:背光源正极。

第 16 脚:背光源负极。

/ / 和 上 官 一 号 的 接 线

/ / 电 源 V S S - - G N D V D D - - 5 V

/ / 对 比 度 V O   - - G N D

/ / 控 制 线 R S   - - P 1 . 0 R W   - - P 1 . 1 E   - - P 1 . 4

/ / 背 光 灯 A   - - 5 V K   - - G D N

/ / 数 据 D 0 到 D 7 - - P 0 . 到 P 0 . 7

 

 二、开发逻辑

LCD1602=16行*2列

 

 搞清楚,在哪显示?显示什么?

1、在哪显示?

比如N是在05这个位置上,化成二进制就是0000 0101,但是LCD1602要求写入显示地址时要求最高位 D7 恒定为高电平 1 ,所以就变成了1000 0101 = 0X85H。

比如c是在40这个位置上,化成二进制就是0100 0000,但是要求写入显示地址时要求最高位 D7 恒定为高电平 1 ,所以就变成了1100 0000 = 0XC0H。

2、显示什么?

 比如a (0110 0001) =0X61 = 97,实际上就是ACILL值

而对于单片机来讲,我发送的地址和数据都是8bit的,怎么区分呢?

比如a,地址是 1110 0001,数据是 0110 0001,在LCD区分我发送的是地址还是数据的时候,需要用到RS寄存器,高电平时选择数据寄存器、低电平时选择指令寄存器。

 三、时序

LCD1602 的基本的操作分为读操作和写操作。

其中读操作可以分为读状态和读数据;写操作可以分为写指令和写数据。

读状态:输入 RS=0、RW=1、E=1;输出:D0~7 读出为状态字;

读数据:输入 RS=1、RW=1、E=1;输出:D0~7 读出为数据;

写指令:输入 RS=0、RW=0、E=上升沿;写入控制指令;

写数据:输入 RS=1、RW=0、E=上升沿;写入需要显示的字符。

读操作时序

 写操作时序

我们以写操作为例,分析一下时序图。

当我们要写指令的时候,RS 置为低电平,RW 置为低电平,E 置为低电平,然后将指令数据送到数据口 D0~D7,延时 tsp1,让 LCD1602 准备接收数据,这时候将 E 拉高,产生一个上升沿,这时候指令就开始写入 LCD1602,延时一段时间,将 E 置为低电平。

当我们要写数据的时候,RS 置为高电平,RW 置为低电平,E 置为低电平,然后将指令数据送到数据口 D0~D7,延时 tsp1,让 LCD1602 准备接收数据,这时候将 E 拉高,产生一个上升沿,这时候数据就开始写入 LCD1602,延时一段时间,将 E 置为低电平。

对比一下可以发现,写指令和写数据在时序上只是 RS 的不同,写指令 RS=0,写数据 RS=1。

 

数序参数

 四、显示一个字符C

代码如下:

#include "reg52.h"
#include "intrins.h"

#define databuffer P0 //定义8位数据线,P0端口组

sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;

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

	_nop_();
	_nop_();
	i = 1;
	j = 162;
	k = 89;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
void check_busy()//检测忙信号
{
	char tmp = 0x80;
	databuffer = 0x80;
	while(tmp & 0x80){//1000 0000
	RS = 0;
	RW = 1;
	EN = 0;
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	tmp = databuffer;
	EN = 0;
	_nop_(); 
	}
}

void Write_Cmd_Func(char cmd)//写入指令/地址函数
{
	check_busy();
	RS = 0;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = cmd;//一个字节一个字节的传输
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
	
}

void Write_Data_Func(char dataShow)//写入数据函数
{
	check_busy();
	RS = 1;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = dataShow;//一个字节一个字节的传输
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
}


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

void main()
{

	char position = 0X80 + 0X05;//地址
	char dataShow = 'C';//数据
	LCD1602_INIT();
	
	Write_Cmd_Func(position);//选择要显示的地址
	Write_Data_Func(dataShow);//选择要显示的数据
 } 

五、显示字符串

代码如下:

#include "reg52.h"
#include "intrins.h"

#define databuffer P0 //定义8位数据线,P0端口组

sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;

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

	_nop_();
	_nop_();
	i = 1;
	j = 162;
	k = 89;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
void check_busy()//检测忙信号
{
	char tmp = 0x80;
	databuffer = 0x80;
	while(tmp & 0x80){//1000 0000
	RS = 0;
	RW = 1;
	EN = 0;
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	tmp = databuffer;
	EN = 0;
	_nop_(); 
	}
}

void Write_Cmd_Func(char cmd)//写入地址函数
{
	check_busy();//每次输入指令前都要判断液晶模块是否处于忙的状态
	RS = 0;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = cmd;//一个字节一个字节的传输
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
	
}

void Write_Data_Func(char dataShow)//写入数据函数
{
	check_busy();//每次输入指令前都要判断液晶模块是否处于忙的状态
	RS = 1;
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = dataShow;//一个字节一个字节的传输
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
}


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

void LCD1602_showLine(char row,char col,char *string){//行、列、字符串
	
	switch(row){
		
		case 1:
			Write_Cmd_Func(0x80+col);//最高位是1,第一行
		while(*string){
			Write_Data_Func(*string);
			string++;
		}
		break;
		
		case 2:
			Write_Cmd_Func(0x80+0x40+col);//最高位是1,第二行
		while(*string){
			Write_Data_Func(*string);
			string++;
		}
		break;
	}
}

void main()
{

	char position = 0X80 + 0X05;//地址
	//char dataShow = 'C';//数据
	LCD1602_INIT();
	
	LCD1602_showLine(1,5,"I LOVE YOU");
	LCD1602_showLine(2,0,"HuangJingYuan");
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值