单片机实现简易四位数计算器功能(加减乘除操作源码详解)

单片机实现简单计算器(4位加减乘除)

在嵌入式系统开发中,实现一个简单的计算器是一个常见且实用的项目,尤其是在学习和实践单片机编程时。我们将通过使用单片机(例如AT89C51)来实现一个支持4位加、减、乘、除的简单计算器。计算器将接收用户输入的两个4位数字,以及操作符,然后进行相应的计算,并通过显示设备(如7段数码管或LCD显示屏)输出结果。

1. 项目需求分析

目标:
  1. 用户输入:用户通过键盘输入两个4位数字和一个操作符(加、减、乘、除)。
  2. 显示结果:计算器将显示计算结果(4位数)。
  3. 操作支持:支持加法、减法、乘法和除法四种基本运算。
  4. 错误处理:如果除数为0,显示错误提示。
功能需求:
  1. 输入功能:通过键盘输入数字和运算符。
  2. 显示功能:通过7段数码管或LCD显示计算结果。
  3. 运算功能:支持加法、减法、乘法、除法等四则运算。
  4. 除数为零处理:当用户进行除法运算且除数为零时,计算器应显示“ERROR”。

2. 硬件设计

2.1 单片机选择

本项目使用AT89C51单片机,它具有足够的GPIO端口来连接显示器和键盘。通过串口或并口与显示器连接,通过GPIO口控制键盘输入。

2.2 硬件连接
  1. 键盘
  2. 使用4×4矩阵键盘进行数字和操作符输入。矩阵键盘通过行列连接到单片机的GPIO口。
  3. 显示设备
  4. 可以使用7段数码管LCD屏来显示输入的数字和计算结果。
  5. 电源
  6. 为单片机和其他外设提供稳定的电源。
