具体功能概括
在前边模拟过短信接收装置的基础上,添加上了搜索功能,可以通过联系人的姓的大写首字母来进行联系人电话号码的搜索。
按键类似于老式手机的按键:
7(A B C) 8(D E F) 9(G H I) 储存键
4(J K L) 5(M N O)6(P Q R)读取和显示键
1(S T U) 2(V W X) 3(Y Z) 删除键
上翻键 0 下翻键 空闲键
(括号表示按下不同的次数对应不同的数字和字母)
按键的时序是,通过串口发送过数据后,按下数字键选择储存地址,然后按储存键表示储存完成。想要删除某个信息,先确定地址,然后按下删除键即可。当储存完成后,(比如存了XXM123456789,XXM表示名字首字母大写,后边的是电话号码),通过按键选出对应的首字母“X”(可在LCD1602的右下角看到此时显示的是那个字母或数字),然后按下读取和显示键,屏幕上会显示出对应的信息。如果首字母相同的有多个人,多次按下读取键会循环显示符合要求的全部联系人信息。(代码中默认的是X,W,C开头的六个联系人,X有两个,W有三个,C有一个,可以自行修改或增添)。上翻键和下翻键可以查看联系人列表,包括已储存和未储存的(未储存的会显示空白)
源代码
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit SDA=P2^0;
sbit SCL=P2^1;//IIC通讯位定义
sbit RS=P3^5;
sbit RW=P3^6;
sbit EN=P3^4;//LCD1602显示位定义
uchar i=0;//串口接收字符串变量
uchar x=0;//字符串数组长度
uchar a=0;//短信储存地址变量
uchar tabel1[16];//用于接收串口传输过来的字符串
uchar tabel2[16];//用于储存从AT24C02中读取出来的字符串
uchar tabel3[10]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90};//用于储存字符串储存的地址
uchar tabel4[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};//LCD1602显示地址
uchar b,c,d,e,f,g,h,j,k,y,z1,z2,z3;
uchar z;
/********串口通信********/
void UARTInit()//串口的初始化
{
TMOD|=0X20;
TH1=0XFD;
TL1=0XFD;
TR1=1;
SM0=0;
SM1=1;
REN=1;
EA=1;
ES=1;
}
void UART() interrupt 4
{
uchar temp;
if(RI)
{
temp=SBUF;
RI=0;
if(temp!='\0')
{
tabel1[i]=temp;
i++;
}
}
}
/********LCD1602********/
void Read_Busy()
{
uchar busy;
P0=0XFF;
RS=0;
RW=1;
do
{
EN=1;
busy=P0;
EN=0;
}while(busy&0x80);
}
void Write_cmd(uchar cmd)
{
Read_Busy();
RS=0;
RW=0;
P0=cmd;
EN=1;
EN=0;
RS=1;
RW=1;
EN=1;
}
void Write_dat(uchar dat)
{
Read_Busy();
RS=1;
RW=0;
P0=dat;
EN=1;
EN=0;
RS=1;
RW=1;
EN=1;
}
void LCD1602Init()
{
Write_cmd(0x38);
Write_cmd(0x0c);
Write_cmd(0x01);
}
void LCDWrite1()
{
Write_cmd(0x4f|0x80);
Write_dat(y);//在右下角显示按键代表的字母
}
void LCDWrite()//LCD1602第一行写数据
{
x=0;
Write_cmd(0x01);
while(x<16)
{
Write_cmd(tabel4[x]|0x80);
Write_dat(tabel2[x]);
x++;
}
}
/********IIC********/
void delay_10us()
{
_nop_();
_nop_();
}
void delay_write(uint a)
{
uint b;
for(b=0;b<a;b++);
}
void Init()
{
SCL=1;
delay_10us();
SDA=1;
delay_10us();
}
void Start()
{
SDA=1;
delay_10us();
SCL=1;
delay_10us();
SDA=0;
delay_10us();
SCL=0;
delay_10us();
}
void Stop()
{
SDA=0;
delay_10us();
SCL=1;
delay_10us();
SDA=1;
delay_10us();
}
void Writebyte(uchar a)
{
uchar b,temp;
temp=a;
for (b=0;b<8;b++)
{
temp=temp<<1;
SCL=0;
delay_10us();
SDA=CY;
delay_10us();
SCL=1;
delay_10us();
}
SCL=0;
delay_10us();
SDA=1;
delay_10us();
}
uchar Readbyte()
{
uchar i,j,k=0;
SCL=0;
delay_10us();
SDA=1;
for (i=0;i<8;i++)
{
delay_10us();
SCL=1;
delay_10us();
if(SDA==1)
j=1;
else
j=0;
k=(k<<1)|j;
SCL=0;
}
delay_10us();
return k;
}
void ACK()
{
uchar i=0;
SCL=1;
delay_10us();
while((SDA==1)&&(i<255))
i++;
SCL=0;
delay_10us();
}
uchar ReadAT24C02(uchar ADDR)
{
uchar i;
Start();
Writebyte(0xa0);
ACK();
Writebyte(ADDR);
ACK();
Start();
Writebyte(0xa1);
ACK();
i=Readbyte();
Stop();
delay_write(100);
return i;
}
void WriteAT24C02(uchar ADDR,uchar DATA)
{
Start();
Writebyte(0xa0);
ACK();
Writebyte(ADDR);
ACK();
Writebyte(DATA);
ACK();
Stop();
delay_write(500);
}
/********数据处理********/
void Show_information()//显示AT24C02中读取出来的信息
{
LCDWrite();
}
void Save_information(uchar a)//将数据保存到LCD1602之中
{
x=0;
while(x<16)
{
WriteAT24C02(tabel3[a]+x,tabel1[x]);
tabel1[x]=0x20;//顺便将储存用的数组清空
x++;
}
}
void Get_information(uchar a)//从储存的地址中读出数据
{
x=0;
Write_cmd(0x01);
while(x<16)
{
tabel2[x]=ReadAT24C02(tabel3[a]+x);
x++;
}
}
void Delete_information(uchar a)//删除储存的数据
{
x=0;
while(x<16)
{
WriteAT24C02(tabel3[a]+x,0X20);
x++;
}
}
/********矩阵键盘********/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void keyscan()
{
uchar temp;
P3=0XFF;
P3=0XFE;
temp=P3&0XF0;
if(temp!=0xf0)
{
delay(20);
P3=0XFE;
temp=0xf0&P3;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:b++;break;
case 0xde:c++;break;
case 0xbe:d++;break;
case 0x7e:Save_information(a);break;//储存键
}
while(temp!=0xf0)
{
temp=P3&0XF0;
}
switch(b)
{
case 1:a=7;y=7+'0';break;
case 2:y='A';break;
case 3:y='B';break;
case 4:y='C';b=0;break;
}
switch(c)
{
case 1:a=8;y=8+'0';break;
case 2:y='D';break;
case 3:y='E';break;
case 4:y='F';c=0;break;
}
switch(d)
{
case 1:a=9;y=9+'0';break;
case 2:y='G';break;
case 3:y='H';break;
case 4:y='I';d=0;break;
}
LCDWrite1();
}
}
P3=0XFF;
P3=0XFd;
temp=P3&0XF0;
if(temp!=0xf0)
{
delay(20);
P3=0XFd;
temp=0xf0&P3;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:e++;break;
case 0xdd:f++;break;
case 0xbd:g++;break;
case 0x7d:z1++;z2++;z3++;break;//读取和展示键
}
while(temp!=0xf0)
{
temp=P3&0XF0;
}
switch(e)
{
case 1:a=4;y=4+'0';break;
case 2:y='J';break;
case 3:y='K';break;
case 4:y='L';e=0;break;
}
switch(f)
{
case 1:a=5;y=5+'0';break;
case 2:y='M';break;
case 3:y='N';break;
case 4:y='O';f=0;break;
}
switch(g)
{
case 1:a=6;y=6+'0';break;
case 2:y='P';break;
case 3:y='Q';break;
case 4:y='R';g=0;break;
}
if(y=='X')
{
switch(z1)
{
case 1:Get_information(0);z2=0;z3=0;delay(3);Show_information();break;
case 2:Get_information(1);z1=0;z2=0;z3=0;delay(3);Show_information();break;
}
}
if(y=='W')
{
switch(z2)
{
case 1:Get_information(2);z1=0;z3=0;delay(3);Show_information();break;
case 2:Get_information(3);z1=0;z3=0;delay(3);Show_information();break;
case 3:Get_information(4);z2=0;z1=0;z3=0;delay(3);Show_information();break;
}
}
if(y=='C')
{
switch(z3)
{
case 1:Get_information(5);z3=0;z1=0;z2=0;delay(3);Show_information();break;
}
}
LCDWrite1();
}
}
P3=0XFF;
P3=0XFb;
temp=P3&0XF0;
if(temp!=0xf0)
{
delay(20);
P3=0XFb;
temp=0xf0&P3;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:h++;break;
case 0xdb:j++;break;
case 0xbb:k++;break;
case 0x7b:Delete_information(a);break;//删除键
}
while(temp!=0xf0)
{
temp=P3&0XF0;
}
switch(h)
{
case 1:a=1;y=1+'0';break;
case 2:y='S';break;
case 3:y='T';break;
case 4:y='U';h=0;break;
}
switch(j)
{
case 1:a=2;y=2+'0';break;
case 2:y='V';break;
case 3:y='W';break;
case 4:y='X';j=0;break;
}
switch(k)
{
case 1:a=3;y=3+'0';break;
case 2:y='Y';break;
case 3:y='Z';k=0;break;
}
LCDWrite1();
}
}
P3=0XFF;
P3=0XF7;
temp=P3&0XF0;
if(temp!=0xf0)
{
delay(20);
P3=0XF7;
temp=0xf0&P3;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:z++;if(z==11) z=0;break;//上翻查看储存的信息
case 0xd7:a=0;y=(0+'0');break;
case 0xb7:z--;if(z==0) z=11;break;//下翻查看储存的信息
case 0x77:break;
}
while(temp!=0xf0)
{
temp=P3&0XF0;
}
switch(z)
{
case 1:Get_information(0);delay(5);Show_information();break;
case 2:Get_information(1);delay(5);Show_information();break;
case 3:Get_information(2);delay(5);Show_information();break;
case 4:Get_information(3);delay(5);Show_information();break;
case 5:Get_information(4);delay(5);Show_information();break;
case 6:Get_information(5);delay(5);Show_information();break;
case 7:Get_information(6);delay(5);Show_information();break;
case 8:Get_information(7);delay(5);Show_information();break;
case 9:Get_information(8);delay(5);Show_information();break;
case 10:Get_information(9);delay(5);Show_information();break;
}
}
}
P3=0XFF;
}
/********main函数********/
void main()
{
uchar i;
UARTInit();
Init();
LCD1602Init();//一系列的初始化函数
for(i=0;i<16;i++)
{
tabel1[i]=0x20;
tabel2[i]=0x20;
}//手动清空AT24C02里的数据
while(1)
{
keyscan();
}
}
写在后边
实现拨打电话功能将在后边完善,代码可能会有冗余,个位大神可以进行优化。
感觉博主写的不错的小伙伴,别忘了点个赞哈~