×
单片机 > 单片机程序设计 > 详情

基于单片机的简易计算器proteus仿真和源代码

发布时间:2020-08-27 发布时间:
|

51单片机的计算器仿真设计原理图如下(proteus仿真工程文件可到本帖附件中下载)

单片机源程序如下:

#include   //头文件

#define uint unsigned int 

#define uchar unsigned char


sbit lcden=P2^2; //LCD1602控制引脚

sbit rs=P2^0;

sbit rw=P2^1;

sbit busy=P0^7;//LCD忙


char i,j,temp,num,num_1;

long a,b,c;     //a,第一个数 b,第二个数 c,得数

float a_c,b_c;

uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符

//flag=1表示运算符键按下,flag=0表示运算符键没有按下;

//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。


uchar code table[]={//运算数字输入数组

7,8,9,0,

4,5,6,0,

1,2,3,0,

0,0,0,0};

uchar code table1[]={        //经处理后进行键输入显示准备的数组

7,8,9,0x2f-0x30,        //7,8,9,÷

4,5,6,0x2a-0x30,        //4, 5, 6,×

1,2,3,0x2d-0x30,        //1, 2, 3,-

0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+

};

void delay(uchar z) // 延迟函数

{

uchar y;

for(z;z>0;z--)

   for(y=0;y<110;y++);

}

void write_com(uchar com) // 写指令函数

{

        rs=0;

        P0=com;    //com指令付给P0口

        delay(5);lcden=1;delay(5); lcden=0;

}


void write_date(uchar date) // 写数据函数

{

        rs=1; P0=date; delay(5);

        lcden=1; delay(5); lcden=0;

}


void init() //初始化

{

    num=-1;

lcden=1; //使能信号为高电平

rw=0;

write_com(0x38); //8位,2行

delay(5); write_com(0x38); //8位,2行

delay(5); write_com(0x0c); //显示开,光标关,不闪烁*/

delay(1); write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?

delay(1); write_com(0x80); //检测忙信号

delay(1); write_com(0x01); //显示开,光标关,不闪烁

num_1=0;

i=0; j=0;

a=0;     //第一个参与运算的数

b=0;     //第二个参与运算的数

c=0;

flag=0; //flag表示是否有符号键按下, 

fuhao=0; // fuhao表征按下的是哪个符号

}

void keyscan() // 键盘扫描程序

{

        P3=0xfe; 

        if(P3!=0xfe)

        {

           delay(20);// 延迟20ms

           if(P3!=0xfe) {  temp=P3&0xf0;

            switch(temp)

            {

             case 0xe0:num=0;   break;        //7

             case 0xd0:num=1;   break;         //8

             case 0xb0:num=2;   break;        //9

             case 0x70:num=3;   break;        //÷

            }

           }   while(P3!=0xfe);

           if(num==0||num==1||num==2)//如果按下的是'7','8'或'9

           { 

               if(j!=0){write_com(0x01); j=0;  }

               if(flag==0)//没有按过运算符键

                    { a=a*10+table[num];    } //按下数字存储到a

                    else//如果按过运算符键

                    {    b=b*10+table[num];   }//按下数字存储到b

           }

           else//如果按下的是'/'            除法

           {

            flag=1;         //按下运算符

            fuhao=4;//4表示除号已按

           }

           i=table1[num];     //数据显示做准备

           write_date(0x30+i);//显示数据或操作符号

        }


        P3=0xfd;

        if(P3!=0xfd)

        {

           delay(20);

           if(P3!=0xfd){  temp=P3&0xf0;

            switch(temp)

            {

             case 0xe0:num=4; break; //4

             case 0xd0:num=5; break; //5

             case 0xb0:num=6; break; //6

             case 0x70:num=7; break; //×

            }

           }   while(P3!=0xfd);//等待按键释放

           if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'

           { 

            if(j!=0){ write_com(0x01);  j=0;   }

               if(flag==0)//没有按过运算符键

            { a=a*10+table[num];     }

            else//如果按过运算符键

            { b=b*10+table[num];   }

           }

           else//如果按下的是'×'

           {  flag=1;

              fuhao=3;//3表示乘号已按

           }

           i=table1[num];      //数据显示做准备

           write_date(0x30+i);//显示数据或操作符号

        }


        P3=0xfb;

        if(P3!=0xfb){  delay(20);

           if(P3!=0xfb) { temp=P3&0xf0;

            switch(temp)

            {

             case 0xe0:num=8;    break;         //1

             case 0xd0:num=9;    break;         //2

             case 0xb0:num=10;   break;         //3

             case 0x70:num=11;   break;         //-

            }

           }   while(P3!=0xfb);

           if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'

           { 

            if(j!=0){ write_com(0x01);  j=0;  }

              if(flag==0)//没有按过运算符键

            { a=a*10+table[num];   }

            else//如果按过运算符键

            { b=b*10+table[num]; }

           }

           else if(num==11)//如果按下的是'-'

           {

            flag=1;

            fuhao=2;//2表示减号已按

           }

           i=table1[num];  //数据显示做准备

           write_date(0x30+i);//显示数据或操作符号

        }


        P3=0xf7;

        if(P3!=0xf7){   delay(20);

           if(P3!=0xf7){ temp=P3&0xf0;

            switch(temp)

            {

             case 0xe0:num=12; break;  //清0键    

             case 0xd0:num=13; break;  //数字0    

             case 0xb0:num=14; break;  //等于键    

             case 0x70:num=15; break;  //加

            }                                                                   

                } while(P3!=0xf7);


           switch(num)

           {

            case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"

                            break;

            case 13:{                //按下的是"0"

               if(flag==0)//没有按过运算符键

{ a=a*10; write_date(0x30);



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项