📄 信息收发备份增强版.c
字号:
#include<at89x51.h>
sbit rs=P3^5;
sbit rw=P3^4;
sbit e=P3^3;
sbit d7=P1^7;
unsigned char store1,store2,store;//用于全局扫瞄键值决定用
unsigned char k; //显示地址变量
unsigned char store_send_number[32];//存放要发送的数据,注意数组的元素不要过多!!!十分重要
unsigned char m;//存放发送数据的个数的计数
unsigned char f;//存放接收数据个数 后者为清除键是否起作用键
unsigned char store_receive_number[70];//存放要发送的数据
void delay(unsigned char a)//延时a*1ms
{
unsigned char b;
while(--a!=0)
{
for(b=0;b<125;b++);
}
}
void if_busy(void)//液晶忙否判断
{ P1=0xff;//很必要
rs=0;rw=1;
e=0;e=1;
while(d7==1); //先执行读忙指令再能判断忙
}
void rst_serial_port()//初始化串口
{
SCON=0x50;//串口工作方式3,双机工作 ,接收发送中断位置零 接收允许REN=1
PCON=0x80;//串口波特率倍增,即设定SMOD=1;
TMOD=0x20;//定时器1工作方式2,用于产生波特率
TH1=0xfd;
TL1=0xfd;//设定波特率为19200kbs
ET1=0;
ES=1;//串口中断允许
PS=1;//串口中断优先级最高 很重要!!!!否则接收的不稳定
TR1=1;//启动定时器,注意不能允许定时器中断,否则会与串口中断干扰
RI=0;TI=0;EA=1;//设定所有的值才开中断!
}
void send_or_receive(void) interrupt 4//串行口中断处理 接收使用中断清除中断标志
{
if(f!=70)
{
store_receive_number[f]=SBUF;
P3_2=0;//接收到数据时就驱动蜂鸣器
f++;
RI=0;//接收中断清零
}
}
void rst_lcd(void)
{
if_busy();
P1=0x01;
rs=0;rw=0;
e=0;e=1;//执行清显示
if_busy();P1=0x38;
rs=0;rw=0;
e=0;e=1;//显示模式设定:双行、5*7格式、8位数据转送
if_busy();P1=0x0e;
rs=0;rw=0;
e=0;e=1;//显示设定:光标有且不闪动,开显示
if_busy();P1=0x06;
rs=0;rw=0;
e=0;e=1;//光标和显示模式:光标右移,字不移动
}
void show(unsigned char c)
{
if_busy();
rs=0;rw=0;
P1=k;delay(20);//让液晶能过正确地接收数据
if(k==0xc0)delay(20);//由于液晶是慢显示器件,因此需要换行地址的读取时先延时!很重要否则会出错
e=0;e=1;//写入显示的地址
k=k+0x01;//地址移至下一位
if(k==0x90)
{
k=0xc0;//当到达第一行末尾时换行
}
if_busy();
rs=1;rw=0;
P1=c;delay(20);
e=0;e=1;//执行
store_send_number[m]=c;//存入写入的数据
m+=1;//为下个数据的存入做准备
}
void which(void)//进行按键的二次选择
{
while(P2!=0x0f); //等待第一次按键的释放
delay(20);//按键释放去抖动
P2=0xf0;
while(P2==0xf0);//等待第二次按键的输入
delay(20);//去抖动处理
if(P2!=0xf0)
{
store1=P2;
P2=0x0f;
store2=P2;
store=store1|store2;//注意|是进行或运算 ;||是逻辑或
}
while(P2!=0x0f);delay(20);//等待按键的释放
}
void key11(void)
{
which();
if(store==0xbd)
{
show('a');//显示a,液晶的ascll码的字母和数字和计算机相同 ,一次可以这样赋值
}
if(store==0x7d)
{
show('b');
}
if(store==0xee)
{
show('c');
}
}
void key21(void)
{
which();
if(store==0xbd)
{
show('d');
}
if(store==0x7d)
{
show('e');
}
if(store==0xee)
{
show('f');
}
}
void key31(void)
{
which();
if(store==0xbd)
{
show('g');
}
if(store==0x7d)
{
show('h');
}
if(store==0xee)
{
show('i');
}
}
void key41(void)
{
which();
if(store==0xbd)
{
show('j');
}
if(store==0x7d)
{
show('k');
}
if(store==0xee)
{
show('l');
}
}
void key12(void)
{
which();
if(store==0xbd)
{
show('m');
}
if(store==0x7d)
{
show('n');
}
if(store==0xee)
{
show('o');
}
}
void key22(void)
{
which();
if(store==0xbd)
{
show('p');
}
if(store==0x7d)
{
show('q');
}
if(store==0xee)
{
show('r');
}
}
void key32(void)
{
which();
if(store==0xbd)
{
show('s');
}
if(store==0x7d)
{
show('t');
}
if(store==0xee)
{
show('u');
}
}
void key42(void)
{
which();
if(store==0xbd)
{
show('v');
}
if(store==0x7d)
{
show('w');
}
if(store==0xee)
{
show('x');
}
}
void key13(void)
{
which();
if(store==0xbd)
{
show('y');
}
if(store==0x7d)
{
show('z');
}
if(store==0xee)
{
show(' ');
}
}
void key23(void)
{
which();
if(store==0xbd)
{
show('!');//空格
}
if(store==0x7d)//显示句号
{
show('?');
}
if(store==0xee)//显示感叹号
{
show('.');
}
}
void clear()//清屏
{
unsigned char b;
if(m!=0)
{
k=0x80;
if_busy();P1=0x01;rs=0;rw=0;e=0;e=1;//执行清显示
if(m==1){m=0;}
else
{
for(b=0;b<(m-1);b++,m--){show(store_send_number[b]);}
m--;
}
}
}
void show_success(void)//发送成功后显示success!
{
if_busy();m=0;k=0x80;//地址回到开头
show('s');show('u');show('c');show('c');show('e');show('s');show('s');show('!');
}
void send_data(void)
{
unsigned char n=0;
REN=0;EA=0;//发送时在程序中把发送中断标志位清零
while(n<m)//m的最大值为32
{
SBUF=store_send_number[n];//装入数据寄存器
while(TI==0);//等待发送完成
TI=0;//中断标志清零
n++;
}
if_busy();
rs=0;rw=0;P1=0x01;delay(50);
e=0;e=1;delay(100);
show_success();//发送成功后显示success字样
REN=1;EA=1;//接收允许 中断允许
P2=0xf0;while(P2==0xf0);//等待按键的输入开始新的数据输入或数据接收
delay(20);
if(P2!=0xf0)//按下任意键实现数据的重新输入
{
if_busy();rs=0;rw=0;P1=0x01;delay(20);e=0;e=1;//清屏
k=0x80;m=0;store_send_number[0]=0;//清空数据
while(P2!=0xf0);//等待按键的释放
delay(50);//去抖动处理
}
}
void receivedata(void)
{
unsigned char x=0;
P3_2=1;
if_busy();rs=0;rw=0;P1=0x01;delay(20);e=0;e=1;delay(20);//清屏
k=0x80;//开头开始显示
for(x=0;x<f;x++)
{
if_busy();
show(store_receive_number[x]);
if((x+1)%31==0)
{
show('>');P2=0xf0;//当显示32个字符后 用>提示下一页有信息
while(P2==0xf0);delay(20);
if_busy();rs=0;rw=0;P1=0x01;delay(20);e=0;e=1;delay(20);//清屏
k=0x80;//按下任意键后显示未显示的字符
}
}
store_send_number[0]=0;//发送数据第一个清零
store_receive_number[0]=0;//防止按下接收键时重新接收
m=0;f=0;k=0x80;REN=1;EA=1;//重新开接收
P2=0xf0;while(P2==0xf0);delay(20); //按下任意键实现清屏
if_busy();rs=0;rw=0;P1=0x01;delay(20);e=0;e=1;delay(20);//清屏
}
void whichkey(void)
{
P2=0x0f;
store2=P2;//由于按键未释放,因此store2的值不是0fH
store=store1|store2;//得到变化的键值
if(store==0xe7)//与键key11值比较
{
key11();//进入键的执行
}
if(store==0xd7)//与键key21比较
{
key21();
}
if(store==0xb7)
{
key31();
}
if(store==0x77)
{
key41();
}
if(store==0xeb)
{
key12();
}
if(store==0xdb)
{
key22();
}
if(store==0xbb)
{
key32();
}
if(store==0x7b)
{
key42();
}
if(store==0xed)
{
key13();
}
if(store==0xdd)
{
key23();
}
if(store==0xbe)
{
if(m!=0)
{
send_data();
}
}
if(store==0x7e)
{
if(store_receive_number[0]!=0)
{
REN=0;EA=0;//显示时先禁止接收
receivedata();
}
}
if(store==0xde){clear();while(P2!=0x0f);delay(20);}//清除数据
}
void main(void)
{
rst_lcd();//初始化
f=0;m=0;k=0x80;rst_serial_port();
while(1)//初始化后cpu一直进行按键的判断
{
P2=0xf0;
if(P2!=0xf0)
{
delay(20);
if(P2!=0xf0)
{
P3_2=1;//关闭蜂鸣器,当接收到数据时按下除接收键外的按键能实现关闭蜂鸣器的目的
store1=P2;
whichkey();//键值判断
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -