从 C 语言计算器到串口屏应用

在工业控制、智能家居等领域,串口屏作为人机交互的重要组件被广泛应用。理解串口屏的工作原理,最好的方式是从基础的 C 语言编程入手。本文将通过实现一个简单的计算器,逐步展示如何从传统 C 语言程序过渡到适合串口屏开发的代码结构。

目录

一、基础计算器实现

二、状态机设计:模拟串口屏交互模式

三、串口屏实战:淘晶驰代码解析

四、总结


一、基础计算器实现

让我们从最基本的 C 语言计算器开始:

复制代码
#include <stdio.h>

int main() {
    double n0, n1;  // n0:当前结果, n1:中间值
    char t1;        // 运算符

    printf("=== 简易计算器 ===\n");
    
    // 输入第一个数字
    printf("请输入第一个数字: ");
    scanf("%lf", &n0);

    // 输入运算符
    printf("请输入运算符 (+, -, *, /): ");
    while (getchar() != '\n'); // 清除缓冲区
    scanf("%c", &t1);

    // 输入第二个数字
    printf("请输入第二个数字: ");
    scanf("%lf", &n1);

    // 根据运算符计算结果
    switch (t1) {
        case '+':
            n0 += n1; break;
        case '-':
            n0 -= n1; break;
        case '*':
            n0 *= n1; break;
        case '/':
            if (n1 == 0) {
                printf("错误:除数不能为零!\n");
                return 1;
            }
            n0 /= n1; break;
        default:
            printf("错误:不支持的运算符!\n");
            return 1;
    }

    // 输出结果
    printf("计算结果: %.2f\n", n0);

    return 0;
}

运行结果如下:

二、状态机设计:模拟串口屏交互模式

串口屏的交互模式与传统控制台程序不同,更接近计算器的操作方式。下面我们实现一个支持连续计算的版本:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 全局变量定义
double n0 = 0;        // 当前输入值/计算结果
double n1 = 0;        // 中间计算结果存储
char t1[2] = "";      // 当前运算符存储
char t2[2] = "";      // 输入状态标记

// 初始化计算器状态
void initCalculator() {
    n0 = 0;
    n1 = 0;
    strcpy(t1, "");
    strcpy(t2, "");
    printf("计算器已初始化\n");
}

// 数字按钮处理函数
void handleDigit(int digit) {
    if (strcmp(t2, "*") == 0) {
        strcpy(t2, "");
        n0 = digit;
    } else {
        n0 = n0 * 10 + digit;
    }
    printf("当前值: %.2f\n", n0);
}

// 运算符按钮处理函数
void handleOperator(char op) {
    strcpy(t2, "*");
    
    if (strcmp(t1, "") == 0) {
        n1 = n0;
    } else if (strcmp(t1, "+") == 0) {
        n1 = n1 + n0;
        n0 = n1;
    } else if (strcmp(t1, "-") == 0) {
        n1 = n1 - n0;
        n0 = n1;
    } else if (strcmp(t1, "*") == 0) {
        n1 = n1 * n0;
        n0 = n1;
    } else if (strcmp(t1, "/") == 0) {
        if (n0 != 0) {
            n1 = n1 / n0;
            n0 = n1;
        } else {
            printf("错误: 除数不能为0\n");
        }
    }
    
    t1[0] = op;
    t1[1] = '\0';
    printf("当前运算符: %s\n", t1);
}

// 等号按钮处理函数
void handleEquals() {
    strcpy(t2, "*");
    
    if (strcmp(t1, "") != 0) {
        if (strcmp(t1, "+") == 0) {
            n1 = n1 + n0;
        } else if (strcmp(t1, "-") == 0) {
            n1 = n1 - n0;
        } else if (strcmp(t1, "*") == 0) {
            n1 = n1 * n0;
        } else if (strcmp(t1, "/") == 0) {
            if (n0 != 0) {
                n1 = n1 / n0;
            } else {
                printf("错误: 除数不能为0\n");
            }
        }
        n0 = n1;
        printf("计算结果: %.2f\n", n0);
    }
}

// 清零按钮处理函数
void handleClear() {
    initCalculator();
}

