51单片机基础04 LCD1602时序;Proteus仿真单片机、总线、网络标号等;

目录

一、LCD显示字符

1、写指令

(1)、LCD状态配置

(2)、显示开关与光标

2、写数据

(1)、设置地址

(2)、设置数据

3、初始化代码

(1)、初始化流程

(2)、初始化代码

4、数据显示

(1)、地址写入

(2)、数据写入

二、按键控制LED流水灯-总线与网络标号

1、原理图

2、代码


一、LCD显示字符

        打开LCD1602的控制时序图,其采用了HD44780及兼容芯片,可以看到:

        当然一般对LCD,我们都是写指令和写输入,可以先不看读的部分,注意到写指令和写数据最重要的就是RS控制进行区分。

1、写指令

(1)、LCD状态配置

        看手册关于指令码,常用的有4.1.1,00111000=0x38;

(2)、显示开关与光标

        显示开、关与光标设置,一般如果不进行输入操作的时候不显示光标,而在每次上电的时候,最好先设置关显示,进行清屏后再打开,因此一般为00001100/00001000即0X0C/0X08;

2、写数据

(1)、设置地址

        可以看到通过输入80H+地址码设置好要写的地方,即对应上面的图。

(2)、设置数据

3、初始化代码

(1)、初始化流程

        手册也提供了一个比较好的初始化流程:

(2)、初始化代码

void LCD1602_init(void)
{ 
     Delay1602(1500);               //调用延时函数
     LCD1602_Write_com(0x38);       //8位数据总线,两行显示模式,5*7点阵显示
     Delay1602(500);                //调用延时函数
     LCD1602_Write_com(0x38);       //8位数据总线,两行显示模式,5*7点阵显示
     Delay1602(500);                //调用延时函数
     LCD1602_Write_com(0x38);       //8位数据总线,两行显示模式,5*7点阵显示
     LCD1602_Write_com_busy(0x38);  //8位数据总线,两行显示模式,5*7点阵显示
     LCD1602_Write_com_busy(0x08);  //显示功能关,无光标
     LCD1602_Write_com_busy(0x01);  //清屏
     LCD1602_Write_com_busy(0x06);  //写入新的数据后,光标右移,显示屏不移动
     LCD1602_Write_com_busy(0x0C);  //显示功能开,无光标
} 

        相关的寄存器设置都在上面进行了清晰的展示。

前面说到写数据需要检测忙或者不检测,因此需要进行两个代码进行展示

①不忙写入

//1602液晶相关I/O设置
sbit E=P2^3;               //1602液晶的E脚接在P2.3口上
sbit RW=P2^4;              //1602液晶的RW脚接在P2.4口上
sbit RS=P2^5;              //1602液晶的RS脚接在P2.5口上
//写指令 不检测忙信号
void LCD1602_Write_com(unsigned char combuf)
{ 
     RS=0;                //选择指令寄存器
     RW=0;                //选择写状态
     P0=combuf;           //将命令字通过P0口送至DB
     E=1;                 //E高电平将命令字写入1602液晶
     E=0;                 //写完以后,恢复E的电平
} 

②忙检测

void LCD1602_busy(void)
{ 
     P0_7=1;              //将P0.7置1,为读状态做准备 
     RS=0;                //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
     RW=1;                //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
     E=1;                 //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
     while(P0_7==1);      //由P0.7读入1,表示1602液晶忙,需要等待
	                       //单片机处理完当前任务,忙信号P0_7自动置0(无效),即不忙
     E=0;                 //读完以后,恢复E的电平
} 

        本质上忙检测就是检测那个IO是否被LCD置位0。

4、数据显示

(1)、地址写入

void LCD1602_Write_address(unsigned char x,unsigned char y)
{ 
     x&=0x0f;             //列地址限制在0-15间
     y&=0x01;             //行地址限制在0-1间
     if(y==0)             //如果是第一行
         LCD1602_Write_com_busy(x|0x80);        //将列地址写入
     else                 //如果是第二行
         LCD1602_Write_com_busy((x+0x40)|0x80); //将列地址写入
			                 //x列数加上0x40是要从第二行的40的存储单元算起。1602共2行(每行40个存储单元)
} 

        前文提到,需要地址码+0X80,在数据语言中,|可以用来表示加法,但是如果直接用0-27、40-67在用户态很麻烦,因此一般用户端就写具体的行列,加地址在bsp驱动层完成。

(2)、数据写入

        直接调用LCD1602_Write_data_busy即可,写入的就是char字符,如果要多次显示,则多次调用即可。

LCD1602_Disp(0,0,DISbuf/100+'0');      //在第1行的第1列显示百位
LCD1602_Disp(1,0,(DISbuf%100)/10+'0'); //在第1行的第2列显示十位
LCD1602_Disp(2,0,DISbuf%10+'0');       //在第1行的第3列显示个位

二、按键控制LED流水灯-总线与网络标号

1、原理图

        可以看到本次采用了一个总线方式的连接,同时放置了网络标号。

        通过此总线可以放置蓝色的线,点击放置连线标号,输入字符串例如t1、再点击另一端也输入t1,即可实现该两端连接。

2、代码

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//延时
void DelayMS(uint x)
{
	uchar i;
	while(x--)
	{
		for(i=0;i<120;i++);
	}
}
//主程序
void main()
{
	uchar i;
	P2=0x01;
	while(1)
	{
		for(i=0;i<7;i++)
		{
			P2=_crol_(P2,1); //P2的值向左循环移动
			DelayMS(150);
		}
		for(i=0;i<7;i++)
		{
			P2=_cror_(P2,1); //P2的值向右循环移动
			DelayMS(150);
		}
	}
}

作者:陌夏微秋

物联沃分享整理
物联沃-IOTWORD物联网 » 51单片机基础04 LCD1602时序;Proteus仿真单片机、总线、网络标号等;

发表回复