谁有简易计算器利用单片机制作的,LED数码管显示的。

我做的是单片机实验,利用单片机实现简易的计算器,LED八位数码管显示,用汇编语言实现。谢谢高手帮忙啊~!我用的单片机是AT89S52。

第1个回答  2011-01-05

#include<reg51.H>

//#include<stdio.h>

#define LEDS 8

/***按键程序***/

char keyscan();

 

/***显示程序***/ 

void display();

char dsp[9]={0,0,12,12,12,12,12,12,12}; //初始化显示数组

/***计算程序***/ 

void calculate(char k,char c1[8],char c2[8]);

 

/***片选***/

unsigned char code Select[]=

{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

/***码选***/ 

unsigned char code LED_CODES[]=    

{0xC0,0xF9,0xA4,0xB0,0x99, //0-4

0x92,0x82,0xF8,0x80,0x90, //5-9

0x86,0xAF,0xFF,0x7F,0xBF,}; //E,r,空格,.,-

/***main函数***/

void main(void)

{

char i,j,k,c;

char a[8],b[8];

/***定时1ms***/

TMOD=0;

TL0=-(1000/256);

TH0=-(1000%256);

EA = 1; //总中断开关

ET0 = 1; //开中断

TR0 = 1; //启用计数器0

KSC:do

 {

 for(i=1;i<9;i++) //数字录入循环

  {

  dsp[0]=keyscan();

  if(c==2&&dsp[0]<10)  //此段代码验证是否有旧的计算结果在显示,且不再参与新计算

   {

   dsp[1]=dsp[0];

   for(j=2;j<9;j++)

   dsp[j]=12;

   c=0;

   }

  else if(c==2&&dsp[0]>9)  //旧的计算结果将参与新的计算,作为第一个数

   {

   c=0;

   }

    

  if(dsp[0]==0&&dsp[1]==0&&dsp[2]==12) //个位为0且十位为空时按下0,按键无效,跳回KSC等待正确输入

   {

   /***goto跳转标志***/ 

   goto KSC;

   }

  else if(dsp[0]>9) break; //有操作符按下,跳出数字录入循环  

   else

   {for(j=i;j>0;j--)

   dsp[j]=dsp[j-1]; //移位,以正确显示数字

   }   

  } 

 

 if(i==9) //判断是否输入8个有效数字,是则等待操作符,否则直接判断操作符

  {

  do //使用do while无论是否第一个数都取一次操作符

   {

   dsp[0]=keyscan(); //获取操作符号

   if(dsp[0]==14||dsp[0]<10) //按下C或者第9位数字清零

    {

    dsp[1]=0;

    for(i=2;i<9;i++)

    dsp[i]=12;

    c=0;

    }

   }while((dsp[0]==15)&&(c==0));  //等号被按下,等待新的操作符(仅对第一个数字有效)

  }

 else if(dsp[0]==14) //按下C清零

  {

  dsp[1]=0;

  for(i=2;i<9;i++)

  dsp[i]=12;

  c=0;

  }

  while(dsp[0]==15&&c==0)  //未输满8位且是第一个数字即按下等号,等待非等号操作符

  {

  dsp[0]=keyscan(); //获取操作符号

  if(dsp[0]==14||dsp[0]<10) //按下C或者数字都进行清零,重新输入a

   {

   dsp[0]=14; //将dsp[0]置为14,防止因数字清零未能拦截

   dsp[1]=0;

   for(i=2;i<9;i++)

   dsp[i]=12;

   c=0;

   }  

  }

 }while(dsp[0]==14);  //数字输入未完成即按下C,重新等待输入

 do

 {

  if(c==0) //没有数字输入

  {  

  k=dsp[0]; //存计算符(循环内已排除C、=、数字)

  for(i=0;i<8;i++) //将第一个数存入a[8]

   {

   a[i]=dsp[i+1];

   }

   

  dsp[1]=0; //清零

  for(i=2;i<9;i++)

  dsp[i]=12;

  

  c=1; //已输入a

  /***goto跳转标志***/

  goto KSC;

  }

 else if(c==1)

  {  

  for(i=0;i<8;i++) //将第二个数存入b[8]

   {

   b[i]=dsp[i+1];

   }

   c=2; //已输入b

 

  if(dsp[0]!=15) //b输完后操作符不是等号

   {

   calculate(k,a,b);

   for(i=0;i<8;i++) //将计算结果存入a[8],a值更新

    {

    a[i]=dsp[i+1];

    }

   k=dsp[0]; //更新计算符

   c=1;

   /***goto跳转标志***/

   goto KSC;

   }

  }

 }while((dsp[0]==15)&&(c<2)); //直到ab输入完成且按下等号

calculate(k,a,b); //进行最后计算

/***goto跳转标志***/

goto KSC; //跳回KSC,等待新一轮计算

while(1); //防止程序跑飞

}

char keyscan()

{

char KeyL;

char KeyR;

char j;

do

 {

 do

  {

  P3=0xF0;

  P3=P3|0xF0;//行扫描11110000  

  if(P3!=0xF0)

   {

   KeyL=P3;

   P3=0x0F;

   P3=P3|0x0F;//列扫描00001111

   KeyR=P3;

   }

  }while(KeyL==0xF0||KeyR==0x0F);

  for(j=0;j<12;j++)  //延时0.001s=1ms

  {;}

 }while(P3!=0x0F); 

switch(KeyL&KeyR)

 {

 case 0x28:{return 0;break;}

 case 0x11:{return 1;break;}

 case 0x21:{return 2;break;}

 case 0x41:{return 3;break;}

 case 0x12:{return 4;break;}

 case 0x22:{return 5;break;}

 case 0x42:{return 6;break;}

 case 0x14:{return 7;break;}

 case 0x24:{return 8;break;}

 case 0x44:{return 9;break;}

 case 0x81:{return 10;break;}//加法(第一行,第四列)

 case 0x82:{return 11;break;}//减法(第二行,第四列)

 case 0x84:{return 12;break;}//乘法(第三行,第四列)

 case 0x88:{return 13;break;}//除法(第四行,第四列)

 case 0x18:{return 14;break;}//清零(第四行,第一列)

 case 0x48:{return 15;break;}//计算结果(第四行,第三列)

 }

}

void display() interrupt 1 using 1 //利用定时器中断实现间时显示  

{

char i,j,h;

ET0=0;

for(j=8;j>0;j--) //扫描8次

 {

 for(i=7;i>=0;i--) //从高位到低位扫描显示

  {

  P2=0;

  P1=LED_CODES[dsp[8-i]];

  P2=Select[i];

  for(h=0;h<8;h++)

  {;}

  }

 }

TL0=-(1000/256);

TH0=-(1000%256);

ET0=1; 

}

void calculate(char k,char a[8],char b[8])

{

char r[8];

long i,x,y;

i=0;

x=0;

y=0;

for(i=7;i>0;i--) //数值转化,将代表空格的12转化为数字0,因为个位不显示空格,默认为0,所以不转化

 {

 while(a[i]==12)a[i]=0;

 while(b[i]==12)b[i]=0;

 }

x=a[4];

x=10000*x;

x=x+a[0]+a[1]*10+a[2]*100+a[3]*1000+a[5]*100000+a[6]*1000000+a[7]*10000000;

y=b[4];

y=10000*y;

y=y+b[0]+b[1]*10+b[2]*100+b[3]*1000+b[5]*100000+b[6]*1000000+b[7]*10000000;

if(k==10)//加法运算

 {

 x=x+y;

 if(x>99999999) //大于8位,显示“Err”

  {

  r[0]=11; //r

  r[1]=11; //r

  r[2]=10; //E

  r[3]=12; //空格

  r[4]=12;

  r[5]=12;

  r[6]=12;

  r[7]=12;

  }

 else

  {

  r[0]=x%10;

  r[1]=(x%100)/10;

  r[2]=(x%1000)/100; 

  r[3]=(x%10000)/1000;

  r[4]=(x%100000)/10000;

  r[5]=(x%1000000)/100000;

  r[6]=(x%10000000)/1000000;

  r[7]=x/10000000;

  }

 }

if(k==11)//减法运算

 {  

 if(x<y)

  {

  x=y-x;

  if(x>9999999)

   {

   r[0]=11; //r

   r[1]=11; //r

   r[2]=10; //E

   r[3]=12; //空格

   r[4]=12;

   r[5]=12;

   r[6]=12;

   r[7]=12;

   }

  else

   {

   r[0]=x%10;

   r[1]=(x%100)/10;

   r[2]=(x%1000)/100; 

   r[3]=(x%10000)/1000;

   r[4]=(x%100000)/10000;

   r[5]=(x%1000000)/100000;

   r[6]=(x%10000000)/1000000;

   r[7]=x/10000000;

   

   for(i=7;i>0;i--) //将有效数字的高一位转化为-号

    {

    if(r[i]==0&&r[i-1]!=0)

     {

     r[i]=14;

     break;

     }

    }

   }

  }

 else

  {

  x=x-y;

  r[0]=x%10;

  r[1]=(x%100)/10;

  r[2]=(x%1000)/100; 

  r[3]=(x%10000)/1000;

  r[4]=(x%100000)/10000;

  r[5]=(x%1000000)/100000;

  r[6]=(x%10000000)/1000000;

  r[7]=x/10000000;

  } 

 }

if(k==12)//乘法运算

 {

 i=x;

 x=x*y;

 if(y==0)

  {

  x=0;

  }

 else if(x>99999999||x<i) //积大于99999999或者小于乘数都认为是异常,存在其他可能的溢出,须自行辨别

  {

  r[0]=11; //r

  r[1]=11; //r

  r[2]=10; //E

  r[3]=12; //空格

  r[4]=12;

  r[5]=12;

  r[6]=12;

  r[7]=12;

  }

 else

  {

  r[0]=x%10;

  r[1]=(x%100)/10;

  r[2]=(x%1000)/100; 

  r[3]=(x%10000)/1000;

  r[4]=(x%100000)/10000;

  r[5]=(x%1000000)/100000;

  r[6]=(x%10000000)/1000000;

  r[7]=x/10000000;

  }

 }

if(k==13)//除法运算

 { 

 if(y==0) //被除数不能为0

  {

  r[0]=11; //r

  r[1]=11; //r

  r[2]=10; //E

  r[3]=12; //空格

  r[4]=12;

  r[5]=12;

  r[6]=12;

  r[7]=12;

  }

 else

  {

  x=x/y;

  r[0]=x%10;

  r[1]=(x%100)/10;

  r[2]=(x%1000)/100; 

  r[3]=(x%10000)/1000;

  r[4]=(x%100000)/10000;

  r[5]=(x%1000000)/100000;

  r[6]=(x%10000000)/1000000;

  r[7]=x/10000000;

  }

 }

for(i=7;i>0;i--) //数值转化,将高位的无效数字0转化为空格符12

 {

 if(r[i]==0)

  r[i]=12;

   else 

    break;

 }

for(i=0;i<8;i++) //将计算结果存入dsp[9],显示数更新

 {

 dsp[i+1]=r[i];

 }

}

本回答被提问者和网友采纳
第2个回答  2011-01-09
我也在想用矩阵键盘做个简易计算器呢,对初学者来说有点难啊。
第3个回答  2011-01-04
我觉得最好找一下c语言的计算器,然后呢,自己去翻译。
相似回答