2.3 电路设计
  • 矩阵键盘:连接至单片机的4行4列引脚。
  • 7段数码管:连接至单片机的多个GPIO引脚,用于显示输入的数字和计算结果。
  • 3. 软件设计

    3.1 键盘扫描

    使用矩阵键盘来输入数字和运算符。每按下一个键,程序将根据扫描键盘的状态,将按键值保存下来。

    3.2 运算逻辑

    根据用户输入的两个4位数字和操作符进行相应的计算。支持加法、减法、乘法和除法。对于除法操作,需要特别处理除数为零的情况。

    3.3 显示功能

    使用7段数码管或LCD显示屏显示计算结果。由于结果可能是4位数,需要确保显示器能够显示足够的字符。

    3.4 程序设计
    1. 配置矩阵键盘输入,扫描用户输入。
    2. 根据输入的数字和运算符进行四则运算。
    3. 结果通过数码管或LCD显示。
    4. 错误处理(如除数为零)。
    3.5 代码实现
    #include <reg51.h>  // 包含51单片机的寄存器定义文件
    
    // 定义矩阵键盘的行列引脚
    #define ROW1 P1_0
    #define ROW2 P1_1
    #define ROW3 P1_2
    #define ROW4 P1_3
    #define COL1 P1_4
    #define COL2 P1_5
    #define COL3 P1_6
    #define COL4 P1_7
    
    // 定义7段数码管连接端口
    #define SEGMENTS P2
    
    // 用于存储输入的数字和操作符
    unsigned char num1[4], num2[4], operator;
    unsigned char result[4];  // 用于存储计算结果
    
    // 函数声明
    void delay(unsigned int time);
    void init_keypad();
    unsigned char scan_keypad();
    void display_result(unsigned char* result);
    unsigned char calculate(unsigned char num1[], unsigned char num2[], unsigned char operator);
    
    void delay(unsigned int time) {
        unsigned int i, j;
        for (i = 0; i < time; i++) {
            for (j = 0; j < 120; j++);
        }
    }
    
    // 初始化矩阵键盘扫描
    void init_keypad() {
        ROW1 = ROW2 = ROW3 = ROW4 = 1;  // 设置为输入状态
        COL1 = COL2 = COL3 = COL4 = 0;  // 设置为低电平
    }
    
    // 扫描矩阵键盘
    unsigned char scan_keypad() {
        unsigned char key = 0;
        init_keypad();  // 初始化矩阵键盘
        if (COL1 == 0) key = 1;  // 按键1
        else if (COL2 == 0) key = 2;  // 按键2
        else if (COL3 == 0) key = 3;  // 按键3
        else if (COL4 == 0) key = 4;  // 按键4
        return key;
    }
    
    // 数码管显示结果(这里只是示例,具体显示可根据需求调整)
    void display_result(unsigned char* result) {
        // 显示数组中的数字(假设是4位数)
        // 你可以在这里使用具体的显示函数来显示数字
        SEGMENTS = result[0];  // 显示第一个数字
        delay(500);
        SEGMENTS = result[1];  // 显示第二个数字
        delay(500);
        SEGMENTS = result[2];  // 显示第三个数字
        delay(500);
        SEGMENTS = result[3];  // 显示第四个数字
    }
    
    // 计算两个数字的运算结果
    unsigned char calculate(unsigned char num1[], unsigned char num2[], unsigned char operator) {
        unsigned int n1 = num1[0] * 1000 + num1[1] * 100 + num1[2] * 10 + num1[3];
        unsigned int n2 = num2[0] * 1000 + num2[1] * 100 + num2[2] * 10 + num2[3];
        unsigned int res;
    
        switch (operator) {
            case '+':
                res = n1 + n2;
                break;
            case '-':
                res = n1 - n2;
                break;
            case '*':
                res = n1 * n2;
                break;
            case '/':
                if (n2 == 0) {
                    // 处理除数为零的情况
                    result[0] = 'E';
                    result[1] = 'R';
                    result[2] = 'R';
                    result[3] = '0';
                    return 0;  // 错误
                }
                res = n1 / n2;
                break;
            default:
                return 0;  // 错误
        }
        result[0] = res / 1000;       // 高位
        result[1] = (res % 1000) / 100; // 次高位
        result[2] = (res % 100) / 10;   // 次低位
        result[3] = res % 10;           // 低位
        return 1;
    }
    
    // 主程序
    void main() {
        unsigned char key = 0;
        unsigned char state = 0;  // 用于记录当前输入状态(输入num1、num2或操作符)
        
        while (1) {
            key = scan_keypad();  // 扫描按键输入
            
            if (key) {
                if (state == 0) {  // 输入第一个数字(num1)
                    num1[0] = key;  // 存储按下的数字
                    state = 1;  // 切换到输入num2
                } else if (state == 1) {  // 输入操作符
                    operator = key;  // 存储操作符
                    state = 2;  // 切换到输入num2
                } else if (state == 2) {  // 输入第二个数字(num2)
                    num2[0] = key;  // 存储按下的数字
                    state = 3;  // 切换到计算并显示
                }
            }
    
            if (state == 3) {  // 进行计算
                if (calculate(num1, num2, operator)) {
                    display_result(result);  // 显示结果
                }
                state = 0;  // 重置状态,准备进行下一次计算
            }
        }
    }
    

    4. 代码解释

    1. 初始化键盘和显示器

    2. init_keypad()函数用于初始化矩阵键盘,准备开始扫描。
    3. display_result()函数用于将计算结果显示在数码管上(这里只是一个简化的示例,具体显示功能可以根据需要设计)。
    4. 矩阵键盘扫描

    5. scan_keypad()函数负责扫描矩阵键盘,返回按下的键值。
    6. 计算函数

    7. calculate()函数根据输入的两个数字和操作符进行计算。支持加法、减法、乘法和除法。当除数为零时,返回错误信息。
    8. 主程序流程

    9. 主程序中不断扫描键盘,等待用户输入数字、操作符和第二个数字,计算结果并显示。

    5. 仿真步骤

    1. 在Proteus中创建一个新项目,添加AT89C51单片机
    2. 连接矩阵键盘到单片机的相应引脚,连接数码管或LCD显示器。
    3. 配置仿真环境,上传代码,启动仿真。
    4. 仿真时通过键盘输入数字、操作符,观察数码管显示计算结果。

    6. 总结

    本项目成功实现了一个简单的四则运算计算器,支持加、减、乘、除四种运算,能够进行基本的错误处理(如除数为零)。通过矩阵键盘输入和数码管或LCD显示屏输出,用户能够与计算器进行交互。此设计不仅展示了单片机在数学运算中的应用,还可以作为嵌入式系统学习的基础,具备较高的实用价值。

    作者:Katie。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机实现简易四位数计算器功能(加减乘除操作源码详解)

    发表回复