1602显示的简单计算器

2020-01-27 11:41发布

没运算级别,程序如下:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define slong signed long
#define KeyPort P1
#define LCDPort P3
#define RadixMax 4
sbit RS = P2^5;
sbit RW = P2^6;
sbit EN = P2^7;
enum Sign{Null=10,Add,Sub,Mul,Div,Enter};
enum Sign Opera = Null;
bit DelayFlag = 0;
bit KeyFlag = 0;    //键按下标志
uchar DelayBase = 0;        //延时基数
uchar KeyData = 0;           //按键值
uchar KeyCnt= 0;          //按键次数
float Data = 0;       
float Result = 0;
uchar code LCDTab[] = {"0123456789.+-*/="};
uint code PowTab[] = {10,100,1000,10000,10000};       

void TimerInit(void);
uchar KeyRead(void);
void LCDInit(void);
void LCD_EN(void);
void LCDWriteCmd(uchar);
void LCDWriteData(uchar);
void LCDSet_XY(uchar, uchar);
void LCDWriteChar(uchar,uchar,uchar *);
void DisplayResult(float);
void DisplaySign(enum Sign);
void DisplayMum(uchar);
void DisplayClear(void);
void main(void)
{
        KeyPort = 0XFF;
        TimerInit();
        EA = 1;
        LCDInit();
        while(1)
        {  
                if(KeyFlag)
                {
                        KeyFlag = 0;
                        switch(KeyData)
                        {
                                case 0: break;
                                case 0XEE: DisplayMum(7);    break;                                                                                                                               
                                case 0XDE: DisplayMum(8);    break;                                                                                                                                
                                case 0XBE: DisplayMum(9);    break;                                                                                               
                                case 0X7E: DisplaySign(Div); break;                                                                                                                       
                                case 0XED: DisplayMum(4);    break;                                                                                               
                                case 0XDD: DisplayMum(5);    break;                                                                                       
                                case 0XBD: DisplayMum(6);         break;                                                                                       
                                case 0X7D: DisplaySign(Mul); break;                                                                                               
                                case 0XEB: DisplayMum(1);         break;                                                       
                                case 0XDB: DisplayMum(2);         break;                                                                                       
                                case 0XBB: DisplayMum(3);          break;                                                                                       
                                case 0X7B: DisplaySign(Sub); break;                                                                                                                                
                                case 0XE7: DisplayClear();         break;                                                       
                                case 0XD7: DisplayMum(0);         break;                                                                                                               
                                case 0XB7: DisplaySign(Enter);
                                                   DisplayResult(Result); break;                               
                                case 0X77: DisplaySign(Add); break;                               
                        }
                }                                               
        }               
}

void DisplayMum(uchar Index)                //按下数字键调用此函数,Index为相应的键值
{
        LCDWriteChar(KeyCnt-1,0,&LCDTab[Index]);
                Data = Data*10 + Index;                                       
}

void DisplaySign(enum Sign Index)          //按下运算符键调用此函数,Index为相应的运算,包括加减乘除等于
{
        LCDWriteChar(KeyCnt-1,0,&LCDTab[Index]);         //显示运算符号
                switch(Opera)                   //判断上一次按下的运算符,执行相应的操作
                {
                        case Null: Result = Data; break;
                        case Add: Result = Result + Data; break;
                        case Sub: Result = Result - Data; break;
                        case Mul: Result = Result * Data; break;
                        case Div: Result = Result / Data; break;
                        case Enter: Result = Result;
                }
                Data = 0;       
                Opera = Index;                                       
}
void DisplayResult(float Index)          //显示计算结果
{
        uchar i = 0;
        uchar j = 0;
        slong IndexTemp = 0;
        bit NegativeFlag = 0;          //负数标志
        bit RadixFlag = 0;      //小数标志
        IndexTemp = (slong)(Index * 10);
        if(IndexTemp%10 != 0)
        {
                RadixFlag = 1;
                for(j=0;j<RadixMax;j++)
                {
                        IndexTemp = (slong)(Index * PowTab[j]);
                        if(IndexTemp%10 == 0)
                        {
                                IndexTemp = IndexTemp/10;
                                break;
                        }               
                }       
        }
        else
                IndexTemp = IndexTemp/10;               
        if(IndexTemp == 0)
                LCDWriteChar(15,1,&LCDTab[0]);
        if(IndexTemp < 0)                           //如果IndexTemp为负数
        {
                IndexTemp = (~IndexTemp) + 1;   //则将IndexTemp取反再加以,转化为正数
                NegativeFlag = 1;
        }
        if(IndexTemp > 0)
        {
                while(IndexTemp != 0)
                {                                                        
                        LCDWriteChar(15-i,1,&LCDTab[IndexTemp%10]);
                        IndexTemp = IndexTemp/10;                       
                        i ++;
                        if(RadixFlag)                 //如果是小数,则显示.
                        {
                                if(i == j)
                                {
                                        RadixFlag = 0;
                                        LCDWriteChar(15-i,1,&LCDTab[10]);
                                        i = i + 1;
                                        if(IndexTemp == 0)
                                                LCDWriteChar(15-i,1,&LCDTab[0]);
                                }                               
                        }
                }
                if(NegativeFlag)                //如果是负数,则显示-号
                {
                        NegativeFlag = 0;
                        LCDWriteChar(15-i,1,&LCDTab[12]);
                }
        }               
}

