基于51单片机设计的计算器软件源代码

/*
接盘按键说明:
--------------------------------------------------
            |  7  |  8  |  9  |  /  |  
            - - - - - - - - - - - - -
            |  4  |  5  |  6  |  *  |
            - - - - - - - - - - - - -
            |  1  |  2  |  3  |  -  |
            - - - - - - - - - - - - -
            | C   |  0  |  =  |  +  | 
--------------------------------------------------*/
//操作简介
// 按第一个数,再按'+-*/',再按'='显示出结果,然后按C清屏
// 加最大9999+9999=19998
// 减最大9999-0   =9999
// 乘最大9999*9999=99980001
// 除 1/9=0.1111 保留小数点后4位
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
//--------LCD1602-------------------
//P00-07==== D0-7
sbit rs=P2^7;        //指令or数据
sbit wela=P2^6;      //读or写
sbit lcden=P2^5;     //使能信号
//--------LCD1602-------------------
//--------KEY-----------------------
//P1口
//--------KEY-----------------------
uchar code table[]= "                ";

long  int data_a,data_b;     //第一个数和第二个数
long  int data_c;            //计算结果

uchar dispaly[10];         //显示缓冲

//************************************************************************/
// 描述: 延时t us函数
//************************************************************************/
void LCD_Delay_us(unsigned int t)
{
    while(t--);           //t=0,退出
}
//************************************************************************/
// 描述: 延时t ms函数
//************************************************************************/
void LCD_Delay_ms(unsigned int t)
{
    unsigned int i,j;
    for(i=0;i<t;i++)               //执行t次循环
    for(j=0;j<113;j++)             //执行113次循环
    ;
}
//************************************************************************/
// 描述: 1602液晶写指令
//************************************************************************/
void write_com(uchar com)        //1602液晶写指令
{
    rs=0;                       //写指令
    lcden=0;                    //使能1602 
    P0=com;                     //写入指令com
    LCD_Delay_ms(1);            //延时1ms
    lcden=1;                    //使能1602
    LCD_Delay_ms(2);            //延时2ms  
    lcden=0;                    //使能1602
}
//************************************************************************/
// 描述:1602液晶写数据 
//************************************************************************/
void write_date(uchar date) //1602液晶写数据
{
    rs=1;                        //写数据
    lcden=0;                     //使能1602 
    P0=date;                     //写入数据date
    LCD_Delay_ms(1);             //延时1ms
    lcden=1;                     //使能1602
    LCD_Delay_ms(2);             //延时2ms
    lcden=0;                     //使能1602
}
//************************************************************************/
// 描述:指定x,y写入字符函数
//************************************************************************/
 void W_lcd(unsigned char x,unsigned char y,unsigned char Data) 
 {     
     if (y == 0){write_com(0x80 + x);}   //第一行  
     else{write_com(0xc0 + x);}          //第二行
     write_date( Data);                  //写入数据
 }
 //指定x,y写入字符串函数
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
 {     
 if (y == 0){write_com(0x80 + x);}         //第一行
 else{write_com(0xC0 + x);}                //第二行
 while (*s)                                //
     {write_date( *s); s++;}              //写入数据
 }
