參考了宋雪松老師的教學例程 ,源程序只能計算加法 ,本程序稍作修改后 可進行加法和減法計算
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共陰字形碼
uchar code keycodemap[4][4]={
{ 0x31, 0x32, 0x33, 0x26 }, //數字鍵1、數字鍵2、數字鍵3、向上鍵
{ 0x34, 0x35, 0x36, 0x25 }, //數字鍵4、數字鍵5、數字鍵6、向左鍵
{ 0x37, 0x38, 0x39, 0x28 }, //數字鍵7、數字鍵8、數字鍵9、向下鍵
{ 0x30, 0x1B, 0x0D, 0x27 }}; //數字鍵0、ESC鍵、 回車鍵、 向右鍵};
uchar keysta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}; //全局變量 記錄四個鍵的狀態 0按下 1彈起 當keysta反正變化時 說有按鍵動作 1變0 按下 0變1 彈起
uchar Ledbuf[6]={0X3F,0X00,0X00,0X00,0X00,0X00}; //數碼管顯示緩沖區,第0位為最低位(個位) ,第5位為符號位
long result=0;
long adden=0;
sbit keyin0=P1^0;
sbit keyin1=P1^1;
sbit keyin2=P1^2;
sbit keyin3=P1^3;
sbit keyout0=P1^4;
sbit keyout1=P1^5;
sbit keyout2=P1^6;
sbit keyout3=P1^7;
void InitTimer1(void) //定時1ms
{
TMOD = 0x10;
TH1 = 0xFC;
TL1 = 0x18;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void shownumber(long num)
{
static uchar buf[5]={0,0,0,0,0};
char i;
if(num<0) //負數為補碼 取反加1得到原碼
{ num=~num;
num++;
Ledbuf[5]=0x40;
}
else
{
Ledbuf[5]=0x00;
}
for(i=0;i<5;i++)
{buf[ i]=num%10;
num=num/10; }
for (i=4; i>=1; i--) //從最高位起,遇到0轉換為空格,遇到非0則退出循環
{
if (buf[ i] == 0)
Ledbuf[ i] = 0x00;
else
break;
}
for( ;i>=0;i--)
{Ledbuf[ i]=table[buf[ i]];}
}
void keyaction(uchar keycode)
{
long temp;
static uchar yunsuanfuhao=0;
if((keycode>=0x30)&&(keycode<=0x39)) //按下數字鍵
{
temp=adden;
adden=(adden<<3)+(adden<<1)+keycode-0x30;
if(adden>99999) adden=temp;
shownumber(adden);
}
else if(keycode==0x26) //加號鍵
{
yunsuanfuhao=1;
result=result+adden;
adden=0;
shownumber(adden);
}
else if(keycode==0x25) //減號鍵
{
yunsuanfuhao=2;
result=result+adden;
adden=0;
shownumber(adden);
}
else if(keycode==0x0d) // 等號鍵
{
if(yunsuanfuhao==1) //加法
{ result=result+adden;
adden=0;
}
else if(yunsuanfuhao==2) //減法
{ result=result-adden;
adden=0;
}
shownumber(result);
// result=0;
}
else if (keycode==0x1b) //清零鍵
{
result=0;
adden=0;
shownumber(result);
}
}
void keydriver()
{
uchar i,j; //i行 j列
static uchar backup[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if((backup[ i][j])!=(keysta[ i][j]))
{
backup[ i][j]=keysta[ i][j] ;
if(keysta[ i][j]==1)
{
keyaction(keycodemap[ i][j]);
}
}
}
}
}
void keyscan()
{
static uchar buf[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
static uchar hang=0;
uchar i;
buf[hang][0]=((buf[hang][0])<<1)|((uchar) keyin0); //按行進行按鍵值的讀取 讀該行共4個鍵的鍵值 進入buf[hang][0-3]
buf[hang][1]=((buf[hang][1])<<1)|((uchar) keyin1);
buf[hang][2]=((buf[hang][2])<<1)|((uchar) keyin2);
buf[hang][3]=((buf[hang][3])<<1)|((uchar) keyin3);
for(i=0;i<4;i++) //判斷該按鍵是否按下 即keysta是否為0 經16ms后讀取buf[hang][0-3]的低4位值 觀察是否為0X0F 或0X00
{
if (((buf[hang][ i])&0x0f )== 0x0f) keysta[hang][ i]=1;
else if (((buf[hang][ i])&0x0f )== 0x00) keysta[hang][ i]=0;
}
hang++;
if(hang>=4) hang=0;
switch(hang) //按行掃描,選取第i行,該行線輸出低電平
{
case 0:keyout3=1;keyout0=0;break; // P1=0B1110 1111;
case 1:keyout0=1;keyout1=0;break; // P1=0b1101 1111;
case 2:keyout1=1;keyout2=0;break;//P1=0b1011 1111;
case 3:keyout2=1;keyout3=0;break;//P1=0b0111 1111;
default: break;
}
}
void ledscan()
{
static uchar i=0;
P2=~(0X01<<i);
P0=Ledbuf[5-i];
i++;
if(i>=6) i=0;
}
void main()
{
InitTimer1();
while(1)
{
keydriver();
}
}
void timer1(void) interrupt 3
{
TH1 = 0xFC;
TL1 = 0x18;
keyscan();
ledscan();
}
|