精华内容
下载资源
问答
  • 简易计算器是一种非常广泛日常工具,对现代社会越来越流行。它可以进行一些简易的计算。本系统提供详细的时、分、秒、年、月、日的时间信息,同时还可进行简易的计算信息,还具有时间校准等功能。该电路采用AT89S52...
  • 单片机为核心的计算器模拟系统设计,输入采用矩阵键盘,可以进行加减乘除等十几种数字运算,同时支持括号的嵌套使用级浮点数的运算,并在上显示操作过程。
  • 包含全套资料原理图、仿真、源程序及论文等
  • 基于51单片机多功能计算器,提供原理图,PCB图,源码。实现普通计算、按键音开关、多种进制之间的转换。
  • 51单片机计算器(包含小数计算) 编写语言:C 运行情况:完美运行,尚未发现bug 备注:同普通实现小数计算程序不一样(浮点型数据计算存在精度丢失的情况),本程序全部采用整形进行计算,对小数点进行记录,最后...
  • 基于51单片机多功能计算器设计_基于51单片机多功能计算器设计_源码
  • 本文档介绍的是基于51单片机设计的运算功能计算器,该电路设计简单,用的洞洞板和5*8矩阵键盘、LCD1602液晶显示器等构成。运算结果均为单精度浮点数。总共有19 钟运算功能加,减,乘,除,平方,开方,N次方,开N...
  • 本程序实现了完整版计算器,包括加减乘除、带小数点显示、带小数点输入、此外还有带时钟功能。当然也可以实现函数功能,只是东西太了,放不开了。。就没有加上。以后在上传吧.带仿真文件的,一定要用Proteus7.8...
  • 基于51单片机计算器设计

    万次阅读 多人点赞 2019-04-22 16:05:21
    能做计算器的单片机 ...它主要由51单片机的数码管,键盘等模块组成。本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程...

    能做计算器的单片机

    单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活的各个领域,电子、科技、通信、汽车、工业等。本次设计是设计一个简易计算器,能够进行多位的加减乘除运算。它主要由51单片机的数码管,键盘等模块组成。本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程,实现计算器的设计。

    把期中做的作业放上来哈哈

    硬件电路描述

    要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。 对于键盘的扫描,这里采用行列扫描的方法来完成对键盘的扫描。原理就是先确定按键在哪一行,接着再确定是哪一列,这样就可以知道是哪个按键被按下了。我是将P3口作为按键扫描口的,比如,先使行线输出全“0”,读列线,再使列线输出全为“0”,读行线。两次结果再相与,则得到一个值为键值。同理,每个按键都会有一个对应的十六进制值,把它们列出来进行一一对应就行了。如下图。
    在这里插入图片描述

    程序设计描述

    1.程序总流程图
    在这里插入图片描述
    2.编程思路
    在单片机接通电源后,单片机就会一直重复检测键盘上的按钮是否被按下。如果有键被按下,就会进入选择判断,当按下数字键,相应数字计入变量keynum中并在数码管上移位显示;当按下运算符键和特殊功能键,也将对应的10到15数字计入到keynum中并进行第二次判断,如果keynum是0~9,则将数据变量dat×10加上keynum;如果是10(加号对应值),进入加法程序(加法标识变量加1,其他运算符标识变量归零,把dat赋值给另一变量datA;当法标识变量大于1时,就是连加,需要将dat等于dat加上datA的值)。其他运算符也是差不多的程序。keynum等于14,就进入等于运算程序。这个程序中也就是四个if语句,如果运算符变量为1就运行相应代码。如加法运算符为1,则使dat加上datA的值赋给dat。最后将dat放入显示程序中显示,而无论何时按下keynum等于15时,所有状态清零。这就是我写的代码的主要思路。

    源代码及注释

    #include <reg51.h>
    #define long unsigned long
    #define KEYPORT P3
    sbit beep=P1^4;
    bit dot;
    typedef unsigned char byte;
    
    long dat;       //数据
    long datA;      //过度数据
    byte addflag;   //加法标志位
    byte subflag;   //减法标志位
    byte mulflag;   //乘法标志位
    byte divflag;   //除法标志位
    byte clrflag;   //数据处理标志位
    byte scanok;
    int checkok;
    int keynum;    //按键键值
    static byte dispbuf[6];
    //数码管字段表
    sbit duan=P2^6;
    sbit wela=P2^7;
    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                            0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    //变量定义
    
    void delayms(int ms)//这个软件大约可以等待ms毫秒
    {
    	  int i,k;
    	  for(k=0; k<ms;k++)	{   for(i=0;i<50;i++);  }
    }
    
    
    /*---------------------------------------------------------------
    查询是否有键按下,有键按下返回键值,无键按下则返回0xff
    ---------------------------------------------------------------*/
    byte keysearch(void)
    {
    	byte k;
     	KEYPORT=0xf0;
     	k=KEYPORT;
     	KEYPORT=0x0f;
     	k=KEYPORT|k;
     	scanok=1;return k;
    }
    void HEX_TO_BCD(int num)
    {	dispbuf[5]  = num%1000000/100000;
        dispbuf[4]  = num%100000/10000;
        dispbuf[3]  = num%10000/1000;
        dispbuf[2]  = num%1000/100;
        dispbuf[1]  = num%100/10;
        dispbuf[0]  = num%10;
    }
    /*---------------------------------------------------------------
    显示子程序
    轮流导通各位数码管,再送出字段码
    延时显示一段时间后再继续导通下一位
    ---------------------------------------------------------------*/
    void scandisp(void)       
    {
    	byte posi=0x1f,i,temp;
    	//posi,为position的缩写,指显示哪一个8字
    	for(i=0;i<6;i++)
     	{
        	temp= dispbuf[i];         //显示缓存区数据查表
        	temp= table[temp];
        	if(i==2&&dot)temp|=0x80;  //i是小数点位置,变量dot=1,点亮小数点
        	P0 = 0;	     duan=1;   duan=0;//先关闭数码管,再切换
        	P0 = posi;   wela=1;   wela=0;  	
        	P0 = temp;   duan=1;   duan=0;
        	delayms(5);//延时 
        	posi>>=1;  posi|=0x20;    //循环右移
     	}
    }
    
    /*---------------------------------------------------------------
    移位显示子程序
    把显示数组中的最低3位赋给高3位,使最新输入的键盘值赋给数组的最低位
    输入:键值
    返回:无
    ---------------------------------------------------------------*/
    void digitin(byte val)               
    { 
    	dispbuf [3]= dispbuf [2];
     	dispbuf [2]= dispbuf [1];
    	dispbuf [1]= dispbuf [0];
     	dispbuf [0]= val;
    }
    
    /*---------------------------------------------------------------
    扫描得到的键值和实际需要的键盘任务的转换函数
    也叫键盘码散转程序
    输入:键值,有0x00~0xff钟可能性,根据显示的键值可以修改此函数
    返回:无
    ---------------------------------------------------------------*/
    void keybranch(byte k)          
    {	if(scanok)
       {scanok=0;
    	switch(k)
     	{
     	    case 0x00:break;
         	case 0xee:keynum=1;break;
         	case 0xde:keynum=2;break;
         	case 0xbe:keynum=3;break;
         	case 0xed:keynum=4;break;
         	case 0xdd:keynum=5;break;
        	case 0xbd:keynum=6;break;
         	case 0xeb:keynum=7;break;
         	case 0xdb:keynum=8;break;
         	case 0xbb:keynum=9;break;
         	case 0xd7:keynum=0;break;
    		case 0x7e:keynum=10;break;//加法
    		case 0x7d:keynum=11;break;//减法
    		case 0x7b:keynum=12;break;//乘法
    		case 0x77:keynum=13;break;//除法
    		case 0xb7:keynum=14;break;//等于
    		case 0xe7:keynum=15;break;//清零
         	default:break;
     	 } checkok=1;
    } }
    /*---------------------------------------------------------------
    处理程序,键值为15时或者清除标志为1时,数据清零
    ---------------------------------------------------------------*/
    void datchuli(void)
    {if(keynum==15)
      {
       dat=0;  datA=0;
       HEX_TO_BCD(dat);
      }
    else if(clrflag)                    //清除标志为1,则执行以下。
      {        
       dat=0;
       clrflag=0;                 //为下次使用准备。
       HEX_TO_BCD(dat);
      }
      if(keynum<10)
      {
      digitin(keynum);
      dat=dat*10+keynum;
      }
    }
    
    void add(void)
    {
       addflag++;                          //加法标志置1。。。
       subflag=mulflag=divflag=0;          //将其它运算标志清零。。(一次只能作一种运算)
       clrflag=1;                          //清零标标置1,(当按下加号后,再按第二个加数时,这时应该显示第二加数。。所以要清掉第一个加数。)
       if(addflag>1)
       {
       dat=datA+dat;
       datA=dat;
       }
       datA=dat;
    }
    void sub(void)						   //减法
    { subflag++;
      addflag=mulflag=divflag=0;
      clrflag=1;
      if(subflag>1)
      {
      dat=datA-dat;
      datA=dat;
      }
      datA=dat;
    }
    void mul(void)							//chengfa
    { mulflag++;
      addflag=subflag=divflag=0;
      clrflag=1;
      if(mulflag>1)
      {
      dat=dat*datA;
      datA=dat;
      }
      datA=dat;
    }
    void div(void)							//chufa
    { divflag++;
      addflag=subflag=mulflag=0;
      clrflag=1;
      if(divflag>1)
      {
      dat=datA/dat;
      datA=dat;
      }
      datA=dat;
    }
    void equ(void)
    {
     
       if(addflag)                           //如果些时做加法运算。。
       {
       dat=dat+datA;                     //计算各存入dat(显示程序会将dat显示的。。)
       }
       if(subflag)
       {
       dat=datA-dat;
       }
       if(mulflag)
       {
       dat=datA*dat;
       }
       if(divflag)
       {
       dat=datA/dat;
       }
       addflag=subflag=mulflag=divflag=0;//运算一次完成后将所有运标志清零。为下次运算作准备。。
       HEX_TO_BCD(dat);	clrflag=1;
    }
    void calculate_handle(void)//计算函数。。
    {	
     if(checkok)//如果检测键值完。则执行以下。
     {
      checkok=0;//检测完标志清零..
      switch (keynum)//如果是+,-,*,/,=则进入相应的函数。。
      {
       case 10 : {add();HEX_TO_BCD(dat);} break;    //如果是按了"+",则进入加法函数。
       case 11 : {sub();HEX_TO_BCD(dat);} break;    //如果是按了"-",则进入减法函数。
       case 12 : {mul();HEX_TO_BCD(dat);} break;    //如果是按了"*",则进入乘法函数。
       case 13 : {div();HEX_TO_BCD(dat);} break;    //如果是按了"/",则进入除法函数。
       case 14 : equ(); break;    //如果是按了"=",则进入等于函数。
       default : datchuli();       //如果不是,计算符(即为数字),则进入数据处理函数。
      }
    
     }}
    /*---------------------------------------------------------------
    主函数:将4X4键盘的键值显示在数码管上
    ---------------------------------------------------------------*/
    void main(void)
    {
    	byte k;
    	while(1)
     	{
     		k=keysearch();
    		
    		if(k!=0xff)   
        {
        	delayms(10);//有键按下
        	k=keysearch();
    		keybranch(k);
      		do
    		{
      			k=keysearch();
    			scandisp();
      		} while(k!=0xff);      //等待键释放
         }
    	 calculate_handle();
    	 scandisp();
      }
    }
    
    

    设计体会

    一开始只是会矩阵键盘和LCD扫描显示,所以当时是想做一个计算器应该还是挺容易的,但直到真正开始做的时候,才发现并不简单。一开始,想的就是,把运算键前输入的数值存到一个变量,后面的数值存到另一个变量内,然后再运算。但问题就来了,如何让单片机知道两次输入的数值要存到不同的变量去?如何把这些变量分别显示到显示管上?然后就要引入更多的变量、设计更多的函数。做出来的第一个版本,能实现加减乘除了,但还有一些问题。按下运算符时,数码管就会直接清零,不像真正计算器那样,按下运算符数码管上数值先不变,等下一数值输入时才变。还有不能实现连续运算的问题,最后还是修改好了。总的来说,这次设计的过程是很有挑战的,尤其对于我这种不善于编程的人来讲,遇到的问题,虽说比较麻烦,但还是车到山前必有路

    展开全文
  • 单片机少不了要做课程设计,分享一个基于单片机设计的计算器,当时是为了课程设计做的,MCU用STC89C51,显示部分用LCD1602,矩阵按键和独立按键输入。 功能有:加减乘除、乘方运算、可输入小数点、可连续运算、结果...
  • 基于51单片机的智能计算器

    千次阅读 2018-09-16 21:53:58
    其实,说智能也不算智能,就是在计算器上加上了日历、时钟和温度显示而已。...2、计算器功能 3、日历及时钟功能 4、温度实时测量 然后用代码依次实现各个功能 刚开始只用矩阵键盘来控制计算器的时候是很简单...

            其实,说智能也不算智能,就是在计算器上加上了日历、时钟和温度显示而已。具体用到的也是51很基础的模块,一个键盘,一个1602,温度显示那块用到了DS18B20,硬件调试的部分也很少,主要是代码的书写。

    功能简介:

    1、打开电源时,显示欢迎字样

    2、计算器功能

    3、日历及时钟功能

    4、温度实时测量

    然后用代码依次实现各个功能

    刚开始只用矩阵键盘来控制计算器的时候是很简单的,定义一个数组,确定每个键盘所对应的符号或数字,然后用列检测法确定按键是否按下,并将其显示在1602上。我设置的键盘包括数字键(0-9)、符号键(+-、*、/),清除键和等号键。

    附上矩阵键盘的电路图:

         

    其中4*4矩阵键盘分别表示

                                                   1,   2,    3,    +,

                                                    4,   5,    6,     -,

                                                    7,   8,    9,     *,

                                                     0=off ,   /,

    最开始只能做整数运算,后来我又定义了浮点型的数据,并且扩宽了加减运算的范围,整个计算器就比较完整了。

    实现计算器的功能后,我开始加上日历及时钟的功能。先给年月日时分秒初始化一个值,并设置最大值,将前两行矩阵键盘作为调节日历及时钟的按键,s1,s2,s3分别用来调节时分秒,s5,s6,s7分别用来调节年月日,按下键后进行相应的加一操作,并使用定时器进行计时,若加到我们设定的最大值时,则置为0,并且令前一位加一。

    紧接着是加上温度显示,我采用的DS18B20模块,工作原理图如下:

    温度分辨率如下:

    利用DS18B20对外界温度进行检测,并将温度以一定的格式显示在1602上。

    最后也是最关键的是设置功能模式的切换,切换键大致如下:

    K1=0时,表示选择时间显示功能

    K2=0时,表示选择温度显示功能

    K3=0时,表示选择计算器功能

    按下相应的切换键即表示选择相应的功能。

     

    展开全文
  • 51单片机设计的多功能计算器

    热门讨论 2010-06-26 00:51:03
    我以前做的一个C语言51单片机计算器,使用两个4*4矩阵键盘,能实现很多功能,当然也包括哪些计算器基础的功能了,protues仿真也有,但是p1口的键功能和上面显示不是一样的,p1口的有开方,阶乘,等等,后面还留有两...
  • 基于51单片机多功能计算器课程设计说明书.doc
  • 基于51单片机的简易计算器制作

    万次阅读 多人点赞 2018-05-08 23:16:13
    51单片机可以实现的功能,今天笔者介绍一种使用4*4矩阵键盘和八位共阴数码制作的简易计算器。数码管使用的是CL3641AH。原理图如下: S15 S11 S7 S3分别是4,5,6,- S14 S10 S6 S2分别是7,8,9,* /* S16 S12...

    基于51单片机的简易计算器制作

    51单片机可以实现的功能很多,今天笔者介绍一种使用4*4矩阵键盘和八位共阴数码制作的简易计算器。数码管使用的是CL3641AH。原理图如下:捕获

    捕获

    S15 S11 S7 S3分别是4,5,6,-
    S14 S10 S6 S2分别是7,8,9,*
    
    /*  S16 S12 S8 S4分别是1,2,3,+
    
    ​```
    S15 S11 S7 S3分别是4,5,6,-
    S14 S10 S6 S2分别是7,8,9,*
    S13 S9 S5 S1分别是0,CLR,=,/
    ​```
    
    */
    
    /* 可以实现两个数运算,每个数至多八位  */
    
    # include<reg52.h>
    
    typedef unsigned char uint8;
    typedef unsigned int uint16;
    
    sbit rw=P2^5;
    sbit rs=P2^6;
    sbit e=P2^7;
    sbit led=P3^7;
    
    sbit beep=P2^0;
    uint8 key,num;
    uint8 fuhao;//定义那个具体的符号是加减还是乘除
    uint8 flag; //定义有没有按下符号按键,这个是统称
    long a,b,c,d;   //定义运算数据的第一个和第二个及等于的数变量
    uint8 k; //定义小数点后面显示的位数
    uint8 biao;
    
    uint8 dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x2a-0x30, 0,0x01-0x30,0x3d-0x30,0x2b-0x30 };//保存显示的数据
    
    void delay(uint16 i)
    {
    
    ​```
    while(i--);
    ​```
    
    }
    void lcdwrc(uint8 c)
    {
    
    ​```
    delay(1000);
    rs=0;
    rw=0;
    e=0;
    P0=c;
    e=1;
    delay(1000);
    e=0;
    ​```
    
    }
    void lcdwrd(uint8 dat)
    {
    
    ​```
    delay(1000);
    rs=1;
    rw=0;
    e=0;
    P0=dat;
    e=1;
    delay(1000);
    e=0;
    rs=0;
    ​```
    
    }
    
    void lcdinit()
    {
    
    ​```
    delay(1500);
    lcdwrc(0x38);
    delay(500);
    lcdwrc(0x38);
    delay(500);
    lcdwrc(0x38);
    delay(500);
    lcdwrc(0x38);
    lcdwrc(0x08);
    lcdwrc(0x01);
    lcdwrc(0x06);
    lcdwrc(0x0c);
    key=0;
    num=0;
    flag=0;
    fuhao=0;
    a=0;
    b=0;
    c=0;
    d=0;
    biao=0;
    led=0;
    ​```
    
    }
    
    void keyscan()
    {
    
    ​```
    P1=0xfe;   //定义第一行为零,然后判断哪一列按下
    if(P1!=0xfe)
    {
        delay(1000);
        if(P1!=0xfe)
        {
            key=P1&0xf0;
            switch(key)
            {
                case 0xe0: num=0;break;   //1
                case 0xd0: num=1;break;   //2
                case 0xb0: num=2;break;   //3
                case 0x70: num=3;break;   //¼Ó
            }
        }
        while(P1!=0xfe);
        if(num==0||num==1||num==2)   //确认第一行的数1,2,3
        {
            if(flag==0)  //没有按下符号建
            {
                //led=1;
                a=a*10+dat1[num];   
            }
            else
            {
                //led=1;
                b=b*10+dat1[num];
            }
    
        }
        if(num==3)
        {
            //led=0;
            flag=1;
            fuhao=1;//加号
        }
        lcdwrd(0x30+dat1[num]);
    }
    ​```
    
    ​```
    P1=0xfd;                //令第二行为零,然后判断第几行按下
    if(P1!=0xfd)
    {
        delay(1000);
        if(P1!=0xfd)
        {
            key=P1&0xf0;
            switch(key)
            {
                case 0xe0: num=4;break;   //4
                case 0xd0: num=5;break;   //5
                case 0xb0: num=6;break;   //6
                case 0x70: num=7;break;   //减-
            }   
        }
        while(P1!=0xfd);
        if(num==4||num==5||num==6)
        {
            if(flag==0)  //没有按下符号建
            {
                //led=1;
                a=a*10+dat1[num];   
            }
            else
            {
                //led=1;
                b=b*10+dat1[num];
            }           
        }
        else
        {
            flag=1;
            fuhao=2;//´代表减号
        }
        lcdwrd(0x30+dat1[num]);
    }
    ​```
    
    ​```
    P1=0xfb;         //令第三行为零,然后判断第几列按下
    if(P1!=0xfb)
    {
        delay(1000);
        if(P1!=0xfb)
        {
            key=P1&0xf0;
            switch(key)
            {
                case 0xe0: num=8;break;   //7
                case 0xd0: num=9;break;   //8
                case 0xb0: num=10;break;  //9
                case 0x70: num=11;break;  //乘*
            }   
        }
        while(P1!=0xfb);
        if(num==8||num==9||num==10)
        {
            if(flag==0)  //没有按下符号键
            {
                //led=1;
                a=a*10+dat1[num];   
            }
            else
            {
                //led=1;
                b=b*10+dat1[num];
            }           
        }
        else
        {
            flag=1;
            fuhao=3;//代表乘号
        }
        lcdwrd(0x30+dat1[num]);
    }
    ​```
    
    ​```
    P1=0xf7;         //另第四行为零,然后判断第几列按下
    if(P1!=0xf7)
    {
        delay(1000);
        if(P1!=0xf7)
        {
            key=P1&0xf0;
            switch(key)
            {
                case 0xe0: num=12;break;  //0
                case 0xd0: num=13;break;  //清楚rst
                case 0xb0: num=14;break;  //等号=
                case 0x70: num=15;break;  //除/
            }   
        }
        while(P1!=0xf7);
        switch(num)
        {
            case 12: 
                    if(flag==0)  //没有按下符号键
                    {
                        //led=1;
                        a=a*10+dat1[num];
                        lcdwrd(0x30);   
                    }
                    else
                    {
                        //led=1;
                        b=b*10+dat1[num];
                        lcdwrd(0x30);
                    }
                    break;
    
            case 13: 
                    lcdwrc(0x01);   //清屏指令      
                    a=0;
                    b=0;
                    flag=0;
                    fuhao=0;
                    break;
    
            case 15:
    
                    flag=1;
                    fuhao=4;
                    lcdwrd(0x2f);//除号/
                    break;
    
            case 14: 
                    if(fuhao==1)//加
                    {
                        lcdwrc(0x4f+0x80);
                        lcdwrc(0x04);//设置光标左移¯,屏幕不移动
                        c=a+b;
                        while(c!=0)  //一位一位显示
                        {
                            lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
                            c=c/10;//取前面的结果数据   
                        }
                        lcdwrd(0x3d); //显示等于号=
                        a=0;
                        b=0;
                        flag=0;
                        fuhao=0;//全部清除为零
                    }
                    if(fuhao==2)   //减
                    {
                        lcdwrc(0x4f+0x80);
                        lcdwrc(0x04);//设置光标左移,屏幕不移动
                        if(a>b)
                            c=a-b;
                        else
                            c=b-a;
    
                        while(c!=0)  //一位一位的显示
                        {
                            lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
                            c=c/10;//取前面的结果数据   
                        }
                        if(a<b) lcdwrd(0x2d); //显示减号-
                        lcdwrd(0x3d); //显示等号=
                        a=0;
                        b=0;
                        flag=0;
                        fuhao=0;//全部清除为零
                    }
    
                    if(fuhao==3)//乘法        
                    {
                        lcdwrc(0x4f+0x80);
                        lcdwrc(0x04);//设置光标左移,屏幕不移动
                        c=a*b;
                        while(c!=0)  //一位一位的显示
                        {
                            lcdwrd(0x30+c%10);//显示结果的位置在0x4f的位置
                            c=c/10;//取前面的结果数据   
                        }
                        lcdwrd(0x3d); //显示等于号=
                        a=0;
                        b=0;
                        flag=0;
                        fuhao=0;//全部清除为零    
                    }
                    if(fuhao==4)
                    {
                        k=0;
                        lcdwrc(0x4f+0x80);
                        lcdwrc(0x04);//设置光标左移,屏幕不移动
                        c=(long)(((float)a/b)*1000);//强制转化为long
                        while(c!=0)  //一位一位的显示
                        {
                            k++;
                            lcdwrd(0x30+c%10);//显示接轨的最后一位在0x4f的位置
                            c=c/10;//取前面的结果数据
                            if(k==3)
                            {
                                lcdwrd(0x2e);
                                k=0;
                            }       
                        }
                        if(a/b<0)     //如果a比b小的话那么除的结果最高位是零
                        {
                            lcdwrd(0x30);   
                        }
                        lcdwrd(0x3d); //显示等号
                        a=0;
                        b=0;
                        flag=0;
                        fuhao=0;//全部清除为零
                    }
                    break;
    
        }
    }
    ​```
    
    }
    
    
    
    void main()
    {
    
    ​```
    lcdinit();
    while(1)
    {
        keyscan();  
    }
    ​```
    
    }
    
    展开全文
  • 硬件设计 (末尾附文件) 工作原理 利用矩阵键盘进行按键的输入,通过对矩阵键盘的扫描,获取用户的输入,并实时的显示在1602液晶上,每次获取到输入时,根据软件设计的相应方法对输入进行处理、运算,输入...reg51.

    硬件设计

    (末尾附文件)

    工作原理
    利用矩阵键盘进行按键的输入,通过对矩阵键盘的扫描,获取用户的输入,并实时的显示在1602液晶上,每次获取到输入时,根据软件设计的相应方法对输入进行处理、运算,输入结束后(以“=“为标志),将最终的运算结果输出的液晶上。

    在这里插入图片描述

    仿真图1: (LCD1602显示,支持负数和进制运算及有限的连续运算,连续运算时候无法识别优先级,不支持小数;)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    仿真图2: LCD1602显示,支持负数和小数及开根号,不支持连续运算;

    在这里插入图片描述
    在这里插入图片描述

    程序设计1

    #include <reg51.h>
    #include <stdio.h>
    #include <intrins.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    
    
    #define u8  unsigned char
    #define u16  unsigned char
    sbit LCDEN=P3^4;
    sbit RS=P3^5;
    sbit RW=P3^6;
    sbit BF=P0^7; 
    sbit change_m=P3^7;
    
    u8 code keyval[]="789/456*123-c0=+"; //按键对应的符号 
    u8 data1[10];
    u8 k=0;
    char  m[8]={0};
    double sum=0;
    int flag;
    void WrDatLCD(unsigned char DatVal);
    void WrComLCD(unsigned char ComVal);
    void delay(u16 x)	  //延时x毫秒
    {
    u16 i,j;
    for(i=0;i<x;i++)
    	for(j=0;j<115;j++)
    		;
    }
    int convertBinaryToDecimal(long n)
    {
    	int decimalNumber = 0, i = 0, remainder;
    	while (n != 0)
    	{
    		remainder = n % 10;
    		n /= 10;
    		decimalNumber += remainder * pow(2, i);
    		++i;
    	}
    	return decimalNumber;
    }
    
    int convertBinaryToDecimal8(long n)
    {
    	int decimalNumber = 0, i = 0, remainder;
    	while (n != 0)
    	{
    		remainder = n % 10;
    		n /= 10;
    		decimalNumber += remainder * pow(8, i);
    		++i;
    	}
    	return decimalNumber;
    }
    
    
    
    
    
    u8 keypad4_4()//按键扫描函数:要去抖,若有按键按下,返回对应的按键值(0-15),没有按键按下返回16
    {
    u8 i,row,temp;
    u8 key=16;//按键号,初值设置为16,目的是:没有按键按下时返回16;
              //若不设初值(默认值为0),没有按键按下时,将返回0,会误认为0被按下  
    row=0xef; //从第一列开始      
    for(i=0;i<4;i++)
    {
    	P1=0xff;  
    	P1=row;	//第i列信号,对应列为低,其他全为高
    	row=_crol_(row,1); 	  //生成下一列信号
    	temp=P1; //读入扫描信号
    	temp=temp&0x0f; //屏蔽高4位列信号,只保留低4位行信号 
    	if(temp!=0x0f)//有按键被按下,因为第i列某行有按键按下,则低4位中有一位为低  
     	{  
    		delay(20);  //延时去抖
    		temp=P1;  
    		temp=temp&0x0f;  
    		if(temp!=0x0f)   //再次确认有按键被按下
      		{  
            	switch(temp)  //根据低4位行信号,判断哪个按键被按下
                {  
                	case 0x0e:key=0+i;break; //第i列第1行按键被按下 
                    case 0x0d:key=4+i;break; //第i列第2行按键被按下  
                    case 0x0b:key=8+i;break; //第i列第3行按键被按下
    				case 0x07:key=12+i;      //第i列第4行按键被按下 
                }
    			
    			do
    			{
    				temp=P1;  	    //再次扫描按键
      				temp=temp&0x0f;  
      			}while(temp!=0x0f); //等待按键释放   
      		}  
         }
    	
    	
    		 if(change_m == 0)
    		 {
    			 delay(50);
    			 if(change_m == 0)
    			 {
    				 flag++;
    				 if(flag == 3)
    				 {
    					 flag = 0;
    				 }
    			 } while(!change_m);
    		 }
    
    
    
    		 
    }  
    return(key);//扫面结束,返回按键值
    }
    
    unsigned char DectectBusyBit(void)//状态判断函数(忙/闲?)
    {   
    	bit result;
    	P0 = 0xff;	//读状态前先置高电平,防止误判
    	RS = 0;
    	delay(5);
        RW = 1;
    	LCDEN = 1;
    	delay(5);
    	result=BF; //若LCM忙,则反复测试,在此处原地踏步;当LCM闲时,才往下继续
    	LCDEN = 0;
    	return result;		      
    }
    
    void WrComLCD(unsigned char ComVal)//写命令函数
    {
    	while(DectectBusyBit()==1);         //先检测LCM是否空闲
    	RS = 0;
    	delay(1);
        RW = 0;
    	LCDEN = 1;
    	P0 = ComVal;
    	delay(1);
    	LCDEN = 0;	
    }
    
    void WrDatLCD(unsigned char DatVal)//写数据函数
    {
    while(DectectBusyBit()==1); 
    	RS = 1;
    	delay(1);
        RW = 0;
    	LCDEN = 1;
    	P0 = DatVal;
    	delay(1);
    	LCDEN = 0;	
    }
    
    void LCD_Init(void)//1602初始化函数
    { 
    	WrComLCD(0x38);     // 功能设定:16*2行、5*7点阵、8位数据接口
    	WrComLCD(0x38);
    	WrComLCD(0x38);    
    //多次重复设定功能指令,因为LCD启动后并不知道使用的是4位数据接口还是8位的,所以开始时总是默认为4位
    	WrComLCD(0x01);    // 清屏 
    	WrComLCD(0x06);    // 光标自增、屏幕不动  
    	delay(1);	      // 延时,等待上面的指令生效,下面再显示,防止出现乱码
    	WrComLCD(0x0c);    // 开显示
    }
    			 
    void compute(){
    	u8 i,j=0,k,n=0;
    	char data3[3]={0};
    	int sum1,data2[4]={0};
    	int a,b,c,d,o;
    	int getValue[6]={0};
    	sum=0;
    
    	for(i=0;data1[i]!='\0';i++){
    		  if(data1[i]!='+' && data1[i]!='-' && data1[i]!='*' && data1[i]!='/'){
    		  	data2[j] =data2[j]*10+(data1[i]-'0');
    
    		  }
    		  else{
    		  	data3[n++] = data1[i];
    		  	j++;
    		  } 
    	}
    	a=data2[0];
    	b=data2[1];
    	c=data2[2];
    	d=data2[3];
    	if(flag == 1)  //如果二进制
    	{
    	a=convertBinaryToDecimal(a);
    	b=convertBinaryToDecimal(b);
    	c=convertBinaryToDecimal(c);
    	d=convertBinaryToDecimal(d);
    	}
    	if(flag == 2)  //如果8进制
    	{
    	a=convertBinaryToDecimal8(a);
    	b=convertBinaryToDecimal8(b);
    	c=convertBinaryToDecimal8(c);
    	d=convertBinaryToDecimal8(d);
    	}
    
    	
    	for(i=0;i<n;i++){
    		if(i==0){
    			if(data3[0]=='+')  sum = a + b;
    			if(data3[0]=='-')  sum = a - b;
    			if(data3[0]=='*')  sum = a * b;
    			if(data3[0]=='/')  sum = a / (double)b; 
    		}
    		if(i==1){
    			if(data3[1]=='+')  sum = sum+c;
    			if(data3[1]=='-')  sum = sum-c;
    			if(data3[1]=='*')  sum = sum*c;
    			if(data3[1]=='/')  sum = sum/((float)c); 
    		}
    		if(i==2){
    			if(data3[2]=='+')  sum = sum+d;
    			if(data3[2]=='-')  sum = sum-d;
    			if(data3[2]=='*')  sum = sum*d;
    			if(data3[2]=='/')  sum = sum/((float)d); 
    		}
    
    	
    	}
    

    .

    文件仅供参考:

    链接:https://pan.baidu.com/s/1ZAxAbTe_oD_cuTvvKWxU5A
    提取码:x102

    .

    展开全文
  • 51单片机设计计算器

    2015-04-04 10:57:08
    可以通过键盘输入,并能显示输入相对应的数字,能够进行加、减、乘、除准确的基本运算的计算器
  • 基于51单片机的简易电子计算器——有温度显示和万年历等额外功能 设计实际所实现的功能 模式一可显示日期、时钟、温度,模式二可进行计算器的计算,且显示日期温度模式和计算器模式可随意切换,模式三可以滚动显示...
  • C语言51单片机之简易计算器

    千次阅读 2019-01-30 15:17:41
    名称:液晶显示计算器 内容:整数之间运算,没有小数所有除法得出的结果不正确,有负号运算, ------------------------------------------------*/ #include&lt;reg52.h&gt; //包含头文件,一般情况不...
  • 基于51系列单片机89C58的多功能计算器软件,以AT89C58单片机为核心,外接一个4*4按键、LCD显示1602模块等,构成一个的单片机系统。
  • 三、编程实现 1、主函数部分: #include #include "LCD1602.h" #include "MatrixKey.h" /*********************************************** 51单片机大作业 —— 基于AT89C51的简易计算器 作者:智能医学工程2002班...
  • 基于单片机的智能计算器(AT89C51、LCD1602、矩阵键盘) 一、简介 此电路由AT89C51最小系统、LCD1602液晶显示模块和矩阵键盘模块组成。 二、执行效果 三、代码 /* S16 S12 S8 S4分别是123+ S15 S11 S7 S3分别是456...
  • 基于51单片机的矩阵计算器设计

    千次阅读 2018-03-16 08:36:47
    当初本科的毕业设计不是很完美,一直想把它完善一下,这学期刚开始有点时间,就以一个小项目的...Ø 为了生成单片机可执行文件,选择使用了Ubuntu系统下的sdcc编译器,安装使用都很简单(想在Ubuntu下进行编程)...
  • 之前讲的计算器都是基于C语言的,接下来讲一下基于汇编语言的简易计算器。 硬件设计 (末尾附文件) 显示器仍然是数码管,MCU是C51,支持整数部分的计算 仿真图: 程序设计 YJ EQU 50H ;结果存放 YJ1 EQU 51H ;中间...
  • 这是一款基于89C51单片机的智能计算器程序,使用的语言是C语言
  • ---- 常用的加法计算器功能。有连加功能。 ---- 本程序有2个窗口。 ---- 第1个窗口:原始数据和运算结果窗口。 比如加法运算中的被加数 ---- 第2个窗口:第二个参与运行的数据窗口。比如加法运算中的加数 ---- ...
  • 51单片机设计的多功能计算器 ,设计比较完整;可以做为毕业设计论文参考。
  • 这是个51单片机的小程序,是我接触单片机之初的一个小练习。 首先感谢学社的学长学姐指导,再感谢我自己...这个非常重要,51单片机好像并不能完成线程任务,有些事情用外部中断或计时器中断会大大提高效率。 先...
  • 标签:51单片机、LCD1602 资料预览 效果图: 总体资料: 原理图: 软件设计流程: 系统框图: 本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成计算器的整个系统,其中包含中控...
  • 今天是51单片机模块! 事实上,也是离不开C语言编程啦 适合手头上有51单片机且对硬件有兴趣的小伙伴们 这里推荐初学者(我自己就是哈哈哈)购买天祥电子51单片机开发板(TX-1C) 话不说,上代码: #include<reg52...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 544
精华内容 217
关键字:

51单片机多功能计算器