//************************************************************************/
// 描述:初始化液晶,及画面初始化 
//************************************************************************/
void init_lcd(void)            //初始化液晶,及画面初始化
{
    wela=0;                      //写液晶
    lcden=0;                     //使能1602
    write_com(0x38);             //8 位总线,双行显示,5X7 的点阵字符
    LCD_Delay_us(100);           //延时100us
    write_com(0x0c);             //开显示,无光标,光标不闪烁
    write_com(0x06);             //光标右移动
    write_com(0x01);             //清屏
    write_com(0x80);             //DDRAM 地址归0
}
//************************************************************************/
// 描述: 反转法键盘扫描 
//************************************************************************/
short keycheckdown()                /* 反转法键盘扫描 */
{

    short temp1,temp2,temp,a=0xff;
    P1=0xf0;                        /* 输入行值(或列值) */
    LCD_Delay_ms(20);                /* 延时 */
    temp1=P1;                        /* 读列值(或行值) */
    P1=0xff;
    LCD_Delay_ms(20);                /* 延时 */
    P1=0x0f;                        /* 输入列值(或行值) */
    LCD_Delay_ms(20);                /* 延时 */    
    temp2=P1;                        /* 读行值(或列值) */
    P1=0xff;
    temp=(temp1&0xf0)|(temp2&0xf);    /* 将两次读入数据组合 */
    switch(temp)                    /* 通过读入数据组合判断按键位置 */
    {


        case 0x77 :a=0x0a;break;//  按键+   
        case 0x7b :a=0x0e; break;// 按键=    
        case 0x7d :a=0;       break;// 按键0
        case 0x7e :a=0x0f; break;// 按键CE

        case 0xe7 :a=0x0d;break;//     按键/
        case 0xeb :a=0x9;break; //  按键9
        case 0xed :a=0x8;break; //  按键8 
        case 0xee :a=0x7;break; //     按键7

        case 0xd7 :a=0x0c;break;//  按键*
        case 0xdb :a=0x6;break; //     按键6
        case 0xdd :a=0x5;break; //     按键5
        case 0xde :a=0x4;break; //     按键4

        case 0xb7 :a=0x0b; break;// 按键-
        case 0xbb :a=3;break;    //  按键3
        case 0xbd :a=2;break;    //  按键2
        case 0xbe :a=1;break;    //  按键1

        default :a=0xff;
    }
    return a;                        /* 返回按键值 */
}
void display_a() //显示数据a
{
    dispaly[3]=data_a%10000/1000;    //千
    dispaly[2]=data_a%1000/100;      //百
    dispaly[1]=data_a%100/10;        //十
    dispaly[0]=data_a%10;            //个 

    write_com(0x80+0);               //显示数据a
    if(data_a>999){    write_date('0'+dispaly[3]);}      //显示千位
    if(data_a>99){    write_date('0'+dispaly[2]);}         //显示百位
    if(data_a>9){    write_date('0'+dispaly[1]);}     //显示十位
                      write_date('0'+dispaly[0]);      //显示个位
}

void display_b() //显示数据b
{
    write_com(0x80+7); //第一行
    dispaly[3]=data_b%10000/1000;    //千
    dispaly[2]=data_b%1000/100;      //百
    dispaly[1]=data_b%100/10;        //十
    dispaly[0]=data_b%10;            //个 

if(data_b>999){    write_date('0'+dispaly[3]); }     //显示千位   
if(data_b>99) {    write_date('0'+dispaly[2]); }    //显示百位  
if(data_b>9)  {    write_date('0'+dispaly[1]); }     //显示十位
                  write_date('0'+dispaly[0]);      //显示个位
}

//计算结果
void display_c(x)
{

    if(data_c<100000000&&data_c>-1)//溢出时显示错误
    {    

        dispaly[8]=data_c%1000000000/100000000;        //万万
        dispaly[7]=data_c%100000000/10000000;        //千万
        dispaly[6]=data_c%10000000/1000000;            //百万
        dispaly[5]=data_c%1000000/100000;            //十万
        dispaly[4]=data_c%100000/10000;                //万
        dispaly[3]=data_c%10000/1000;                //千
        dispaly[2]=data_c%1000/100;                  //百
        dispaly[1]=data_c%100/10;                    //十
        dispaly[0]=data_c%10;                        //个 
        write_com(0x80+6+0x40); //第一行
        if(x==4)
        {    
            if(data_c>99999999)    {    write_date('0'+dispaly[8]);}    //显示万万
            if(data_c>9999999)    {    write_date('0'+dispaly[7]);}   //千万
            if(data_c>999999)    {    write_date('0'+dispaly[6]);}    //百万
            if(data_c>99999)    {    write_date('0'+dispaly[5]);}    //十万
            if(data_b!=0)        {
                                    write_date('0'+dispaly[4]);    //万
                                    write_date('.');
                                    write_date('0'+dispaly[3]);    //千
                                    write_date('0'+dispaly[2]);    //百
                                    write_date('0'+dispaly[1]);    //十
                                    write_date('0'+dispaly[0]);    //个 
                                }
        }
    else{
        if(data_c>99999999)    {    write_date('0'+dispaly[8]);}    //显示万万
        if(data_c>9999999)    {    write_date('0'+dispaly[7]);}    //千万
        if(data_c>999999)    {    write_date('0'+dispaly[6]);}    //百万
        if(data_c>99999)    {    write_date('0'+dispaly[5]);}    //十万
        if(data_c>9999)        {    write_date('0'+dispaly[4]);}    //万
        if(data_c>999)        {    write_date('0'+dispaly[3]);}    //千
        if(data_c>99)        {    write_date('0'+dispaly[2]);}    //百
        if(data_c>9)        {    write_date('0'+dispaly[1]);}    //十
                                write_date('0'+dispaly[0]);    //个 
        }
    }
//    else  //溢出时显示错误
//    {
//        write_com(0x80+11+0x40); //第一行
//        write_date('E');         //显示 E 
//        write_date('r');         //显示R
//        write_date('r');         //显示R
//        write_date('o');         //显示O
//        write_date('r');         //显示E
//    }
}

void eql(uchar x)//加减乘除运算
{
    switch(x)        /*功能键选择*/
            {   
                case 1:data_c=data_a+data_b;break;           //加  /* + S=1 */ /* 数值转换函数 */                                    
                case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///减
                       else{data_c=data_b-data_a;W_lcd(5,1,'-');} //负数符号
                       break;       
                case 3:data_c=(data_a*data_b);break;          /* * S=3 *///乘
                case 4:if(data_b==0){LCD_Write_String(0,1,"Error !         ");}else{data_c=(data_a*10000)/data_b;}break;          /* / S=4 *///除//溢出时显示错误
                case 0:break;
            }      

}

void main()
{
    uchar   key=0xff;               //键值初始化
    uchar   n=0;                     //第1个数可以按1-4次
    uchar   m=5;                     //第2个数可以按1-4次
    uchar   x=0; 
    data_a=0;                       //前一个数
    data_b=0;                       //后一个数
    data_c=0;                       //结果 
    init_lcd();                      //1602液晶初始化
    display_a();
    while(1)
      {
          key=keycheckdown();            /*动态扫描键盘,返回按键对应值,赋给j        key=0到f */
        if(0xff!=key)                /*若返回值有效,进入内部处理程序*/
        { 
          if(key<10)
          {
              if(key==0&&n==0) ;
            else
            {
                if(n<4){data_a=data_a*10+key;m=5;display_a();}n++;  //首先输入第一个数    
            }
            if(key==0&&m==0) ;
            else
            {
                if(m<4){data_b=data_b*10+key;n=5;display_b();}m++;  //必须按了+-*/才能输入第二个数    
            }
          }
          else
          {    switch(key)        /*功能键选择*/
                    {
                        case 0xa:n=5;m=0;x=1;W_lcd(5,0,'+');break; //加  /* + S=1 */ /* 数值转换函数 */                                    
                        case 0xb:n=5;m=0;x=2;W_lcd(5,0,'-');break;          /* - S=2 *///减
                        case 0xc:n=5;m=0;x=3;W_lcd(5,0,'*');break;          /* * S=3 *///乘
                        case 0xd:n=5;m=0;x=4;W_lcd(5,0,'/');break;          /* / S=4 *///除
                        case 0xe:n=5;m=5;eql(x);W_lcd(12,0,'=');display_c(x);break;       /* = */
                        case 0xf:n=0;x=0;m=5; data_a=0;data_b=0;data_c=0;LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0');break; /*     C*/
                    }                
          }
            do{P1=0xf0;}while(P1!=0xf0);        /*等待按键松开*/
          }//(0xff!=key)      
      }//while
}//main


 

51计算器程序#include #include #define uchar unsigned char #define uint unsigned int sbit lcden=P3^4; sbit lcdrw=P3^6; sbit lcdrs=P3^5; uchar num,temp,jia=0,cheng=0,chu=0,jian=0,qing=0; uint key,key1,shu; uchar fuhao,flag1,flag=0; uchar table[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,}; void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=114;y>0;y--); } bit lcd_bz() { bit result; lcdrs = 0; lcdrw= 1; lcden = 1; _nop_(); _nop_(); _nop_(); _nop_(); result=(bit)(P0&0x80;); lcden=0; return result; } void write_com(uchar com) { while(lcd_bz()); lcdrs=0; lcden=0; lcdrw=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_date(uchar date) { while(lcd_bz()); lcdrs=1; lcden=0; lcdrw=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void lcd_init() { lcden=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); } void keyscan() { P3=0xfe; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xee:key=1;num=0;break; case 0xde:key=2;num=0;break; case 0xbe:key=3;num=0;break; case 0x7e:num=1;break; //¼ÓºÅ } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } P3=0xfd; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xed:key=4;num=0;break; case 0xdd:key=5;num=0;break; case 0xbd:key=6;num=0;break; case 0x7d:num=2;break; //¼õºÅ } while( temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } P3=0xfb; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb:key=7;num=0;break; case 0xdb:key=8;num=0;break; case 0xbb:key=9;num=0;break
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SKCQTGZX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值