51单片机资源吧 关注:38贴子:174
  • 3回复贴,共1

计算器(加减乘除)

只看楼主收藏回复




IP属地:湖北1楼2024-12-08 20:19回复
    #include "reg51.h"
    #include "lcd1602.h"
    #define uchar unsigned char
    #define uint unsigned int
    sbit test=P2^0;
    sbit beep=P2^4;
    uchar mode=0;//模式
    uchar num1[]=" ";
    uchar num2[]=" ";
    uchar num3[]=" ";//结果
    unsigned long x=0,y=0,z=0;//计算变量
    uchar fuhao=0;//符号
    void clear()//显示清零
    {
    uchar i;
    for(i=0;i<8;i++)
    {
    num1[i]=' ';
    num2[i]=' ';
    }
    write_string(1,0," ");
    write_string(2,0," ");
    }
    uchar key()//按键检测
    {
    uchar i,j;
    i=0;j=0;
    P3=0x0f;//行检测
    if(P1!=0xff)
    {
    switch(P1)
    {
    case 0xfe:i=1;break;
    case 0xfd:i=5;break;
    case 0xfb:i=9;break;
    case 0xf7:i=13;break;
    case 0xef:i=17;break;
    case 0xdf:i=21;break;
    case 0xbf:i=25;break;
    case 0x7f:i=29;
    }
    P3=0xff;
    P1=0;
    switch(P3)
    {
    case 0xef:j=0;break;
    case 0xdf:j=1;break;
    case 0xbf:j=2;break;
    case 0x7f:j=3;
    }
    while(P3!=0xff);
    P1=0xff;
    }
    return i+j;
    }
    //主函数
    void main()
    {
    uchar i,j,k;
    init_1602();
    write_string(1,3,"input:");
    while(1)
    {
    //输入第一个数
    i=key();
    if(i==18) //清空
    {
    mode=0;
    clear();
    write_string(1,3,"input:");
    fuhao=0;
    i=0;
    }
    if(mode==0)
    {
    if((i>0)&&(i<11))
    {
    for(j=0;j<7;j++)
    {
    num1[j]=num1[j+1];
    }
    num1[7]=i+0x2f;
    write_string(1,3,num1);
    }
    if((i>12)&&(i<17))//输入符号
    {
    mode=1;
    switch(i)
    {
    case 13:write_string(2,0,"+ ");fuhao=1;break;//+
    case 14:write_string(2,0,"- ");fuhao=2;break;//-
    case 15:write_string(2,0,"x ");fuhao=3;break;//*
    case 16:write_string(2,0,"/ ");fuhao=4;// /
    }
    i=0;
    }
    if(i>16) //错误
    {
    beep=0;
    for(k=0;k<100;k++)
    delay_uint(1000);
    }
    else
    beep=1;
    }
    //=====================================
    //输入第二个数
    if(mode==1)
    {
    if((i>0)&&(i<11))//输入数字
    {
    for(j=0;j<7;j++)
    {
    num2[j]=num2[j+1];
    }
    num2[7]=i+0x2f;
    write_string(2,3,num2);
    }
    if(i==17)//计算
    {
    mode=2;
    x=0;y=0;z=0;
    for(j=0;j<8;j++)//提取x
    {
    x=x*10;
    if(num1[j]!=' ')
    {
    x=x+num1[j]-0x30;
    }
    }
    for(j=0;j<8;j++)//提取y
    {
    y=y*10;
    if(num2[j]!=' ')
    {
    y=y+num2[j]-0x30;
    }
    }
    //计算结果
    num3[0]=' ';
    switch(fuhao)
    {
    case 1:z=x+y;break;//+
    case 2:
    if(x>y)
    z=x-y;
    else
    {
    num3[0]='-';
    z=y-x;
    }
    break;//-
    case 3:z=x*y;break;//*
    case 4:// /
    z=x/y;
    }
    //显示
    num3[8]=z%10+0x30;z=z/10;
    num3[7]=z%10+0x30;z=z/10;
    num3[6]=z%10+0x30;z=z/10;
    num3[5]=z%10+0x30;z=z/10;
    num3[4]=z%10+0x30;z=z/10;
    num3[3]=z%10+0x30;z=z/10;
    num3[2]=z%10+0x30;z=z/10;
    num3[1]=z%10+0x30;
    clear();
    delay_uint(50000);
    write_string(1,0," = ");
    write_string(2,1,num3);
    fuhao=0;
    }
    if((i>17)||((i>10)&&(i<17)))//错误
    {
    beep=0;
    for(k=0;k<100;k++)
    delay_uint(1000);
    }
    else
    beep=1;
    }
    }
    }


    IP属地:湖北2楼2024-12-08 20:20
    回复
      2025-05-11 08:45:56
      广告
      #ifndef __LCD1602_H_
      #define __LCD1602_H_
      /**********************************
      当使用的是4位数据传输的时候定义,
      使用8位取消这个定义
      **********************************/
      //#define LCD1602_4PINS
      /**********************************
      包含头文件
      **********************************/
      #include<reg51.h>
      //---重定义关键词---//
      #ifndef uchar
      #define uchar unsigned char
      #endif
      #ifndef uint
      #define uint unsigned int
      #endif
      /**********************************
      PIN口定义
      **********************************/
      sbit rs=P2^7; //1602数据/命令选择引脚 H:数据 L:命令
      sbit rw=P2^6; //1602读写引脚 H:数据寄存器 L:指令寄存器
      sbit e =P2^5; //1602使能引脚 下降沿触发
      /**********************************
      函数声明
      **********************************/
      void write_com(uchar com); //LCD1602写入8位数据子函数
      void write_data(uchar dat); //1602写数据函数
      void init_1602(); //LCD1602初始化子程序
      void write_string(uchar hang,uchar add,uchar *p); //显示字符串
      void delay_uint(uint i);
      #endif


      IP属地:湖北3楼2024-12-08 20:20
      回复
        #include "lcd1602.h"
        void delay_uint(uint i)
        {
        while(i--);
        }
        /********************************************************************
        * 名称 : write_com(uchar com)
        * 功能 : 1602命令函数
        * 输入 : 输入的命令值
        * 输出 : 无
        ***********************************************************************/
        void write_com(uchar com)
        {
        e=0;
        rs=0;
        rw=0;
        P0=com;
        delay_uint(20);
        e=1;
        delay_uint(20);
        e=0;
        }
        /********************************************************************
        * 名称 : write_data(uchar dat)
        * 功能 : 1602写数据函数
        * 输入 : 需要写入1602的数据
        * 输出 : 无
        ***********************************************************************/
        void write_data(uchar dat)
        {
        e=0;
        rs=1;
        rw=0;
        P0=dat;
        delay_uint(20);
        e=1;
        delay_uint(20);
        e=0;
        }
        /********************************************************************
        * 名称 : write_string(uchar hang,uchar add,uchar *p)
        * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
        write_string(1,5,"ab cd ef;")
        * 输入 : 行,列,需要输入1602的数据
        * 输出 : 无
        ***********************************************************************/
        void write_string(uchar hang,uchar add,uchar *p)
        {
        if(hang==1)
        write_com(0x80+add);
        else
        write_com(0x80+0x40+add);
        while(1)
        {
        if(*p == '\0') break;
        write_data(*p);
        p++;
        }
        }
        /********************************************************************
        * 名称 : init_1602()
        * 功能 : 初始化1602液晶
        * 输入 : 无
        * 输出 : 无
        ***********************************************************************/
        void init_1602()
        {
        write_com(0x38);//数据总线为8位,显示2行,5x7点阵
        write_com(0x0e);//开显示,有光标,光标闪烁
        write_com(0x06);//光标自动右移
        delay_uint(1000);//等待设置完成
        }


        IP属地:湖北4楼2024-12-08 20:20
        回复