用单片机加LCD写的混合四则运算计算器

#include "reg52.h"
#include "stdio.h"
sbit RS=P2^4;
sbit RW=P2^5;
sbit EN=P2^6;
unsigned char code mima[10]="0123456789";
unsigned char sign[7],count=0,Error_flag;//sign是用来标记运算符的,count是用来进行下标计算的
float a[8];//用来记录数据的
unsigned char h,jia,k;//jia,和k是用来记录数据的个数和符号的个数的
void delay(unsigned char m)//延时约1ms
{
  while(--m);
}
void delays(unsigned char t)//延时约1s
{
   while(t--)
   {
      delay(245);
 delay(245);
   }
}
void write_com(unsigned char com)//LCD的写命令
{
  RS=0;
  RW=0;
  EN=1;
  P0=com;
  delays(5);
  EN=0;
}
void write_dat(unsigned char date)//LCD的写一个数据
{
   RS=1;
   RW=0;
   EN=1;
   P0=date;
   delays(5);
   EN=0;
}
void write_string(unsigned char hangshu,unsigned char weizhi,unsigned char *s)//LCD的写字符串的
{
   if(hangshu==1)
   {
     write_com(0x80+weizhi);
while(*s!='\0')
{
  write_dat(*s);
  s++;
}
   }
   if(hangshu==2)
   {
     write_com(0xc0+weizhi);
while(*s!='\0')
{
  write_dat(*s);
  s++;
 }
}
}
unsigned char keyscanf()//键盘扫描(反转法)
{
   unsigned char hang,lie;
   P3=0x0f;
   hang=P3&0x0f;
   if(hang!=0x0f)
   {
      delays(10);
 if((P3&0x0f)!=0x0f)
 {
    hang=P3&0x0f;
P3=hang|0xf0;
lie=P3&0xf0;
while((P3&0xf0)!=0xf0);
return (hang+lie);//必须是行+列,因为行是高四位,列是低四位,所以才是行+列
 }
   }
   return 0xff;
}
void LCD1602inti()//LCD的初始化
{
   write_com(0x38);
   delays(5);
   write_com(0x38);
   delays(5);
   write_com(0x38);
   delays(5);
   write_com(0x38);
   write_com(0x06);
   write_com(0x01);
   write_com(0x08);
   delays(5);
   write_com(0x0c);
}
unsigned char key()//键盘处理
{
  switch(keyscanf())
  {
     case 0x7e:return 1;break;
case 0x7d:return 2;break;
case 0x7b:return 3;break;
case 0x77:return '+';break;
case 0xbe:return 4;break;
case 0xbd:return 5;break;
case 0xbb:return 6;break;
case 0xb7:return '-';break;
case 0xde:return 7;break;
case 0xdd:return 8;break;
case 0xdb:return 9;break;
case 0xd7:return 'x';break;
case 0xee:return 0;break;
case 0xed:return '.';break;
case 0xeb:return '=';break;
case 0xe7:return '/';break;
default :return 0xff;break;
  }

void chengfa()//乘法
{
    a[count+1]=a[count+1]*a[count+2];
if(count+1>=k-1)
   sign[count+1]=0;
else 
    {
   for(h=count+1;h            sign[h]=sign[h+1];
    }
    for(h=count+2;h        a[h]=a[h+1];
    jia--;
    k--;
}
void chufa()//除法
{
    if(a[count+2]==0)
{
Error_flag=1;
}
else
        a[count+1]=a[count+1]/a[count+2];
if(count+1>=k-1)
   sign[count+1]=0;
else
    {
    for(h=count+1;h         sign[h]=sign[h+1];
for(h=k-1;h<10;h++)
    sign[h]=0;
}
    for(h=count+2;h         a[h]=a[h+1];
    k--;
    jia--;
}
void main()
{                                                  //readflag是用来判断是否进行等号的读取
   unsigned char num,i=0,t[6],flag,shu[8],readflag;//num用来接收键盘的值,i用来记录输入的字符,t用来记录字符,flag是记录输入的运算符的个数,shu是用来作为输出的结果
   LCD1602inti();
   while(1)
   {
     num=key();
if(num!=0xff)
{
   if(readflag==1)
{
  readflag=0;
  flag=0;
  write_com(0x01);
}//清零
   if(num=='+'||num=='-'||num=='x'||num=='/'||num=='=')
{
   write_dat(num);
if(i>0)//防止没有数的情况发生
        sscanf(t,"%f",&a[jia++]);//将t的数值转化成float类型
else
   Error_flag=1;//连着两次出现运算符,中间没有数字的情况,报错
if(num!='=')
 sign[k++]=num;//记下此时的符号
for(h=0;h  t[h]=0;//清除缓存
flag++;//flag加一
i=0;//数据从零开始计数
if(flag>=1)
   {
      if(num=='='&&flag==1)//上来就是等号的情况
      {
     write_string(2,0,t);
 k=0;
     flag=0;
     jia=0;//上来就是等号的情况
    readflag=1;i=0;for(h=0;h<10;h++)sign[h]=0;flag=0;
     }
     else if(num=='='&&flag>1)
     {
         
                 while(count<=k-1)
        {
                         switch(sign[count])//这是从前往后找
                {
                     case '+':
                                          if(sign[count+1]!='x'&&sign[count+1]!='/')
                                          {
          a[count+1]+=a[count];
 }
                                           else if(sign[count+1]=='x')
                                           {
                                                    while(sign[count+1]=='x')
                                                        chengfa();
                                                    a[count+1]+=a[count];
                                                    
                                           }
                                           else if(sign[count+1]=='/')
                                           {
                                                    while(sign[count+1]=='/')
                                                         chufa();
                                                    a[count+1]+=a[count];
                                           }
                                           break;
                     case '-':
                                          if(sign[count+1]!='x'&&sign[count+1]!='/')
                                                     a[count+1]=a[count]-a[count+1];
                                          else if(sign[count+1]=='x')
                                          {
                                                    while(sign[count+1]=='x')
                                                    {
                                                           chengfa();
                                                    }
                                                    a[count+1]=a[count]-a[count+1];
                                           }
                                           else if(sign[count+1]=='/')
                                           {
                                                    while(sign[count+1]=='/')
                                                         chufa();
                                                    a[count+1]=a[count]-a[count+1];
                                           }
                                           break;
                     case 'x':
                                           a[count+1]=a[count]*a[count+1];
                                           break;       
                     case '/':
          if(a[count+1]==0)//分母为0的情况
  {
Error_flag=1;
  }
  else 
                                             a[count+1]=a[count]/a[count+1];
                                             break;       
                }
if(Error_flag==1)
   break;
                         count++;
                 }
                 if(Error_flag==0)
{
     sprintf(shu,"%g",a[count]);write_string(2,0,shu);readflag=1;i=0;for(h=0;h<10;h++)sign[h]=0;flag=0;k=0;for(h=0;h<8;h++)a[h]=0;count=0;
}
else
{
     write_string(2,0,"Error!");readflag=1;i=0;for(h=0;h<10;h++)sign[h]=0;flag=0;k=0;for(h=0;h<8;h++)a[h]=0;count=0;Error_flag=0;
}
    }
    
     }
}//加减乘除判断
else
{
 if(num=='.')
 {
   t[i]='.';
write_dat(t[i]);//判读小数点
 }
 else 
 {
   t[i]=mima[num];
   write_dat(mima[num]);//写入数字
 }
 i++;
}
  }
}

}

关于这个计算器,作为小白的我,辛辛苦苦的写了一星期,遇到的困难是在于数组的空间大小没开辟出来,所以在这我建议大家把keil破解完全。

如果有什么不会的可以私聊我。或加qq1034113547

   



你可能感兴趣的:(基础,单片机)