基于PIC18F46K22的UART计算器减法功能故障排查求助
PIC18F46K22 UART计算器减法失效问题排查与修复
核心问题分析
你的代码存在三个关键问题,直接导致减法功能异常:
- 数字未解析:
num1和num2是未初始化的局部变量,没有从输入字符串g_mail.data中提取实际数值。加法功能“正常”只是随机内存值巧合匹配预期结果,减法则因随机值的不确定性表现失效。 - 运算符判断有漏洞:未初始化
operator变量,若输入无合法运算符,会触发未知分支;同时strstr用于单字符查找冗余,且未处理多运算符共存的异常输入。 - 无效输入未处理:没有对无运算符、非数字输入的情况做容错处理,会导致错误结果输出。
修复后的代码
#include <xc.h> //-- for XC8 compiler #include <stdio.h> // for printf #include <ctype.h> #include <string.h> #include <stdlib.h> #define _XTAL_FREQ 32E6 typedef struct { char data[32]; char full; int index; } mailbox; // 全局邮箱变量(假设已在其他位置定义) mailbox g_mail; void main(void) { // 补充UART初始化示例(根据实际波特率调整) TXSTA1bits.TXEN = 1; // 使能发送 RCSTA1bits.SPEN = 1; // 使能串口 SPBRG1 = 51; // 32MHz晶振对应9600波特率 while(1) { if(g_mail.full) { char *op_pos = NULL; int num1, num2; char operator = '\0'; // 初始化运算符为无效值 char resultStr[16] = {0}; // 查找运算符位置(优先匹配+、-) if ((op_pos = strchr(g_mail.data, '+')) != NULL) { operator = '+'; } else if ((op_pos = strchr(g_mail.data, '-')) != NULL) { operator = '-'; } if (operator != '\0' && op_pos != NULL) { // 分割字符串提取数字 *op_pos = '\0'; // 将运算符替换为字符串结束符 num1 = atoi(g_mail.data); num2 = atoi(op_pos + 1); // 执行计算 if (operator == '+') { sprintf(resultStr, "%d", num1 + num2); } else if (operator == '-') { sprintf(resultStr, "%d", num1 - num2); } } else { // 处理无效输入 strcpy(resultStr, "Err"); } // 发送结果 for (int i = 0; resultStr[i] != '\0'; i++) { while (!TXSTAbits.TRMT); // 等待发送缓冲区空闲 TXREG = resultStr[i]; } // 重置邮箱状态 g_mail.full = 0; memset(g_mail.data, 0, sizeof(g_mail.data)); g_mail.index = 0; } } }
关键修复点说明
- 数字解析逻辑:用
strchr定位运算符位置,将输入字符串分割为两个数字子串,通过atoi转换为整数,确保num1和num2使用实际输入值。 - 运算符安全处理:初始化
operator为'\0',避免未初始化的随机值导致错误分支;用strchr替代strstr更高效,适合单字符查找。 - 容错机制:增加无效输入处理,输出
Err提示非法输入。 - UART初始化补充:添加基础的UART初始化代码(根据实际波特率调整
SPBRG1值),确保通信正常。
内容的提问来源于stack exchange,提问作者Lucie Oborná
相关产品推荐
相关产品推荐

