51单片机 计算器_51单片机定时器频率计算器 - CSDN
  • 基于51单片机的简易计算器

    千次阅读 2018-05-01 15:05:13
    //S4:+ S8:- S12:* S16:/ S15: = S13: REMOVE//#include&...reg51.h>#define DIG P0#define KEY P1sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;unsigned long int count=0,sum=1;int a[11]={0x3f,0...
    

    //S4:+    S8:-   S12:*   S16:/   S15: =   S13:  REMOVE

    //

    #include<reg51.h>
    #define DIG P0
    #define KEY P1
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    unsigned long int count=0,sum=1;
    int a[11]={
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x00};
    unsigned  char KeyDate;
    unsigned char symbol;
    void delay();  
    void KeyDown();  
    void DigDisplay();
    void conversion();
    void DigDisplayNumble();
    void main(void)
    {
     while(1)
     {
      KeyDown();
     // conversion();//
      DigDisplay();
     }    
    }
    void KeyDown()//
    {
     KEY=0x0f;
     if(KEY!=0x0f)
     {
      delay();
      if(KEY!=0x0f)
      { 
       KEY=0X0F;
       switch(KEY)
       {
        case(0X07): KeyDate=1;break;
        case(0X0b): KeyDate=2;break;
        case(0X0d): KeyDate=3;break;
        case(0X0e): KeyDate=4;break;
       }  
       KEY=0XF0;
       switch(KEY)
       {
        case(0X70): KeyDate=KeyDate;break;
        case(0Xb0): KeyDate=KeyDate+4;break;
        case(0Xd0): KeyDate=KeyDate+8;break;
        case(0Xe0): KeyDate=KeyDate+12;break;
       }
       while(KEY!=0xf0) ;
        delay();
       conversion();//
      }
     }
    }
    void DigDisplay()
    {
     unsigned int j,p=0; 
     for(j=0;j<8;j++)
     {
      switch(j)
      {
       case(0):
        LSA=0;LSB=0;LSC=0;DIG=a[count%10]; break;
       case(1):
        LSA=1;LSB=0;LSC=0;
        if(count>=10)
         DIG=a[count%100/10];
        else
         DIG=a[10];
        break;
       case(2):
        LSA=0;LSB=1;LSC=0;
        if(count>=100)
         DIG=a[count%1000/100];
        else
         DIG=a[10];
        break;
       case(3):
        LSA=1;LSB=1;LSC=0;
        if(count>=1000)
         DIG=a[count%10000/1000];
        else
         DIG=a[10];
        break;
       case(4):
        LSA=0;LSB=0;LSC=1;
        if(count>=10000)
         DIG=a[count%100000/10000];
        else
         DIG=a[10];
        break;
       case(5):
        LSA=1;LSB=0;LSC=1;
        if(count>=100000)
         DIG=a[count%1000000/100000];
        else
         DIG=a[10];
        break;
       case(6):
        LSA=0;LSB=1;LSC=1;
        if(count>=1000000)
         DIG=a[count%10000000/1000000];
        else
         DIG=a[10];
        break;
       case(7):
        LSA=1;LSB=1;LSC=1;
        if(count>=10000000)
         DIG=a[count%100000000/10000000];
        else
         DIG=a[10];
        break; 
      }
      p=10;      
      while(p--); 
     
      DIG=0x00;
     }
    }

    void conversion()
    {
     unsigned keydate_count;
       if(KeyDate%4!=0)
      {
       if(KeyDate!=15)//
        {
         switch(KeyDate)//
         {
           case 1:
           case 2:
           case 3:keydate_count=KeyDate;break;
           case 5:
           case 6:
           case 7:keydate_count=KeyDate-1;break;
           case 9:
           case 10:
           case 11: keydate_count=KeyDate-2;break;
           case 14 :keydate_count=0;break;
           default :break;      
         }
         count=count*10+keydate_count;
        }
        else//
        {
         if(symbol=='+')
          sum+=count;
         if(symbol=='-')
          sum-=count;
         if(symbol=='*')
          sum*=count;
         if(symbol=='/')
          sum/=count;
         count=sum;
        }
      }
      else  //
      {
        switch(KeyDate)//
        {
         case 4: symbol='+';break;
         case 8: symbol='-';break;
         case 12: symbol='*';break;
         case 16: symbol='/';break;
        }
        sum=count;
        count=0;
       }  
    }
    void delay()  
    {
     unsigned char b,c;
        for(c=200;c>0;c--)
            for(b=200;b>0;b--);
    }

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

    2020-07-30 23:31:48
    51单片机实现计算器功能,包括加减乘除,且支持退格功能。使用矩阵键盘,最右边一列从上到下代表加减乘除,S13代表退格,S15代表等于号,其余为数字
  • 基于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扫描显示,所以当时是想做一个计算器应该还是挺容易的,但直到真正开始做的时候,才发现并不简单。一开始,想的就是,把运算键前输入的数值存到一个变量,后面的数值存到另一个变量内,然后再运算。但问题就来了,如何让单片机知道两次输入的数值要存到不同的变量去?如何把这些变量分别显示到显示管上?然后就要引入更多的变量、设计更多的函数。做出来的第一个版本,能实现加减乘除了,但还有一些问题。按下运算符时,数码管就会直接清零,不像真正计算器那样,按下运算符数码管上数值先不变,等下一数值输入时才变。还有不能实现连续运算的问题,最后还是修改好了。总的来说,这次设计的过程是很有挑战的,尤其对于我这种不善于编程的人来讲,遇到的问题,虽说比较麻烦,但还是车到山前必有路

    展开全文
  • 基于51单片机的简易计算器制作

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

    基于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();  
    }
    ​```
    
    }
    
    展开全文
  • 本程序实现了完整版计算器,包括加减乘除、带小数点显示、带小数点输入、此外还有带时钟功能。当然也可以实现函数功能,只是东西太多了,放不开了。。就没有加上。以后在上传吧.带仿真文件的,一定要用Proteus7.8...
  • 51单片机计算器(程序+AD+仿真)本人花3周完成,已经打样出板子
  • 新手教程,基于51单片机的计算机例程,亲测有效,51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为...
  • 51单片机计算器(包含小数计算) 编写语言:C 运行情况:完美运行,尚未发现bug 备注:同普通实现小数计算程序不一样(浮点型数据计算存在精度丢失的情况),本程序全部采用整形进行计算,对小数点进行记录,最后...
  • 单片机计算器课程设计,有报告的,总共花了好几天才完成的,共享一下,多多指教!
  • 绝对正确的51单片机简易计算器程序,#include #include #include<string.h>
  • 基于51单片机计算器Proteus仿真:资源包含原理图,源程序及文档。
  • 51单片机计算器的编写及实现

    千次阅读 2017-12-25 08:44:25
    code:/* S16 S12 S8 S4分别是123+ S15 S11 S7 S3分别是456- S14 S10 S6 S2分别是789* S13 S9 S5 S1分别是0 CLR = / */ /* 实现两个数的运算,每个数的位数至少可以八位 */ #include typedef unsigned char ...
    code:
    /*  S16 S12 S8 S4分别是123+
    	S15 S11 S7 S3分别是456-
    	S14 S10 S6 S2分别是789*
    	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;   //令第一行为0,然后判断是哪一列按下
    	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;				//令第二行为0,判断是哪一列按下
    	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;		 //令第三行为0,判断哪一列按下
    	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;		 //令第四行为0,判断哪一列按下
    	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;//全部清除为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;//全部清除为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;//全部清除为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;//全部清除为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小的话那么除的结果最高位是0
    						{
    							lcdwrd(0x30);	
    						}
    						lcdwrd(0x3d); //显示等号
    						a=0;
    						b=0;
    						flag=0;
    						fuhao=0;//全部清除为0
    					}
    					break;
    
    		}
    	}
    
    }
    
    
    
    void main()
    {
    	lcdinit();
    	while(1)
    	{
    		keyscan();	
    	}
    }
    

    展开全文
  • 基于51单片机的简单计算器

    千次阅读 多人点赞 2018-06-06 19:58:31
    在上一篇中,我们已经说过了基于51单片机的简单拨号器,在下边,我们将写一个计算器程序,原理很简单,只需要在拨号器的基础上,算出拨号器所表示的数字,并进行计算即可。 代码如下; #include"reg51.h&...
  • 51单片机上实现的完整功能的计算器源代码 单片机 , 计算器 , 源代码
  • 使用keil4开发的c程序,可用于课设做简易计算器使用。有效好使。
  • 运用51单片机制作计算器的源代码@TOC /* S16 S12 S8 S4分别是123+ S15 S11 S7 S3分别是456- S14 S10 S6 S2分别是789* S13 S9 S5 S1分别是0 CLR = / */ /* 实现两个数的运算,每个数的位数至少可以八位 */ #include&...
  • #include "reg52.h" #include "stdio.h" #include<intrins.h> sbit RS = P2^6; sbit RW = P2^5; sbit EN = P2^7; void DelayMs(x) { int y; for(;x>0;x--) for(y = 110;y>......
  • 所使用的开发板为hot51,1602显示,有小数运算功能
  • Proteus 51单片机 C语言 LCD动态显示 键盘扫描
  • 【C51单片机】简易计算器设计(仿真)

    千次阅读 热门讨论 2020-08-17 21:19:38
    设计一个简易计算器,模拟常见计算器的加减乘除运算功能,通过1602液晶屏来显示数字、4*4的矩阵按键来模拟计算机的按键, 2、PROTEUS中设计的电路图 3、源代码 #include <reg51.h> #include <...
1 2 3 4 5 ... 20
收藏数 803
精华内容 321
关键字:

51单片机 计算器