找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1189|回复: 0
打印 上一主题 下一主题
收起左侧

计算器+1602

[复制链接]
跳转到指定楼层
楼主
ID:222532 发表于 2017-7-28 16:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include<stdio.h>
#include<intrins.h>
#define uchar  unsigned char  
#define uint  unsigned int
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^2;
sbit Busy = P0^7;
void delay(uint z)
{
   while(z--);
}
void BusyJiance(void)                 //忙检测
{
  P0 = 0xFF;
  RS = 0;
  RW = 1;
  EN = 1;
  while(Busy);
  EN = 0;
}
void WriteLCD1602Command(uchar com)
{
            BusyJiance();
   
   P0 = com;
   RS = 0;
   RW = 0;
   EN = 1;
   delay(2);
   EN = 0;
}
void WriteLCD1602Dat(uchar dat)
{
      BusyJiance();
   P0 = dat;
   RS = 1;
   RW = 0;   
   EN = 1;
   delay(2);
   EN = 0;
}
void LCD1602_Init(void)
{
  WriteLCD1602Command(0x38);
  WriteLCD1602Command(0x0c);
  WriteLCD1602Command(0x06);
  WriteLCD1602Command(0x01);
  //WriteLCD1602Command(0x08);
}
/*******显示单个字符函数***********/
void LCD_Write_Char(uchar x,uchar y,uchar a)
{   
   if (y == 0)
   {   
       WriteLCD1602Command(0x80 + x);   
   }   
   else
   {   
       WriteLCD1602Command(0xC0 + x);   
   }      
   WriteLCD1602Dat(a);
}
/*******显示字符串函数************/
void DisplayLCD1602(uchar x, uchar y, uchar *p)
{
  if(x == 0)
  {
    WriteLCD1602Command(0x80 + y);
  }
  else
  {
    WriteLCD1602Command(0xc0 + y);
  }
  
  while(*p)
  {
    WriteLCD1602Dat(*p);
    p++;
  }
}
/*按键扫描函数,返回扫描键值*/
uchar KeyScan()  //键盘扫描函数,使用行列反转扫描法
{
    uchar num1;
static uchar key_on =0;
P2=0x0f;
if(P2!=0x0f)
{
    if(key_on==0)
    {
       key_on=1;
    num1=P2;
    num1 |= 0xf0;
    P2=num1;
    num1=P2;
    return(num1);
        }
}
else
{
    key_on=0;
}
    return(0xff);
}
uchar KeyPro()
{
switch(KeyScan())
{
//    case 0x7e:return '+';break;//0 按下相应的键显示相对应的码值
//   case 0x7d:return '-';break;//1
//   case 0x7b:return '*';break;//2
//   case 0x77:return '/';break;//3
//   
//   case 0xbe:return '3';break;//4
//   case 0xbd:return '6';break;//5
//   case 0xbb:return '9';break;//6
//   case 0xb7:return '=';break;//7
//   
//   case 0xde:return '2';break;//8
//   case 0xdd:return '5';break;//9
//   case 0xdb:return '8';break;//a
//   case 0xd7:return '0';break;//b
//  
//   case 0xee:return '1';break;//c
//   case 0xed:return '4';break;//d
//   case 0xeb:return '7';break;//e
//   case 0xe7:return '.';break;//f
//   default:return 0xff;break;
//  
   case 0xe7:return '.';break;//0 按下相应的键显示相对应的码值
   case 0xeb:return '0';break;//1
   case 0xed:return '=';break;//2 .0=/
   case 0xee:return '/';break;//3
   
   case 0xd7:return '7';break;//4
   case 0xdb:return '8';break;//5 789*
   case 0xdd:return '9';break;//6
   case 0xde:return '*';break;//7
   
   case 0xb7:return '4';break;//8
   case 0xbb:return '5';break;//9 456-
   case 0xbd:return '6';break;//a
   case 0xbe:return '-';break;//b
  
   case 0x77:return '1';break;//c
   case 0x7b:return '2';break;//d 123+
   case 0x7d:return '3';break;//e
   case 0x7e:return '+';break;//f
   default:return 0xff;break;

}
}
void main()
{
  unsigned char num,i,sign;                 
  unsigned char temp[16];   //最大输入16个 -
  bit firstflag;       //标志位
  float a=0,b=0;
  unsigned char s;
  LCD1602_Init();    //初始化液晶屏
  WriteLCD1602Command(0x01); //清屏
  while (1)            //主循环
  {
   num=KeyPro();    //扫描键盘
   if(num != 0xff)    //如果扫描是按键有效值则进行处理
   {
      if(i==0)      //输入是第一个字符的时候需要清空,方便观看
      {
         WriteLCD1602Command(0x01);
      }
      if((num=='+')||(num=='-') || (num=='*')|| (num=='/') || (num=='='))//输入符号表示输入结束
         {
            i=0;    //计数器复位
            if(firstflag==0)  //如果是输入的第一个数据,赋值给a,并把标志位 置1,到下一个数据输入时可以跳转赋值给b
            {
                sscanf(temp,"%f",&a);
                firstflag=1;
               }
               else     //把第二个数据赋给 b
      {
                   sscanf(temp,"%f",&b);
      }
               for(s=0;s<16;s++) //赋值完成后把缓冲区清零,防止下次输入影响结果
               temp[s]=0;
               LCD_Write_Char(0,1,num);
               if(num != '=')      //判断当前符号位并做相应处理
               sign=num;         //如果不是等号记下标志位
               else
               {
                   firstflag=0;   //检测到输入=号,判断上次读入的符合
                   switch(sign)
                   {
         case '+':a=a+b;break;
         case '-':a=a-b;break;
         case '*':a=a*b;break;
         case '/':a=a/b;break;
         default:break;
                   }
                   sprintf(temp,"%g",a);    //输出浮点型,无用的0不输出
                   DisplayLCD1602(1,1,temp);//显示到液晶屏
                   sign=0;a=b=0;            //用完后所有数据清零
                   for(s=0;s<16;s++)     //赋值完成后把缓冲区清零,防止下次输入影响结果
                   temp[s]=0;
               }
            }
       else    //输入的是数字并处理
       {
        if(i<=16)
     {
        if( (1==i) && (temp[0]=='0') )//如果第一个字符是0,判读第二个字符(i不自加一)
        {
            if(num=='.')  //如果是小数点则正常输入,光标位置加1
            {
                temp[1]='.';
                LCD_Write_Char(1,0,num);//输出数据
                i++;
            } //这里没有判断连续按小数点,如0.0.0
                     else
                     {
             temp[0]=num;     //如果是1-9数字,说明0没有用,则直接替换第一位0
             LCD_Write_Char(0,0,num);//输出
                     }
                 }
           else
      {
             temp[i]=num;
             LCD_Write_Char(i,0,num);//输出数据(显示)
             i++;        //光标位置加1
       if(i==16)
       {
          i=0;   //防止当按下17下的时候等待
       }
        }
    }
    }
    }
  }
  
   
  
   
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶1 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表