本段程序的功能使用4*4鍵盤來進行26的英文字母和兩個標點的輸入
#include<at89x52.h>
#include<12864.h> //12864驅動程序,這個在網上很好找的
#include<44jianpan.h> //4*4鍵盤驅動程序
#define uchar unsigned char
uchar idata h[16]={" "}; //清顯示緩存
uchar code asc[]={'0','1','2','3','4','5','6','7','8','9',' '};
uchar code letter[10][3]={{",.0"},{"abc"},{"def"},{"ghi"},{"jkl"},
{"mno"},{"pqr"},{"stu"},{"vwx"},{"yz0"}};
/*第一個按鍵和最後一個按鍵值數組多了一個0是爲了讓數組長度和其他的一致,在後面的輸入時可以使按鍵值不顯示*/
//相應按鍵的按鍵字母
菜單一按鍵功能 菜單二按鍵功能
uchar code a[]={"輸入基站號碼: "};
uchar code b[]={"羣發 "};
uchar code c[]={"無此號碼! "};
uchar code d[]={"輸入要發送內容: "};
uchar code e[]={" "};
uchar i,x,number,let,di;
bit menu,nl,ci,qun,qq,ps;
//i輸入數據個數標識,x發送數據個數標識
//ps發送狀態標識,nl數字字母切換標識
//menu菜單頁數標誌位,number基站號碼標誌位,qun羣發標識
//ci按鍵次數標識,let案件之暫存,di同一個按鍵被按次數
void ser(void)interrupt 4
{
TI=0;
RI=0;
ES=0;
ps=1;
}
void set(void) //串口發送
{
if(x<16)
{
ES=1;
SBUF=h[x];
x++;
}
if(x==16)
{
x=0;
}
ps=0;
}
void dis() //顯示提示內容和輸入的內容
{
uchar t;
lcdpos(0,0);
for(t=0;t<=15;t++)
{
write(1,d[t]);
}
lcdpos(1,0);
for(t=0;t<=15;t++)
{
write(1,h[t]);
}
}
void clr(uchar y) //清楚y行的內容
{
uchar t;
lcdpos(y,0);
for(t=0;t<16;t++)
{
write(1,e[t]);
}
}
void menu1(void)
{
uchar temp,t;
temp=key_scan();
//選擇所要發送的基站號
lcdpos(0,0);
for(t=0;t<16;t++)
{
write(1,a[t]);
}
if(temp==0x0e) //重置機號
{
write(0,0x01);
}
if(temp<=9) //判斷按鍵值是否小於9
{
clr(1);clr(2);
ci=1;
number=temp;
lcdpos(1,0);
write(1,asc[temp]);
}
if(temp==0x0a) //判斷是否羣發按鍵被按下
{
clr(2);
lcdpos(1,0);
for(t=0;t<16;t++)
{
write(1,b[t]);
}
qun=1;
}
if(temp==0x0b) //判斷清除按鍵是否被按下
{
write(0,0x01);
qun=0;
}
if(temp==0x0f) //判斷確定鍵是否被按下
{
if(number>7) //判斷機號是否大於7,否則輸出提示
{
number=0;
lcdpos(2,0);
for(t=0;t<16;t++)
{
write(1,c[t]);
}
ci=0;
}
if((number<=7)&&(ci==1)||(qun==1)) //判斷機號是否小於7,是則轉向menu2
{
menu=2;
write(0,0x01);
ci=0;
}
}
}
void menu2(void)
{
uchar temp,t;
temp=key_scan();
dis();
if(temp==0x0d) //判斷數字字母切換是否被按下
{
if(nl==0)
{
nl=1;
ci=0;
}
else if(nl==1)
{
nl=0;
ci=0;
}
}
if(temp<=9) //判斷按鍵是否爲數字字母
{
if(i<15) //判斷顯示緩存h[]是否滿
{
if(nl==0) //判斷按鍵是否爲爲數字功能
{
if(qq==1)
{i++;di=0;}
h[i]=asc[temp];
i++;
qq=0;
}
if(nl==1) //判斷按鍵是否爲字母功能
{
qq=1;
if(ci==0) //判斷是否爲第一次按鍵
{
let=temp; //暫存按鍵值
ci=1;
h[i]=letter[let][0];
}
if(ci==1) //判斷是否已有按鍵按下過
{
if(let==temp) //判斷本次按鍵值與上次按值是否相等
{
if((di>2)||(letter[let][di]=='0')) // 未確定字母時,使顯示值在本按鍵值之間循環
{ di=0; } //
if((di<=2)&&(letter[let][di]!='0')) //
{ //
h[i]=letter[let][di];
di++;
}
}
if(let!=temp) //判斷本次按鍵與上次按鍵是否不同
{
i++;di=0;
let=temp;
h[i]=letter[let][di];
di++;
}
}
}
}
else
{i=0;}
}
if(temp==0x0c) //判斷髮送鍵是否被按下
{
ps=1;
}
if(temp==0x0b) //判斷清除鍵是否被按下
{
di=0;
let=0;
for(t=0;t<16;t++)
{
h[t]=0x20;
}
i=0;
ci=0;
}
if(temp==0x0e) //判斷重置機號鍵是否被按下
{ menu=1;
write(0,0x01);
lcdpos(1,0);
qun=0;ci=0;i=0;nl=0;
for(t=0;t<16;t++)
{
h[t]=0x20;
}
}
if(temp==0x0f) //判斷字母確定鍵是否被按下
{
if((nl==1)&&(ci==1))//判斷按鍵功能是否爲字母且已有按鍵按下過,及已有字母在LCD上顯示
{
ci=0;
i++;
}
}
}
void init(void) //單片機串口初始化,如果不用和其他芯片通信可以不用
{
menu=1;
TMOD=0X20;
TH1=0XE8;
TL1=0XE8;
PCON=0X00;
TR1=1;
SCON=0X40;
EA=1;
lcdinit();
}
void main()
{
init();
while(1)
{
if(menu==1) //是否爲菜單一
{
menu1();
}
if(menu==0) //是否爲菜單二
{
menu2();
if(ps==1)
{
set();
}
}
}
}