仿真图 (原文件名:仿真图.jpg)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
binaimei2007
1楼-- · 2020-01-27 12:19
顶。。
huangdog
2楼-- · 2020-01-27 13:27
 精彩回答 2  元偷偷看……
wwwdege
3楼-- · 2020-01-27 18:16
wingyu
4楼-- · 2020-01-27 19:04
可惜没有小数点....
hwg_LDW
5楼-- · 2020-01-28 00:29
刚刚才发现之前的程序贴得不完整,现在补充下,呵呵……
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define KeyPort P1
#define LCDPort P3
#define TestBusy 1
#define NotTestBusy 0
#define Add 1                  //加
#define Sub 2                  //减
#define Mul 3                  //乘
#define Div 4                  //除
sbit RS = P2^5;
sbit RW = P2^6;
sbit EN = P2^7;
//sbit a =  P3^5;
bit DelayOn = 0;
uchar Delay5xms = 0;        //延时基数
uchar KeyData = 0;           //按键值
uchar KeyCnt= 0;          //按键次数
uchar OperaCnt= 0;    //运算次数
uchar ClothCnt = 0;            //
uchar code ClothTab[] = {"0123456789/"};        //10的N次方查表

void TimerInit(void);
uchar KeyRead(void);
void LCDInit(void);
bit ReadBusy(void);
void LCD_EN(void);
void LCDWriteCmd(bit,uchar);
void LCDWriteData(bit,uchar);
void LCDSet_XY( uchar, uchar);
void LCDPrint(uchar,uchar,uchar *);
void LCDWriteChar(uchar,uchar,uchar *);
void DisplayResult(ulong);
void main(void)
{
        uchar Opera = 0;
        uint Data = 0;
        uint Result = 0;
        ulong ResultAll = 0;
//        a = 0;
        KeyPort = 0XFF;
        TimerInit();
        EA = 1;
        LCDInit();
        while(1)
        {
                switch(KeyData)
                {
                        case 0:break;
                        case 0XEE:                                
                                LCDPrint(KeyCnt-1,0,"7");       
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 7;                                       
                                }
                                                                                               
                                break;
                        case 0XDE:                                
                                        LCDPrint(KeyCnt-1,0,"8");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 8;                                       
                                }                               
                                break;
                        case 0XBE:                                
                                        LCDPrint(KeyCnt-1,0,"9");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 9;
                                       
                                }
                                break;
                        case 0X7E:                               
                        //        LCDWriteChar(KeyCnt-1,0,0X2F);  //除号
                                LCDWriteChar(KeyCnt-1,0,&ClothTab[10]);
                                ClothCnt = 0;
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Result = Result / Data;
                                        Opera = Div;
                                        Data = 0;                                       
                                }                               
                                break;
                        case 0XED:                                
                                        LCDPrint(KeyCnt-1,0,"4");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 4;                                       
                                }
                                break;
                        case 0XDD:                                
                                        LCDPrint(KeyCnt-1,0,"5");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 5;                                       
                                }
                                break;
                        case 0XBD:                                
                                        LCDPrint(KeyCnt-1,0,"6");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 6;                                       
                                }
                                break;
                        case 0X7D:
                                        LCDPrint(KeyCnt-1,0,"*");   //乘号
                                        ClothCnt = 0;
                                        if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Result = Result * Data;
                                        Opera = Mul;
                                        Data = 0;                                       
                                }                               
                                break;
                        case 0XEB:                                
                                        LCDPrint(KeyCnt-1,0,"1");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 1;
                                       
                                }
                                break;
                        case 0XDB:                                
                                        LCDPrint(KeyCnt-1,0,"2");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 2;
                                       
                                }
                                break;
                        case 0XBB:                                
                                        LCDPrint(KeyCnt-1,0,"3");
                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 3;                                       
                                }
                                break;
                        case 0X7B:                                
                                        LCDPrint(KeyCnt-1,0,"-");        //减号
                                        ClothCnt = 0;
                                        if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Result = Result - Data;
                                        Opera = Sub;
                                        Data = 0;
                                       
                                }
                                break;
                        case 0XE7:
                                        LCDWriteCmd(NotTestBusy,0X01);           //清零                                                               
                                KeyCnt = 0;
                                ClothCnt = 0;
                                Result = 0;
                                Data = 0;
                                OperaCnt = 0;
                                break;
                        case 0XD7:                                
                                        LCDPrint(KeyCnt-1,0,"0");

                                if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Data = Data*10 + 0;                                       
                                }
                                break;                       
                        case 0XB7:
                                        LCDPrint(KeyCnt-1,0,"=");          //等于
                                        ClothCnt = 0;
                                        if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        switch(Opera)
                                        {
                                                case Add: ResultAll = Result + Data; break;
                                                case Sub: ResultAll = Result - Data; break;
                                                case Mul: ResultAll = Result * Data; break;
                                                case Div: ResultAll = Result / Data; break;
                                        }
                                                                               
                                }
                                Data = 0;
                                DisplayResult(Data);          
                                break;
                        case 0X77:
                                        LCDPrint(KeyCnt-1,0,"+");          //加
                                        ClothCnt = 0;
                                        if(OperaCnt == 1)
                                {
                                        OperaCnt = 0;
                                        Result = Result + Data;
                                        Opera = Add;
                                        Data = 0;
                                       
                                }                               
                                break;
                }
                LCDPrint(0,1,"rftfdg");                                               
        }               
}

void DisplayResult(ulong Index)
{
        uchar i = 0;
        while(Index != 0)
        {
                LCDWriteChar(15-i,1,&ClothTab[Index%10]);
                Index=Index/10;
                i ++;
        }       
}
         
uchar KeyRead(void)  //键盘扫描,逐行扫描
{
        static uchar KeyTemp = 0;
        if((KeyPort & 0XF0) == 0XF0)
        {
                KeyPort = 0XFE;
                if((KeyPort & 0XF0) == 0XF0)
                {
                        KeyPort = 0XFD;
                        if((KeyPort & 0XF0) == 0XF0)
                        {
                                KeyPort = 0XFB;
                                if((KeyPort & 0XF0) == 0XF0)
                                {
                                        KeyPort = 0XF7;
                                        if((KeyPort & 0XF0) == 0XF0)
                                                KeyTemp = KeyTemp;
                                }       
                        }       
                }                                       
        }
        else
        {
                 KeyTemp = KeyPort;
                 KeyCnt ++;                 
                 while((KeyPort & 0XF0) != 0XF0)
                 {OperaCnt = 1;}
        }
        return KeyTemp;
}

void TimerInit(void)
{
        TMOD |= 0X01;
        TH0 = 0XEC;
        TL0 = 0X78;
        ET0 = 1;
        TR0 = 1;
}

void LCDInit(void)
{       
        DelayOn = 1;
        Delay5xms = 3;
        while(Delay5xms);
        DelayOn = 0;
        LCDWriteCmd(NotTestBusy,0X38);

        DelayOn = 1;
        Delay5xms = 1;
        while(Delay5xms);
        DelayOn = 0;
        LCDWriteCmd(NotTestBusy,0X38);
        DelayOn = 1;
        Delay5xms = 1;
        while(Delay5xms);
        DelayOn = 0;
        LCDWriteCmd(NotTestBusy,0X38);
        LCDWriteCmd(NotTestBusy,0X38);
        LCDWriteCmd(TestBusy,0X08);
        LCDWriteCmd(TestBusy,0X01);
        LCDWriteCmd(TestBusy,0X0C);       
//        LCDWriteCmd(TestBusy,0X06);
}

void LCD_EN(void)
{
        EN = 1;
        _nop_();
//        _nop_();       
        EN = 0;
}

bit ReadBusy(void)
{
        bit Status;
        RS = 0;
        RW = 1;
        LCD_EN();
        Status = (bit)(LCDPort & 0X80);
        _nop_();       
        return Status;
}

void LCDWriteCmd(bit BusyTest,uchar Cmd)
{
        if(BusyTest)
                while(ReadBusy());
        RS = 0;
        RW = 0;
        LCDPort = Cmd;
        LCD_EN();
}

void LCDWriteData(bit BusyTest,uchar Data)
{
        if(BusyTest)
                while(ReadBusy());
        RS = 1;
        RW = 0;
        LCDPort = Data;
        LCD_EN();       
}

void LCDSet_XY(uchar X, uchar Y)  //写地址函数
{
    uchar Address;
    if(Y == 0)
                Address = 0X80 + X;
    if(Y == 1)   
                Address = 0XC0 + X;
    LCDWriteCmd(NotTestBusy,Address);
}

void LCDPrint(uchar X,uchar Y,uchar *str)  //在X行,Y列显示
{
        LCDSet_XY(X,Y);
        while(*str != '')
        {
                LCDWriteData(NotTestBusy,*str);
                str ++;
        }
}

void LCDWriteChar(uchar X,uchar Y,uchar *Data) //列x=0~15,行y=0,1
{
          LCDSet_XY(X,Y); //写地址
          LCDWriteData(NotTestBusy,*Data);          
}

void Timer0Isr() interrupt 1
{
        static uchar Cnt = 0;
        TH0 = 0XEC;
        TL0 = 0X78;
        if(DelayOn)
        {
                Delay5xms --;       
        }
        if(Cnt >= 4)
        {
                Cnt = 0;
                KeyData = KeyRead();
        }
        else
                Cnt ++;               
}
ERDTxiduoduo
6楼-- · 2020-01-28 04:27
mark

一周热门 更多>