基于51单片机的计算器 C语言程序

发布者:数据舞者最新更新时间:2015-10-28 来源: eefocus关键字:51单片机  计算器  C语言程序 手机看文章 扫描二维码
随时随地手机看文章
 前些日子再博客上转载了一篇计算器的C程序,由于这些日子一直忙于考试,也抽不出时间来重写一下基于C51的计算器,昨晚考完信号处理,回来就着手写,一直弄到凌晨3点多,现面把代码帖出来和大家一起共免,由于时间仓促,代码部分可能还有不足,并且程序只是再我的实验板上调试,如有不足请多多执教,程序时C和汇编混合编程,汇编部分值用到延时的处理,其他代码都用C写的,希望哪为高人能够写出功能更为强大的计算器程序一起分享,对于我的程序,哪位博友增添了更多功能的话,希望发到回复里,以共同进步!
 
程序代码如下:

#include
#define uchar unsigned char
#define uint  unsigned int
bit  NumSem;//前后操作数的互斥信号量
bit  equ;//等号判断
bit  clr;//清零标志
bit  add;//加标志
bit  dec;//减标志
bit  mul;//乘标志
bit  div;//除标志
bit  op;//算术符号标志
uchar  KeyNum;//键值
uint  result;//计算结果
uint  PreNum,LatNum;//计算的两个操作数前操作数,后操作数
uchar  KeyPos;
uchar  DisLed[]={0xC0,0xF9,0xA4,0xB0,0x99,//LED数码七段表
                 0x92,0x82,0xF8,0x80,0x90};
uchar  NumBufe[]={0,0,0,0};
//sbit P10=P1^0;
//sbit P11=P1^1;
//sbit P12=P1^2;
//sbit P13=P1^3;
void  T0Intal(void);//定时器0初始化程序
void DisPlay(void);//显示程序
void ResultNum(void);//计算器运算结果
void Clear(void);//清零程序
void Delay_510(void);//延时510us程序用汇编编写
void ChangeNum(uchar *p,uchar nCount);//NumBufe[]移位程序
void main(void)
{
   T0Intal();
   while(1)
   {
     if(NumSem)
     {
        PreNum=NumBufe[3]*1000+NumBufe[2]*100+NumBufe[1]*10+NumBufe[0];
  NumBufe[4]=0;
     NumSem=0;
     }
  if(op)
  {
    if(PreNum!=0)
    {
       if(NumBufe[4]==0)
    {
     NumSem=1;
    }
          if(equ)
    {
       if(NumBufe[4]!=0)
    {
       LatNum=NumBufe[3]*1000+NumBufe[2]*100+NumBufe[1]*10+NumBufe[0];
    //DisLed[]=0;
    KeyPos=0;
    }
      ResultNum();//计算器结果计算
            //DisPlay();//显示计算结果
    }
   
    }
    else Clear();
 
  }
    if(clr)
 {
   Clear();
    }
 DisPlay();//显示计算结果
   }

}
void  T0Intal(void)
{
   TMOD=0x01;
   TH0=(65536-20000)/256;
   TL0=(65536-20000)%256;
   EA=1;
   ET0=1;
   TR0=1;
}
void DisPlay(void)
{
   //uchar one,two,three,four;
   //one=result/1000;
   P2=DisLed[NumBufe[3]];
   P0=0xFE;
   Delay_510();
   //two=(result-one*1000)/100;
   P2=DisLed[NumBufe[2]];
   P0=0xFD;
   Delay_510();
   //three=(result-one*1000-two*100)/10;
   P2=DisLed[NumBufe[1]];
   P0=0xFB;
   Delay_510();
   //four=(result-one*1000-two*100)%10;
   P2=DisLed[NumBufe[0]];
   P0=0xF7;
   Delay_510();

}
void ResultNum(void)
{
   if(op)
   {
     if(add)
  {
   result=PreNum+LatNum;
  }
     if(dec)
  {
   result=PreNum-LatNum;
  }
  if(mul)
  {
   result=PreNum*LatNum;
  }
  if(div)
  {
   result=PreNum/LatNum;
  }
   }
   //return result;
   //unsigned char
   //uchar one,two,three;
   //one=result/1000;
   NumBufe[3]=result/1000;
   NumBufe[2]=(result-NumBufe[3]*1000)/100;
   //NumBufe[2]=two;
   NumBufe[1]=(result-NumBufe[3]*1000-NumBufe[2]*100)/10;
   //NumBufe[1]=three;
   NumBufe[0]=(result-NumBufe[3]*1000-NumBufe[2]*100)%10;
}
void Clear(void)
{
 // if(Clear)
  //{
     NumBufe[0]=0;
  NumBufe[1]=0;
  NumBufe[2]=0;
  NumBufe[3]=0;
     PreNum=0;
  LatNum=0;
  result=0;
  NumSem=0;
  KeyPos=0;
  clr=0;
  equ=0;
     add=0;
  dec=0;
  mul=0;
  div=0;
  op=0;
 // }
}[page]
void  ChangeNum(uchar *p,uchar nCount)
{
  if(nCount<4)
  {
    uchar ncount;
   ncount=nCount;
   while(ncount>0)
    {
      *(p+nCount)=*(p+nCount-1);
   ncount--;
     }
  }
}
void Delay_510(void)//延时510微秒
{
#pragma asm
 MOV R0,#7DH
 MOV R1,#02H
 TSR1:
 DJNZ R0,TSR1
 MOV R0,#7DH
 DJNZ R1,TSR1
#pragma endasm
}
 
