没用延时函数,只用中断的计算器程序

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x00,0x90,0xbf,0xff};//段选
uchar code wei[]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//段选
uchar bb[8],i,j;
uchar code aa[]={
0xfe,0xfd,0xfb,0xf7};//p3口的送值 ,用于矩阵键盘扫描
long int a,b; // 两个二进制数寄存器
uchar enblescan,flag,sign;
long int count(uchar sign,long int a,long int b);//运算函数
long int sum(uchar bb[]); //bb[]数组的求和函数
void showone(long int count); //任意数的显示函数
uchar keyscan();//矩阵键盘扫描函数
uchar keyval(uchar temp);//返回键盘的键值函数
void show(uchar); // 计算器的显示函数
void init();//初始化函数
void main()
{
 init();//初始化
 show(keyval(keyscan()));//显示的初始化
 while(1)  //主函数的大循环
 {
  if(enblescan==1)//有键按下,进行扫描
  {
   show(keyval(keyscan()));//由扫描得到的键得到键值,再将键值显示
   enblescan=2;//扫描屏蔽
  }
  
  }  
}
/***************************************************
初始化程序用于对全局变量的初始化和中断寄存器的初始化
****************************************************/
void init() //初始化函数
{
 enblescan=0;//允许检测是否有键按下
 sign=0;
 flag=0;
 i=0;
 j=0;
 TMOD=0x01;//设置中断模式字
 TH0=(65536-1000)/256;//设置定时中断时间
 TL0=(65536-1000)%256;
 EA=1;//开总中断
 ET0=1;//开t0中断
 TR0=1;//定时中断开始
}
/************************************************
中断程序用于数码管的动态显示和键盘按下与否的检测;
全局变量enblescan用于对键盘扫描函数的控制
************************************************/
display() interrupt 1

 uchar temp;
 TH0=(65536-1000)/256;//中断初值重装
 TL0=(65536-1000)%256;
 if(i==8)  
 i=0;
 P2=wei[i]; //动态扫描显示设位选
 P1=table[bb[i]];//动态扫描显示设段选
    i++;
 if(enblescan==0) //如果允许检测有键按下
 {
  P3=0XF0;
  temp=P3;
  if(temp!=0xf0) //如果有键按下
   j++;
   else j=0;
  if(j==10)
  {
   j=0;
   enblescan=1;//将enblescan设成扫描允许
  } 
 }
 if(enblescan==2) //如果键盘已经扫描完,检测键是否弹起
 {
  P3=0XF0;
  temp=P3;
  if(temp==0xf0) //如果键已经弹起
   j++;
   else j=0;
  if(j==100)
  {
   j=0;
   enblescan=0;//将enblescan设位扫键允许
  }
  }
}
/*************************************
键盘扫描函数用于在enblescan==1的条件下
对键的位置进行确认。
**************************************/
uchar keyscan()//矩阵键盘扫描函数
{
 uchar temp,temp1,k;
 for(k=0;k<4;k++)      
 { 
  P3=aa[k];
  temp1=P3;
  temp1=temp1&0xf0;
  if(temp1!=0xf0)
  {
   enblescan=1;
   temp=P3;
  }
 }
 return temp;
}
/*******************************************
键值函数用于将键盘扫描函数得到键的位置转化我
们想要的键盘值。其中全局变量flag,sign分别用
于显示模式和运算法则的选择。
*******************************************/
uchar keyval(uchar temp)//返回键盘的键值函数
{
 uchar num;
 switch(temp)
 {
  case 0xee:num=7;
  flag++;
      break;
  case 0xde:num=8;
  flag++;
   break;
  case 0xbe:num=9;
  flag++;
    break;
  case 0x7e:sign=4;   //除法
  flag=0;
   break;
  case 0xed:num=4;
  flag++;
   break;
  case 0xdd:num=5;
  flag++;
   break;
  case 0xbd:num=6;
  flag++;
   break;
     case 0x7d:sign=3;  //乘法
  flag=0;
   break;
  case 0xeb:num=1;
  flag++;
   break;
  case 0xdb:num=2;
  flag++;
      break;
  case 0xbb:num=3;
  flag++;
      break;
  case 0x7b:sign=2;//减法
  flag=0;
   break;
  case 0xe7: //清零
  flag=0;
  a=0;
  b=0;
    break;
  case 0xd7:num=0;
  flag++;
   break;
  case 0xb7:flag=9;//等号
      break;
  case 0x77:sign=1; //加法
  flag=0;
   break;
  default:break;       
              
 }
 return num;      
}
/*************************************************
显示函数用于对键入值进行实时显示和对特权键进行处理。
其中,
**************************************************/
void show(uchar temp)
{ uchar k;
 switch(flag)
 {
  case 0: if(sign!=0)//如果是在按了功能键后
     a=sum(bb);//算出bb[]中的值
  bb[7]=0;//只显示一个零
  for(k=0;k<7;k++)
   bb[k]=11;
  break;
  case 1:bb[7]=keyval(temp); //按了一个数字键
  break;
  case 2:bb[6]=bb[7]; //按了两个数字键
  bb[7]=keyval(temp);
  break;
  case 3:bb[5]=bb[6]; //按了三个数字键
  bb[6]=bb[7];
  bb[7]=keyval(temp);
  break;
  case 4:bb[4]=bb[5]; //....
  bb[5]=bb[6];
  bb[6]=bb[7];
  bb[7]=keyval(temp);
  break;
  case 5:bb[3]=bb[4]; //.....
  bb[4]=bb[5];
  bb[5]=bb[6];
  bb[6]=bb[7];
  bb[7]=keyval(temp);
  break;
  case 6:bb[2]=bb[3]; //....
  bb[3]=bb[4];
  bb[4]=bb[5];
  bb[5]=bb[6];
  bb[6]=bb[7];
  bb[7]=keyval(temp);
  break;
  case 7:bb[1]=bb[2]; //按了七个数字键
  bb[2]=bb[3];
  bb[3]=bb[4];
  bb[4]=bb[5];
  bb[5]=bb[6];
  bb[6]=bb[7];
  bb[7]=keyval(temp);
  break;
  case 8: if(flag!=0)//如果按的还是数字键
  flag=7;
  break; 
  case 9:b=sum(bb);//算出bb[]中的值
  showone(count(sign,a,b));//显示最后结果
  break;
  default:break;
 }
}
/***************************************
求和函数用于当按下特殊键时对数组bb[]求和
****************************************/
long int sum(uchar bb[])
{
 long int b;
 uchar k=1;
 while(bb[k]==11) //对前面的空格键清零
 {
  bb[k]=0;
  k++;
 }
 b=bb[7]+bb[6]*10+bb[5]*100+bb[4]*1000+
 bb[3]*10000+bb[2]*100000+bb[1]*1000000;
 return b; 
}
/*************************************************
求值函数用于当按下等号键时对a,b寄存区的数求和
**************************************************/
long int count(uchar sign,long int a,long int b)
{
 switch(sign)
 {
  case 1:a=a+b;
  break;
  case 2:a=a-b;
  break;
  case 3:a=a*b;
  break;
  case 4:a=a/b;
  break;
  default:break;
 }
 return a;
}
/*************************************************
任意数的显示函数用于对任意一个数转化成bcd码
**************************************************/
void showone(long int count)
{
 uchar k=1;
 bb[1]=count/1000000; //转化成bcd码
 bb[2]=count%1000000/100000;
 bb[3]=count%100000/10000;
 bb[4]=count%10000/1000;
 bb[5]=count%1000/100;
 bb[6]=count%100/10;
 bb[7]=count%10;
 while(bb[k]==0) //把数前面的零转换成空格
 {
  bb[k]=11;
  k++;
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值