// 主函数 - 支持直接输入数字和运算符
int main() {
    initCalculator();
    
    char input[20];
    double number;
    char op;
    
    printf("计算器已启动\n");
    printf("输入格式: 数字 -> 运算符(+,-,*,/,=) -> 数字 -> ...\n");
    printf("输入 'c' 清除计算器,输入 'q' 退出\n");
    
    while (1) {
        printf("\n请输入: ");
        scanf("%19s", input);
        
        // 处理命令
        if (strlen(input) == 1) {
            op = input[0];
            
            if (isdigit(op)) {
                handleDigit(op - '0');
            } else if (op == '+' || op == '-' || op == '*' || op == '/') {
                handleOperator(op);
            } else if (op == '=') {
                handleEquals();
            } else if (op == 'c' || op == 'C') {
                handleClear();
            } else if (op == 'q' || op == 'Q') {
                break;
            } else {
                printf("无效输入,请重试\n");
            }
        } 
        // 处理多位数字
        else if (sscanf(input, "%lf", &number) == 1) {
            // 检查是否是合法的数字
            int i;
            for (i = 0; input[i] != '\0'; i++) {
                if (!isdigit(input[i]) && input[i] != '.') {
                    break;
                }
            }
            
            if (input[i] == '\0') {
                // 如果是新输入,直接设置值
                if (strcmp(t2, "*") == 0) {
                    strcpy(t2, "");
                    n0 = number;
                } 
                // 否则视为错误输入(不能追加多位数字)
                else {
                    printf("错误: 只能逐位输入数字\n");
                    continue;
                }
                
                printf("当前值: %.2f\n", n0);
            } else {
                printf("无效输入,请重试\n");
            }
        } else {
            printf("无效输入,请重试\n");
        }
    }
    
    return 0;
}

运行结果如下:

三、串口屏实战:淘晶驰代码解析

以淘晶驰串口屏为例,其开发逻辑与上述 C 语言状态机高度对应,核心差异在于代码要写到控件下面的弹起事件

淘晶驰串口屏系列文章:

001:串口屏介绍

002:淘晶驰USART HMI 上位机软件安装

003:淘晶驰串口屏开发初体验:10分钟实现简易加法器

004:淘晶驰串口屏:复刻苹果计算器,掌握按键控件的切图使用

005:淘晶驰串口屏:复刻苹果计算器,掌握按键控件的切图使用-2个图片

006:淘晶驰串口屏:复刻苹果计算器,掌握切图控件的使用

007:淘晶驰串口屏:复刻苹果计算器,了解代码编写

以下是计算器界面的关键实现:

/*-----------------------------------------

计算器采用双变量存储模式

n0.val - 当前输入值/计算结果

n1.val - 中间计算结果存储

t1.txt - 当前运算符存储(+、-、*、/)

t2.txt - 输入状态标记("*"表示新输入开始)

// 数字按钮通用逻辑:

// 如果t2标记为"*"(表示新输入开始),则直接设置当前值

// 否则将当前值追加到已有数字后(通过*10+新数字实现)

四、总结

本文以 C 语言编程为切入点,系统展示了从传统计算器开发到串口屏交互逻辑的进阶过程,希望对您有帮助。关注我,解锁更多实战技巧!

相关推荐
云边小网安1 小时前
java集合(十) ---- LinkedList 类
java·开发语言·青少年编程·java集合
Zephyrtoria2 小时前
区间合并:区间合并问题
java·开发语言·数据结构·算法
你怎么知道我是队长3 小时前
GO语言---匿名函数
开发语言·后端·golang
lansye3 小时前
侃侃AI编程
开发语言·qt·ai编程
uyeonashi5 小时前
【QT】窗口详解
开发语言·c++·qt·学习
Hello eveybody6 小时前
C++介绍整数二分与实数二分
开发语言·数据结构·c++·算法
几道之旅6 小时前
零基础RT-thread第二节:按键控制
c语言·stm32
Jay_5156 小时前
C语言环形数组(循环队列)详解:原理、实现与应用
c语言·学习·嵌入式·环形数组
Mallow Flowers7 小时前
Python训练营-Day31-文件的拆分和使用
开发语言·人工智能·python·算法·机器学习