void Time0_Isr_Int(void)  interrupt 1 //定时器0中断服务子程序
{
   TH0=(65536-20000)/256;
   TL0=(65536-20000)%256;
   P1=0xF0;
   if((P1&0xF0)!=0xF0)
   {
      Delay_510();
   if((P1&0xF0)!=0xF0)
   {
      P1=0xFE;
   if((P1&0xF0)==0xE0)//数字键0
   {
      KeyNum=0;
   ChangeNum(NumBufe,KeyPos);
   KeyPos++;
    }
   if((P1&0xF0)==0xD0)
   {
    KeyNum=1;
   ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
      if((P1&0xF0)==0xB0)
   {
     KeyNum=2;
     ChangeNum(NumBufe,KeyPos);
     KeyPos++;
  }
   if((P1&0xF0)==0x70)
   {
    KeyNum=3;
    ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
   P1=0xFD;
   if((P1&0xF0)==0xE0)
   {
    KeyNum=4;
   ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
   if((P1&0xF0)==0xD0)
   {
      KeyNum=5;
      ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
      if((P1&0xF0)==0xB0)
   {
    KeyNum=6;
    ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
   if((P1&0xF0)==0x70)
   {
    KeyNum=7;
    ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
   P1=0xFB;
   if((P1&0xF0)==0xE0)
   {
    KeyNum=8;
    ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
   if((P1&0xF0)==0xD0)
   {
    KeyNum=9;
    ChangeNum(NumBufe,KeyPos);
   KeyPos++;
   }
      if((P1&0xF0)==0xB0)//加法
   {
    op=1;
    add=1;
   }
   if((P1&0xF0)==0x70)
   {
    op=1;
    dec=1;
   }
   P1=0xF7;
   if((P1&0xF0)==0xE0)
   {
    op=1;
    mul=1;
   }
   if((P1&0xF0)==0xD0)
   {
    op=1;
    div=1;
   }
      if((P1&0xF0)==0xB0)//等号
   {
    equ=1;
   }
   if((P1&0xF0)==0x70)//清零
   {
    clr=1;
   }
   }
   }
}


关键字:51单片机  计算器  C语言程序 引用地址:基于51单片机的计算器 C语言程序

上一篇:51单片机P0口使用上拉电阻的作用
下一篇:51单片机呼吸灯

推荐阅读最新更新时间:2024-03-16 14:37

51单片机课程设计:基于DHT11的温湿度报警器
本程序适用于51系列单片机,主要用于读取DHT11温湿度模块数值,显示在数码管上,同时还具备温湿度报警功能,当超出预设值,蜂鸣器报警,可在吉林农业大学单片机开发板上完美运行,其他朋友可以修改部分代码移植的其他型号的开发板上。工程文件以及开发板电路图可到附件下载,同时DHT11部分资料在附件也可以下载。 关于粘贴复制乱码的问题:如果程序复制到Keil编译器上出现注释乱码,可以先建一个.c文件,也就是说不在keil里面编辑,然后用记事本打开.c文件,将源码复制进去,再在keil中添加文件即可。 /************************************说明****************************
[单片机]
51单片机汇编语言实例2
简介:上面的单片机系统和汇编语言控制指令,很容易被更改为多口、多位的单键控制系统。图5为多个LED灯-单个按键的运行结果与汇编语言。图6中对P2.0口改用双掷开关,实现P2.0口的两种电平状态。 a)单个按键与多个LED灯(位操作—输入与字节操作—输出)—判断与子程序 此处只是将输出指令由位指令换成了字节指令,而输入判断仍然是位判断指令。 ORG 0000H MAIN: ;CLR C MOV C,P2.0 ;获取P2.0位状态送位累加器;位与字节转换需要判断指令 JNC ZIJIE;JC位累加器—进位位为1转移到ZIJIE , JNC位累加器为0转移到ZIJIE
[单片机]
<font color='red'>51单片机</font>汇编语言实例2
基于51单片机对电子储物柜系统的设计
电路描述: 安全是我们日常的生活中最关心的问题。 每个人都觉得安全问题是非常至关重要的,在家里的门和安全,可以尽可能多的安全。 为了对于门访问安全 因此,我们打算通过引进一个电子密码锁系统,该系统包括一个人得到一个访问某些项目之前要输入密码的安全性,以及在家里,一个房间密码锁系统,不只是普通的单用户密码锁系统,需要用户插入已编程的代码来访问一个房间; 它是一个密码锁系统,有密码而且可以启用多个用户访问。 在基于51单片机的门储物柜,只允许授权人员进入限制区域的门禁系统。 该系统由8位微控制器AT89C2051具有ROM的2K字节的程序存储器完全控制。 该系统具有通过该密码,可以通过它来输入键盘。 当输入的密码与存储在存储器
[单片机]
基于<font color='red'>51单片机</font>对电子储物柜系统的设计
51单片机程序进行软件加密和硬件解密的方法
 由于固化在片外EPROM 里的单片机程序容易复制,所以,如不在技术上采取保护措施,则程序中所采用的处理方法易被他人分析仿制。对单片机程序进行加密是一种有效的保护措施,也是一项实用的技术。虽然本身带有EPROM 的单片机可做到程序保密,但由于价格和存储容量方面的原因,用户仍常常采用外接EPROM 的单片机来开发产品。 本文以MCS - 51 单片机为例介绍一种对片外E2PROM 里的程序进行软件加密和硬件解密的方法。这种方法不增加用户应用程序开销。 1  基本原理 我们知道,异或运算有这样的特点: A Ý B Ý B =A ,亦即当用变量B 对变量A 作偶数次异或运算后,其结果恢复为变量A。例如A = 32H , B = 5EH ,
[单片机]
<font color='red'>51单片机</font>程序进行软件加密和硬件解密的方法
51单片机学习——8.2--定时计数器
定时计数器原理 CPU时序 振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。 机器周期:1个机器周期含6个状态周期,12个振荡周期。 指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。 例如:外接晶振为12MHz时,51单片机相关周期的具体值为: 振荡周期=1/12us; 状态周期=1/6us; 机器周期=1us; 指令周期=1~4us; 定时计数器介绍 基本特点 51单片机有两组定时器/计数器,因为既可以定时, 又可以计数,故称之为定时器/计数器。 定时器/计数器和单片机的CPU是相互独立的。定时器/
[单片机]
<font color='red'>51单片机</font>学习——8.2--定时计数器
51单片机 汇编语言电子琴
以前写过一个 C 语言的: http://hi.baidu.com/do_sermon/item/c5e55bc1fc2dc30ec710b2f9 应网友要求,再写个汇编的。另外,还增加了显示按键号码的功能。 题目链接:http://zhidao.baidu.com/question/1818901024900190348.html 电路十分简单: P0 外接一个共阳数码管; P1 外接八个独立按键; P3.7 外接扬声器。 汇编语言程序如下: ORG 0000H SJMP START ORG 000BH CPL P3.7 MOV TH0, 30H
[单片机]
基于STC89C51单片机的数字电压表设计
0 引言 数字电压表的设计和开发已有很多类型和款式,传统的数字电压表有自己的特点,它们适合在现场做手工测量,而要完成远程测量并对测量的数据做进一步处理,运用传统的数字电压表是无法完成的。为此,本文设计了基于PC通信的数字电压表,该表既可以完成测量数据的传递,又可借助PC进行测量数据的处理。所以,这种类型的数字电压表无论在功能和实际应用上,都具有传统数字电压表无法比拟的优点,这使得它的开发和应用都具有良好的前景。 1 系统构成 本系统主要由硬件和软件两部分构成,硬件主要包括数据采集电路,单片机最小数据采集系统,单片机与PC机的接口电路等。软件主要有单片机数据采集程序,单片机与上位机通信程序,以及上位机数据处理程序。
[单片机]
80C51单片机程序(1)
//80C51程序 单片机的点亮 #include reg52.h //包含reg52.h头文件 #define uint unsigned int //宏定义uint的数据类型为unsigned int型 sbit D1=P1^2; //定义P1^2位 void main() { uint num=50000; //定义num数据类型,并附初值 D1=0; //点亮发光二极管 while(num--); //延时 } ------------------------------------------------------------------- #inc
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved