2020单片机V2.0-试题4 小型计算器

利用矩阵键盘,实现小型计算器功能,矩阵键盘键位对应的数字随机给定。
能执行整数间的加减乘除,并将结果显示在数码管上。对于计算结果大于8位的整数显示error;
除法舍去小数点后的数目(附带加分项,保留3位小数)

单步计算版:

/************************************************

                      小 型 计 算 器_(例程)

************************************************/

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long int

sbit x = P2 ^ 0;
sbit y = P2 ^ 1;
sbit z = P2 ^ 2;

uchar code error[] = {0x31, 0x3f, 0x31, 0x31, 0x79};
uchar code table[] = {
    0x3f, 0x06, 0x5b, 0x4f, //0,1,2,3
    0x66, 0x6d, 0x7d, 0x07, //4,5,6,7
    0x7f, 0x6f, 0x77, 0x7c, //8,9,A,B
    0x39, 0x5e, 0x79, 0x71  //C,D,E,F
};

void delay(uint z);  //延时(ms)
void digit(uchar num);  //数码管位选
void display(ulong num);  //数码管显示数字
uchar matrixKey();  //矩阵键盘检测,并返回键盘符号
ulong operating(ulong number1, ulong number2, uchar operation);  //执行计算并返回计算结果


/* 延时(ms) */
void delay(uint z)
{
    uint x, y;
    for (x = z; x > 0; x--)
        for (y = 110; y > 0; y--)
            ;
}

/* 数码管位选 */
void digit(uchar num)
{
    switch (num)
    {
    case 0:x = 1;y = 1;z = 1;break;
    case 1:x = 1;y = 1;z = 0;break;
    case 2:x = 1;y = 0;z = 1;break;
    case 3:x = 1;y = 0;z = 0;break;
    case 4:x = 0;y = 1;z = 1;break;
    case 5:x = 0;y = 1;z = 0;break;
    case 6:x = 0;y = 0;z = 1;break;
    case 7:x = 0;y = 0;z = 0;break;
    }
}

/* 数码管显示数字 */
void display(ulong num)
{
    uchar nums[9], j = 0, i = 0;
    if (num > 99999999)  //超出8位数,输出ERROR
    {
        for (j = 0; j < 5; j++)
        {
            digit(j);
            P0 = error[j];
            delay(1);
            P0 = 0; //消影
        }
    }
    else
    {
        while (num > 0) //取出各位数,组成数组
        {
            nums[i] = num % 10;
            num /= 10;
            i++;
        }
        for (j = 0; j < i; j++) //输出数组中的数
        {
            digit(j);
            P0 = table[nums[j]];
            delay(1);
            P0 = 0; //消影
        }
    }
}

/* 矩阵键盘检测 */
uchar matrixKey()
{
    uchar temp, temp2, i, num = '#';
    temp2 = 0xfe;
    for (i = 0; i < 4; i++)  //for循环和temp2配合实现逐行扫描
    {
        P1 = temp2;
        temp = P1;
        temp = temp & 0xf0;
        if (temp != 0xf0) //矩阵键盘检测
        {
            delay(5); //消抖
            temp = P1;
            temp = temp & 0xf0;
            if (temp != 0xf0)
            {
                temp = P1; //重复检测
                switch (temp)
                {
                case 0xee:num = 1;break;
                case 0xde:num = 2;break;
                case 0xbe:num = 3;break;
                case 0x7e:num = '+';break;
                case 0xed:num = 4;break;
                case 0xdd:num = 5;break;
                case 0xbd:num = 6;break;
                case 0x7d:num = '-';break;
                case 0xeb:num = 7;break;
                case 0xdb:num = 8;break;
                case 0xbb:num = 9;break;
                case 0x7b:num = '*';break;
                case 0xe7:num = 0;break;
                case 0xd7:num = '=';break;
                case 0xb7:num = '.';break;
                case 0x77:num = '/';break;
                }
                break;
            }
        }
        temp2 = temp2 << 1 | 0x01;
    }

    temp = P1;
    temp = temp & 0xf0;
    while (temp != 0xf0) //松手检测
    {
        temp = P1;
        temp = temp & 0xf0;
    }
    return num;
}

/* 执行计算 */
ulong operating(ulong number1, ulong number2, uchar operation)
{
        ulong result;
    switch (operation)
    {
    case '+':result = number1 + number2;break;
    case '-':result = number1 - number2;break;
    case '*':result = number1 * number2;break;
    case '/':result = number1 / number2;break;
    }
    return result;
}

void main(void)
{
    uchar input2 = 0, temp, operation, key, isCont = 0;
    ulong number1 = 0, number2 = 0;
    while (1)
    {
        temp = matrixKey(); //获取检测按键得到的值
        if (temp != '#')
        {
            key = temp;  //当获取到有效值时,存入key
            if (!input2)
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')  //若为数字则填入number1
                    number1 = number1 * 10 + key;  
                else  //若为符号
                {
                    if (key != '=')  //符号不是等号,则记录符号并开始输入number2
                    {
                        input2 = 1;
                        operation = key;
                    }
                }
            }
            else  
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')
                    number2 = number2 * 10 + key;
                else //再次输入符号时
                {
                    number1 = operating(number1, number2, operation);  //计算得到结果存入number1
                    input2 = 0;
                }
            }
        }
        if (!input2)  //输入第1个数字时显示number1
            display(number1);
        else
            display(number2);
    }
}

连续计算版:

/************************************************

                      小 型 计 算 器_(例程)

************************************************/

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long int

sbit x = P2 ^ 0;
sbit y = P2 ^ 1;
sbit z = P2 ^ 2;

uchar code error[] = {0x31, 0x3f, 0x31, 0x31, 0x79};
uchar code table[] = {
    0x3f, 0x06, 0x5b, 0x4f, //0,1,2,3
    0x66, 0x6d, 0x7d, 0x07, //4,5,6,7
    0x7f, 0x6f, 0x77, 0x7c, //8,9,A,B
    0x39, 0x5e, 0x79, 0x71  //C,D,E,F
};

void delay(uint z);  //延时(ms)
void digit(uchar num);  //数码管位选
void display(ulong num);  //数码管显示数字
uchar matrixKey();  //矩阵键盘检测,并返回键盘符号
ulong operating(ulong number1, ulong number2, uchar operation);  //执行计算并返回计算结果


/* 延时(ms) */
void delay(uint z)
{
    uint x, y;
    for (x = z; x > 0; x--)
        for (y = 110; y > 0; y--)
            ;
}

/* 数码管位选 */
void digit(uchar num)
{
    switch (num)
    {
    case 0:x = 1;y = 1;z = 1;break;
    case 1:x = 1;y = 1;z = 0;break;
    case 2:x = 1;y = 0;z = 1;break;
    case 3:x = 1;y = 0;z = 0;break;
    case 4:x = 0;y = 1;z = 1;break;
    case 5:x = 0;y = 1;z = 0;break;
    case 6:x = 0;y = 0;z = 1;break;
    case 7:x = 0;y = 0;z = 0;break;
    }
}

/* 数码管显示数字 */
void display(ulong num)
{
    uchar nums[9], j = 0, i = 0;
    if (num > 99999999)  //超出8位数,输出ERROR
    {
        for (j = 0; j < 5; j++)
        {
            digit(j);
            P0 = error[j];
            delay(1);
            P0 = 0; //消影
        }
    }
    else
    {
        while (num > 0) //取出各位数,组成数组
        {
            nums[i] = num % 10;
            num /= 10;
            i++;
        }
        for (j = 0; j < i; j++) //输出数组中的数
        {
            digit(j);
            P0 = table[nums[j]];
            delay(1);
            P0 = 0; //消影
        }
    }
}

/* 矩阵键盘检测 */
uchar matrixKey()
{
    uchar temp, temp2, i, num = '#';
    temp2 = 0xfe;
    for (i = 0; i < 4; i++) //for循环配合temp2实现逐行扫描
    {
        P1 = temp2;
        temp = P1;
        temp = temp & 0xf0;
        if (temp != 0xf0) //矩阵键盘检测
        {
            delay(5); //消抖
            temp = P1;
            temp = temp & 0xf0;
            if (temp != 0xf0)
            {
                temp = P1; //重复检测
                switch (temp)
                {
                case 0xee:num = 1;break;
                case 0xde:num = 2;break;
                case 0xbe:num = 3;break;
                case 0x7e:num = '+';break;
                case 0xed:num = 4;break;
                case 0xdd:num = 5;break;
                case 0xbd:num = 6;break;
                case 0x7d:num = '-';break;
                case 0xeb:num = 7;break;
                case 0xdb:num = 8;break;
                case 0xbb:num = 9;break;
                case 0x7b:num = '*';break;
                case 0xe7:num = 0;break;
                case 0xd7:num = '=';break;
                case 0xb7:num = '.';break;
                case 0x77:num = '/';break;
                }
                break;
            }
        }
        temp2 = temp2 << 1 | 0x01;
    }
    temp = P1;
    temp = temp & 0xf0;
    while (temp != 0xf0) //松手检测
    {
        temp = P1;
        temp = temp & 0xf0;
    }
    return num;
}

/* 执行计算 */
ulong operating(ulong number1, ulong number2, uchar operation)
{
        ulong result;
    switch (operation)
    {
    case '+':result = number1 + number2;break;
    case '-':result = number1 - number2;break;
    case '*':result = number1 * number2;break;
    case '/':result = number1 / number2;break;
    }
    return result;
}

void main(void)
{
    uchar input2 = 0, temp, operation, key, isCont = 0;
    ulong number1 = 0, number2 = 0;
    while (1)
    {
        temp = matrixKey(); //获取检测按键得到的值
        if (temp != '#')
        {
            key = temp;  //当获取到有效值时,存入key
            if (!input2)
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')  //若为数字则填入number1
                    number1 = number1 * 10 + key;  
                else  //若为符号
                {
                    if (key != '='&& isCont == 0)  //符号不是等号且不是连续计算,则开始输入number2并记录符号
                                        {
                                                input2 = 1;
                                                operation = key;
                                        }
                }
            }
            else  
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')
                {
                    isCont = 0;
                    number2 = number2 * 10 + key;
                }
                else //再次输入符号时
                {
                    number1 = operating(number1, number2, operation);  //计算得到结果存入number1
                    number2 = 0;  //将number2清零
                    if (key != '=')
                    {
                        operation = key;  //若符号不是等号,则表示连续计算,记录运算符
                        isCont = 1;
                    }
                    else  //若为等号则显示结束计算
                    {
                        input2 = 0;
                    }
                }
            }
        }
        if (!input2 || isCont)  //输入第1个数字或准备连续计算时显示number1
            display(number1);
        else
            display(number2);
    }
}

含小数连续计算版:

/************************************************

                      *小 型 计 算 器(例程)

************************************************/

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long int

sbit x = P2 ^ 0;
sbit y = P2 ^ 1;
sbit z = P2 ^ 2;

uchar code error[] = {0x31, 0x3f, 0x31, 0x31, 0x79};
uchar code table[] = {
    0x3f, 0x06, 0x5b, 0x4f, //0,1,2,3
    0x66, 0x6d, 0x7d, 0x07, //4,5,6,7
    0x7f, 0x6f, 0x77, 0x7c, //8,9,A,B
    0x39, 0x5e, 0x79, 0x71  //C,D,E,F
};

void delay(uint z);  //延时(ms)
void digit(uchar num);  //数码管位选
void display(ulong num,uchar operation);  //数码管显示数字
uchar matrixKey();  //矩阵键盘检测,并返回键盘符号
ulong operating(ulong number1, ulong number2, uchar operation);  //执行计算并返回计算结果


/* 延时(ms) */
void delay(uint z)
{
    uint x, y;
    for (x = z; x > 0; x--)
        for (y = 110; y > 0; y--)
            ;
}

/* 数码管位选 */
void digit(uchar num)
{
    switch (num)
    {
    case 0:x = 1;y = 1;z = 1;break;
    case 1:x = 1;y = 1;z = 0;break;
    case 2:x = 1;y = 0;z = 1;break;
    case 3:x = 1;y = 0;z = 0;break;
    case 4:x = 0;y = 1;z = 1;break;
    case 5:x = 0;y = 1;z = 0;break;
    case 6:x = 0;y = 0;z = 1;break;
    case 7:x = 0;y = 0;z = 0;break;
    }
}

/* 数码管显示数字 */
void display(ulong num,uchar operation)
{
    uchar nums[9], j = 0, i = 0;
    if (num > 99999999)  //超出8位数,输出ERROR
    {
        for (j = 0; j < 5; j++)
        {
            digit(j);
            P0 = error[j];
            delay(1);
            P0 = 0; //消影
        }
    }
    else
    {
        while (num > 0) //取出各位数,组成数组
        {
            nums[i] = num % 10;
            num /= 10;
            i++;
        }
        for (j = 0; j < i; j++) //输出数组中的数
        {
            digit(j);
                    if(operation == '/' && j == 5)  //若为除法则添加小数点
                        P0 = table[nums[j]] | 0x80;
                    else
            P0 = table[nums[j]];
            delay(1);
            P0 = 0; //消影
        }
    }
}

/* 矩阵键盘检测 */
uchar matrixKey()
{
    uchar temp, temp2, i, num = '#';
    temp2 = 0xfe;
    for (i = 0; i < 4; i++)  //for循环配合temp2实现逐行扫描
    {
        P1 = temp2;
        temp = P1;
        temp = temp & 0xf0;
        if (temp != 0xf0) //矩阵键盘检测
        {
            delay(5); //消抖
            temp = P1;
            temp = temp & 0xf0;
            if (temp != 0xf0)
            {
                temp = P1; //重复检测
                switch (temp)
                {
                case 0xee:num = 1;break;
                case 0xde:num = 2;break;
                case 0xbe:num = 3;break;
                case 0x7e:num = '+';break;
                case 0xed:num = 4;break;
                case 0xdd:num = 5;break;
                case 0xbd:num = 6;break;
                case 0x7d:num = '-';break;
                case 0xeb:num = 7;break;
                case 0xdb:num = 8;break;
                case 0xbb:num = 9;break;
                case 0x7b:num = '*';break;
                case 0xe7:num = 0;break;
                case 0xd7:num = '=';break;
                case 0xb7:num = '.';break;
                case 0x77:num = '/';break;
                }
                break;
            }
        }
        temp2 = temp2 << 1 | 0x01;
    }
    temp = P1;
    temp = temp & 0xf0;
    while (temp != 0xf0) //松手检测
    {
        temp = P1;
        temp = temp & 0xf0;
    }
    return num;
}

/* 执行计算 */
ulong operating(ulong number1, ulong number2, uchar operation)
{
        ulong result;
    switch (operation)
    {
    case '+':result = number1 + number2;break;
    case '-':result = number1 - number2;break;
    case '*':result = number1 * number2;break;
    case '/':result = number1 * 1000 / number2;break;
    }
    return result;
}

void main(void)
{
    uchar input2 = 0, temp, operation, key;
    ulong number1 = 0, number2 = 0;
    while (1)
    {
        temp = matrixKey(); //获取检测按键得到的值
        if (temp != '#')
        {
            key = temp;  //当获取到有效值时,存入key
            if (!input2)
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')  //若为数字则填入number1
                    number1 = number1 * 10 + key;  
                else  //若为符号
                {
                    if (key != '=')  //符号不是等号,则记录符号并开始输入number2
                                        {
                                                input2 = 1;
                                                operation = key;
                                        }
                }
            }
            else  
            {
                if (key != '+' && key != '-' && key != '*' && key != '/' && key != '=')
                    number2 = number2 * 10 + key;
                else //再次输入符号时
                {
                    number1 = operating(number1, number2, operation);  //计算得到结果存入number1
                    input2 = 0;
                }
            }
        }
        if (!input2)  //输入第1个数字时显示number1
            display(number1,operation);
        else
            display(number2,'=');
    }
}

暂无评论

相关推荐

微信扫一扫,分享到朋友圈

2020单片机V2.0-试题4 小型计算器