📄 lcd.c
字号:
/******************用口线方式驱动LCD1602****************************************
接口 DBi-P0.i(i=0~7), RS-P10; RW-P11; E-P12;
LEDA(15#)通过电阻连Vcc,也可直接连Vcc;
Vo(3#)通过电阻连地,也可直接连地;
*******************************************************************************/
#include<AT89x51.h> //或include<AT89x51.h> 此时P10为P1_0;
#include<intrins.h>
#include<absacc.h> //头函数
#define uint unsigned int
#define uchar unsigned char
#define nop _nop_()
#define LCD_DATA P0 //数据线
sbit LCD_RS=P1^1; //定义引脚
sbit LCD_RW=P1^2;
sbit LCD_E=P1^0;
sbit LCD_BF=P0^7;
/*******************************定义函数**************************************/
void WriteDataLcd(uchar dat); //定义写数据函数
void WriteCommandLcd(uchar com,bit BusyCheck); //定义写指令函数
uchar ReadStateLcd(void); //定义读LCD状态函数,未用
void WaitLcd();//检测忙信号,若忙则等待
void InitLcd(void); //定义LCD初始化函数
void Delay5ms(void); //定义延迟5ms函数
void Delay400ms(void); //定义延迟400ms函数
void DisplayOneChar(uchar X,uchar Y,uchar DData);//定义显示单个字符函数 X-列;Y-行
void DisplayListChar(uchar X,uchar Y,uchar *DData);//定义显示一串字符函数
void Ena(void); //使能
int InitFlag=0;
//uchar code first[]={"Lookforward."}; //定义输出字符
//uchar code second[]={"Ourfuture..."};
/**********************************主函数************************************/
void LcdSingle(uchar lie,uchar hang,uchar single)
{
if(!InitFlag)
{
InitLcd();
InitFlag=1;
}
DisplayOneChar(lie,hang,single);
}
void LcdList(uchar hang, uchar *list)
{
if(!InitFlag)
{
InitLcd();
InitFlag=1;
}
DisplayListChar(0,hang,list); //第hang行显示一串字符
}
/**********************************初始化函数************************************/
void InitLcd(void)
{
Delay400ms();
WriteCommandLcd(0x38,0);
Delay5ms();
WriteCommandLcd(0x38,0);
Delay5ms();
WriteCommandLcd(0x38,0);
Delay5ms(); /*说明书上说明初始化先要写三次0x38,并且暂不检测忙信号*/
WriteCommandLcd(0x38,1);
/*显示模式设置(8位数据接口,两行显示,5*7点阵字符),开始要求每次检测忙信号*/
WriteCommandLcd(0x08,1);//关闭显示
WriteCommandLcd(0x01,1);//显示清屏
WriteCommandLcd(0x06,1); // 显示光标移动设置,AC自动增一
WriteCommandLcd(0x0C,1); // 显示开及光标设置
}
/**********************************写指令函数************************************/
void WriteCommandLcd(uchar com,bit BusyCheck)
{
if(BusyCheck) WaitLcd();
LCD_RS=0;
LCD_RW=0;
LCD_DATA=com;
Ena();
}
/**********************************写数据函数************************************/
void WriteDataLcd(uchar dat)
{
WaitLcd(); //检测忙
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA=dat;
Ena();
}
/**********************************检测忙函数************************************/
void WaitLcd(void)
{
LCD_RS=0;
LCD_RW=1;
LCD_DATA=0X00; /*置为0xFF将会出错,LCD无显示,由此怀疑WaitLcd作用*/
LCD_E=1;
nop;
while(LCD_BF);
LCD_E=0;
}
void Ena()
{
LCD_E=1;
Delay5ms(); /********^^^^^^必须延迟一段时间才有效^^^^^^^^*****************/
LCD_E=0;
}
/**********************************延时5ms************************************/
void Delay5ms()
{
uint TempCyc=5552;
while(TempCyc--);
}
/**********************************延时400ms************************************/
void Delay400ms()
{
uchar TempCycA=5;
uint TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
}
}
/**********************************显示单个字符************************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=0x1;
X&=0xf; //限制X不能大于15,Y不能大于1
if(Y)X|=0x40; //当要显示第二行时地址码+0x40;
X|=0x80; //算出指令码
WriteCommandLcd(X,0);//这里不检测忙信号,发送地址码
WriteDataLcd(DData);
}
/**********************************显示一串字符************************************/
void DisplayListChar(uchar X,uchar Y,uchar *DData)
{
uchar ListLength=0;
Y&=0x1;
X&=0xf; //限制X不能大于15,Y不能大于1
while(DData[ListLength]>0x20) //若到达字串尾则退出,字符长度小于16
{
if(X<=0xf) //X坐标应小于0xF(15)
{
DisplayOneChar(X,Y,DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
/**********************************END************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -