///////////////根据自己板子改引脚////////////
#define IODATA P0
sbit E =P2^5; //1602使能引脚
sbit RW =P2^6; //1602读写引脚
sbit RS =P2^7; //1602数据/命令选择引脚
////////////////////////////////////////////
/******************************************************
*功能:延时
******************************************************/
void delay1602()
{
uchar i=10;
while(i--);
}
void del1602(uint delay)
{
uint i,j;
for(i=0;i<delay;i++)
for(j=0;j<=148;j++);
}
/******************************************************
* 名称 : bit Busy(void)
* 功能 : 读状态函数,是否处在忙状态
******************************************************/
void Busy(void)
{
bit busy_flag = 1;
IODATA = 0xff;
RS = 0;
delay1602();
RW = 1;
delay1602();
E = 1;
while(1)
{
busy_flag = (bit)(IODATA & 0x80);
if(busy_flag == 0)
{
break;
}
}
E = 0;
}
/******************************************************
* 名称 : lcd1602_wcmd(uchar tdata)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
******************************************************/
void lcd1602_wcmd(uchar tdata)
{
RS = 0;
delay1602();
RW = 0;
delay1602();
E = 0;
delay1602();
IODATA = tdata;
delay1602();
E = 1;
delay1602();
E = 0;
}
/******************************************************
* 名称 : lcd1602_wdata(uchar tdata)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
******************************************************/
void lcd1602_wdata(uchar tdata)
{
Busy();
delay1602();
RS = 1;
delay1602();
RW = 0;
delay1602();
E = 0;
delay1602();
IODATA = tdata;
delay1602();
E = 1;
delay1602();
E = 0;
}
/******************************************************
* 名称 : lcd1602_init()
* 功能 : 1602初始化
******************************************************/
void lcd1602_init(void)
{
del1602(15);
lcd1602_wcmd(0x38);
del1602(5);
lcd1602_wcmd(0x38);
del1602(5);
lcd1602_wcmd(0x38);
lcd1602_wcmd(0x38);
Busy();
lcd1602_wcmd(0x08);
Busy();
lcd1602_wcmd(0x01);
Busy();
lcd1602_wcmd(0x06);
Busy();
lcd1602_wcmd(0x0c);
}
/******************************************************
* 名称 : lcd1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,
调用该函数如下 L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
******************************************************/
void lcd1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
Busy();
lcd1602_wcmd(a);
Busy();
lcd1602_wdata(sign);
}
/******************************************************
* 名称 : lcd1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"LCD1602" ,
调用该函数如下 L1602_string(1,5,"LCD1602;")
* 输入 : 行,列,需要输入1602的数据
******************************************************/
void lcd1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
while(1)
{
Busy();
lcd1602_wcmd(a);
Busy();
lcd1602_wdata(*p);
a++;
p++;
if((*p == '\0')||(a==0x90)||(a==0xd0))
{
break;
}
}
}
/******************************************************
* 名称 : lcd1602_wdata10(uchar add,uint date)
* 功能 : lcd1602_wdata10(0x80,5000)
* 输入 : 写十进制到地址
******************************************************/
void lcd1602_wdata10(uchar add,uint date)
{
uchar L1,L2,L3,L4,L5,a;
L5=date/10000;
L4=date%10000/1000;
L3=date%10000%1000/100;
L2=date%10000%1000%100/10;
L1=date%10000%1000%100%10;
if(L1!=0){a=1;};
if(L2!=0){a=2;};
if(L3!=0){a=3;};
if(L4!=0){a=4;};
if(L5!=0){a=5;};
switch (a){
case 5:
lcd1602_wcmd(add);
lcd1602_wdata(0x30+L5);
lcd1602_wdata(0x30+L4);
lcd1602_wdata(0x30+L3);
lcd1602_wdata(0x30+L2);
lcd1602_wdata(0x30+L1);break;
case 4:
lcd1602_wcmd(add);
lcd1602_wdata(0x30+L4);
lcd1602_wdata(0x30+L3);
lcd1602_wdata(0x30+L2);
lcd1602_wdata(0x30+L1);break;
case 3:
lcd1602_wcmd(add);
lcd1602_wdata(0x30+L3);
lcd1602_wdata(0x30+L2);
lcd1602_wdata(0x30+L1);break;
case 2:
lcd1602_wcmd(add);
lcd1602_wdata(0x30+L2);
lcd1602_wdata(0x30+L1);break;
case 1:
lcd1602_wcmd(add);
lcd1602_wdata(0x30+L1);break;
default:break;
}
}
/******************************************************
* 名称 : lcd1602_wdata16(uint date);
* 功能 : lcd1602_wdata16(0x10)
* 输入 : 写十六进制到地址
******************************************************/
void lcd1602_wdata16(uint date)
{
uchar dat_H,dat_L;
dat_H=date>>8;
dat_L=date;
lcd1602_wdata(dat_H);
lcd1602_wdata(dat_L);
}
/******************************************************
* 名称 : lcd1602_write_pic(uchar add,uchar *pic_num)
* 功能 : lcd1602_string(i,pic)
* 输入 : 写入自定义字符到CGRAM
******************************************************/
void lcd1602_write_pic(uchar add,uchar *pic_num)
{
uchar i;
add=add<<3;
for(i=0;i<8;i++)
{
lcd1602_wcmd(0x40|add+i);
lcd1602_wdata(*pic_num++);
}
}
/******************************************************
定位光标
******************************************************/
void lcd1602_locate(unsigned char x,unsigned char y)
{
unsigned char aa;
if (x==1) aa=0x80;
if (x==2) aa=0x80+0x40;
Busy();
lcd1602_wcmd(aa+y-1);
Busy();
}