?? 信息收發備份增強版.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 + -