1602液晶的接口说明
分享51单片机学习中的一些收获:
1602液晶是一种字符液晶,其仅仅可以显示英文和日文等字符,不能用来显示汉字。1602液晶是16x2的字符液晶,即每行可以显示16个字符,可以显示两行,第一行对应的首地址是0x80,第二行对应的首地址是0x80+0x40;
为了以后调用液晶函数方便,才写了部分关于1602液晶的程序,如有错误,恳请斧正;
程序中可以直接调用的函数都在1602.h里面有声明,并给出注释;如需要修改1602接口,请直接在1602.h里面修改,以适应硬件的实际连接。
为了以后调用液晶函数方便,才写了部分关于1602液晶的程序,如有错误,恳请斧正;
程序中可以直接调用的函数都在1602.h里面有声明,并给出注释;如需要修改1602接口,请直接在1602.h里面修改,以适应硬件的实际连接。
测试效果
下为程序代码,有注释:
为了以后调用液晶函数方便,才写了部分关于1602液晶的程序,如有错误,恳请斧正;
程序中可以直接调用的函数都在1602.h里面有声明,并给出注释;如需要修改1602接口,请直接在1602.h里面修改,以适应硬件的实际连接。
/*========下面是1602.c的内容========*/
#include "1602.h"
unsigned char code number_1602[10]={'0','1','2','3','4','5','6','7','8','9'}; //数字常量
unsigned char code week_1602[7][4]={"Mon","Tus","Wed","Tur","Fri","Sta","Sun"}; //星期常量
/* 5us延时程序 (12MHZ晶振) */
void delay_5us_1602(void)
{
_nop_();
}
/* N毫秒延时程序 (12MHZ晶振) */
void delay_ms_1602(unsigned char n)
{
unsigned char i;
while(n--)
{
for(i=0;i<120;i++);
}
}
/*****************************************************
功能函数:判断1602液晶的忙碌状态
***************************************************/
void BusyTest_1602(void)
{
RS_1602=0; //1——数据、0——指令
RW_1602=1; //1——读、0——写,此处为读指令
Data_1602=0x00; //初始化端口(亲测,加上这句初始化端口语句在仿真和硬件都能用,不加的话仿真不能用)
E_1602=1; //E=1时,才允许读
delay_5us_1602(); //延时给硬件反应时间
while(BF_1602==1); //直到忙碌标志位BF=0(即空闲)时才结束
E_1602=0;
}
/*=================================================================================
1602液晶常用指令集
1、清显示/清屏——0x01
2、地址计数器归位——0x02
3、输入模式:全部右移,游标不动——0x07
AC右移1位,游标移动1位——0x06
全部左移,游标不动——0x05
AC左移1位,游标移动1位——0x04
4、显示设置:游标显示,闪烁字符——0x0f
游标显示,不闪烁字符——0x0e
游标不显示,闪烁字符——0x0d
游标不显示,不闪烁字符——0x0c
整屏不显示,DDRAM中有内容——0x08
5、功能设置:两行,5x7显示——0x38
单行,5x7显示——0x30
两行,5x10显示——0x3c
单行,5x10显示——0x34
6、游标移动:单游标左移——0x10
单游标右移——0x14
游标显示左移——0x18
游标显示右移——0x1c
==================================================================================*/
/*****************************************************
功能函数:将模式设置指令或显示地址写入液晶模块
入口参数: dictate
***************************************************/
void WriteInstruction_1602(unsigned char dictate)
{
BusyTest_1602(); //忙检测,如果忙就等待
RS_1602=0; //1——数据、0——指令
RW_1602=0; //1——读、0——写,此处为写指令
Data_1602=dictate; //将数据送入P2口,即写入指令或地址
E_1602=1; //E置高电平,用来产生下降沿信号
delay_5us_1602();
E_1602=0; //E产生1到0的跳变,液晶模块开始执行写指令
}
/*****************************************************
功能函数:将数据(字符的标准ASCII码)写入液晶模块
入口参数: Data
***************************************************/
void WriteData_1602(unsigned char Data)
{
BusyTest_1602(); //如果忙就等待
RS_1602=1; //1——数据、0——指令
RW_1602=0; //1——读、0——写,此处为写数据
Data_1602=Data; //将数据送入P2口,即写入指令或地址
E_1602=1; //E置高电平,发生0到1跳变,产生高脉冲
delay_5us_1602();
E_1602=0; //E产生1到0的跳变,液晶模块开始执行指令
}
/*****************************************************
功能函数:对LCD的显示模式进行初始化设置
***************************************************/
void lcd1602_Initiate(void)
{
delay_ms_1602(10); //延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction_1602(0x38); //显示模式设置:16*2显示,5*7点阵,8位数据接口
delay_ms_1602(5);
WriteInstruction_1602(0x38); //显示模式设置:16*2显示,5*7点阵,8位数据接口
delay_ms_1602(5);
WriteInstruction_1602(0x0c); //显示模式设置:显示开,有光标,光标闪烁(0x0e显示光标,不闪烁;0x0f显示光标,闪烁;0x0c不显示光标,不闪烁;0x0d不显示光标,闪烁)
delay_ms_1602(5);
WriteInstruction_1602(0x06); //显示模式设置:光标右移,字符不移(0x06地址光标右移;0x04地址光标左移;0x05整屏右移;0x07整屏左移)
delay_ms_1602(5);
WriteInstruction_1602(0x01); //清屏指令,将以前的显示内容清除
delay_ms_1602(5);
}
/*****************************************************
功能函数:对1602液晶写入数字0~9
入口参数:行x , 列y , 数字numx
***************************************************/
void write_number(unsigned char x, unsigned char y, unsigned char numx)
{
if(x==1)
{
WriteInstruction_1602(0x80+y-1); //0x80是1602液晶第一行首地址(列地址)
WriteData_1602(number_1602[numx]);
}
if(x==2)
{
WriteInstruction_1602(0x80+0x40+y-1); //0x80+0x40是1602液晶第二行首地址(列地址)
WriteData_1602(number_1602[numx]);
}
}
/*****************************************************
功能函数:对1602液晶写入任意字符
入口参数:行x , 列y , 数字charx
***************************************************/
void write_char(unsigned char x, unsigned char y, unsigned char charx)
{
if(x==1)
{
WriteInstruction_1602(0x80+y-1); //0x80是1602液晶第一行首地址(列地址)
WriteData_1602(charx);
}
if(x==2)
{
WriteInstruction_1602(0x80+0x40+y-1); //0x80+0x40是1602液晶第二行首地址(列地址)
WriteData_1602(charx);
}
}
/*****************************************************
功能函数:对1602液晶写入字符串
入口参数:行x , 列y , 字符串头地址*p
***************************************************/
void write_string(unsigned char x, unsigned char y, unsigned char *p)
{
if(x==1)
{
WriteInstruction_1602(0x80+y-1); //0x80是1602液晶第一行首地址(列地址)
while(*p!='\0')
WriteData_1602(*p++);
}
if(x==2)
{
WriteInstruction_1602(0x80+0x40+y-1); //0x80+0x40是1602液晶第二行首地址(列地址)
while(*p!='\0')
WriteData_1602(*p++);
}
}
/*****************************************************
功能函数:对1602液晶写入星期(周一到周日)
入口参数:行x , 列y , 星期weekday
***************************************************/
void write_week(unsigned char x, unsigned char y, unsigned char weekday)
{
write_string(x,y,week_1602[weekday-1]);
}
/*========下面是1602.h的内容========*/
#ifndef __1602_H__
#define __1602_H__
#include <reg52.h>
#include <intrins.h>
#define Data_1602 P2 //1602液晶指令、数据并行输出口
sbit BF_1602=P2^7; //1602液晶忙碌标志位
sbit RS_1602=P0^7; //寄存器选择位,1——数据、0——指令
sbit RW_1602=P0^6; //读写选择位,1——读、0——写
sbit E_1602=P0^5; //使能信号位,1——执行读操作,1->0执行写操作
void delay_5us_1602(void);
void delay_ms_1602(unsigned char n);
void BusyTest_1602(void);
void WriteInstruction_1602(unsigned char dictate);
void WriteData_1602(unsigned char Data);
void lcd1602_Initiate(void);
void write_number(unsigned char x, unsigned char y, unsigned char numx);
void write_char(unsigned char x, unsigned char y, unsigned char charx);
void write_string(unsigned char x, unsigned char y, unsigned char *p);
void write_week(unsigned char x, unsigned char y, unsigned char weekday);
#endif
/*========下面是示例main.c的内容=======*/
#include "1602.h"
void main()
{
lcd1602_Initiate();
write_number(1,5,5);
write_number(1,6,2);
write_number(1,7,0); //第一行5、6、7列写数字520
write_char(1,8,'H');
write_char(1,9,'.');
write_char(1,10,'T');
write_char(1,11,'.');
write_char(1,12,'T'); //第一行8~12列写字符H.T.T
write_string(2,1," I love you ! "); //第二行中间写I LOVE YOU !
while(1);
}