找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1867|回复: 7
打印 上一主题 下一主题
收起左侧

代码高手看一下我的单片机代码有些问题但不知道问题在哪

[复制链接]
跳转到指定楼层
楼主
100黑币
第一个算式正确第二个就在第一个的基础上累加,输入没有优先级


单片机源程序如下:
  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #include <stdlib.h>
  4. void send_int_to_serial_port(int c);
  5. unsigned char rec_data[32],bete;
  6. unsigned char op,flag, num[2],n=0;
  7. unsigned int i,ansi,j,nm;
  8. void send_data(char jieguo);
  9. void chuankou_chushihua()//串口初始化程序
  10. {
  11.    TMOD|=0X20; //设置计数器1为工作方式 2
  12.    SCON=0X50; //设置串行口为工作方式 1
  13.    PCON=0X80; //波特率加倍
  14.    TH1=0XFA; //计数器初始值设置9600baud
  15.    TL1=0XFA;
  16.    ES=1; //打开接收中断
  17.    EA=1; //打开总中断
  18.    TR1=1; //打开计数器
  19. }
  20. void uart() interrupt 4 //串口通信中断函数
  21. {
  22.            if(RI == 1)
  23.         {
  24.                
  25.                 RI=0;//清除接收中断标志位
  26.                 bete=SBUF;//存储接收到的数据
  27.                 send_data(bete);
  28.                 rec_data[nm++]=bete;
  29.         }
  30.                 flag=1;
  31. }
  32. void send_data(char jieguo)
  33. {

  34.         SBUF=jieguo;
  35.         while(TI==0);
  36.   TI=0;
  37. }
  38. int panduan_jisuan()
  39. {
  40.         if('0'<=rec_data[0]&&rec_data[0]<='9')
  41.     num[0] = rec_data[0] - '0';   
  42.         // 将第一个数字存入num[0]  
  43.     for (i = 1; i < nm; i++)// 扫描整个字符数组,从第二个字符开始逐一处理
  44.     {
  45.         if (rec_data[i] == '+' || rec_data[i] == '-' || rec_data[i] == '*' ||rec_data[i] == '/')// 如果是运算符,则将其存储到op中,并将下一个数字存入num[1]
  46.         {
  47.             op = rec_data[i];
  48.             num[1] = rec_data[i + 1] - '0';  // 将指针移位至下一个数  
  49.         }

  50.         else if (rec_data[i] == '=')  // 如果是等号,则运算结果即为第一个数字
  51.         {
  52.             ansi = num[0];
  53.         }      
  54.         else if('0'<=rec_data[0]&&rec_data[0]<='9') // 如果是数字,则根据之前的运算符进行运算
  55.         {
  56.             switch (op)
  57.             {
  58.                 case '+':
  59.                     num[0] = num[0] + (rec_data[i] - '0');
  60.                     break;
  61.                 case '-':
  62.                     num[0] = num[0] - (rec_data[i] - '0');
  63.                     break;
  64.                 case '*':
  65.                     num[0] = num[0] * (rec_data[i] - '0');
  66.                     break;
  67.                 case '/':
  68.                     num[0] = num[0] / (rec_data[i] - '0');
  69.                     break;
  70.             }
  71.                          ansi=num[0];        
  72.                                                 
  73.         }
  74.     }
  75.                 return ansi;
  76.                
  77.         }
  78. void send_int_to_serial_port(int c)
  79.         {
  80.                
  81.     char buffer[16];
  82.     sprintf(buffer, "%d", c);// 使用 sprintf() 函数将整型变量转换为字符串

  83.     for (i = 0; buffer[i] != '\0'; i++) // 将字符串逐个发送到串口
  84.                 {
  85.         send_data(buffer[i]);
  86.     }
  87.         }

  88. void main()
  89. {         
  90.   int k;
  91.         chuankou_chushihua( );        

  92.         while(1)
  93.         {
  94.                 if(flag==1)
  95.                  {        
  96.                          k=panduan_jisuan();        
  97.                          send_int_to_serial_port(k);
  98.                          flag=0;        
  99.                    }   
  100.                                        
  101.         }
  102. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:235200 发表于 2023-6-22 13:12 | 只看该作者
接收中断发生时,需一次把所有接收字符接收完(没有做到),
send_int_to_serial_port这个函数想把接收表达式及结果发送出去,可buffer缓冲区中无内容
回复

使用道具 举报

板凳
ID:1067540 发表于 2023-6-23 14:15 | 只看该作者
在计算结束后把存储计算结果的变量清零
回复

使用道具 举报

地板
ID:1063563 发表于 2023-6-25 09:47 | 只看该作者
buffer缓冲区不够了,数据溢出了吧。
回复

使用道具 举报

5#
ID:1086796 发表于 2023-7-2 15:55 | 只看该作者
这个程序有几个问题:  在程序开头引入的头文件reg52.h是基于8051单片机的,而不是适用于大多数现代的开发平台。你可以考虑移除这个头文件。  头文件stdio.h中的printf函数和stdlib.h中的sprintf函数不能直接使用,因为它们是针对标准输入输出流的,而不是嵌入式系统中的串口通信。你需要自己实现串口发送函数和接收函数。  rec_data数组没有进行边界检查,可能导致越界访问。在处理接收到的数据之前,应该先检查接收到的数据长度是否超过了数组的长度。  没有对变量nm进行初始化,可能导致未定义的行为。在使用或判断nm之前,应该将其初始化为合适的值。  在函数panduan_jisuan中,判断数字是否在正确的范围内时,使用了错误的条件。应该是'0'<=rec_data[i]&&rec_data[i]<='9'而不是'0'<=rec_data[0]&&rec_data[0]<='9'。  在函数panduan_jisuan中,在执行完一个运算符后没有重置op的值,可能导致后续运算出错。在处理完一个运算符后,应该将op重置为空字符。  在函数send_int_to_serial_port中,没有定义变量i的类型和初始值。应该在函数开头定义并初始化变量i。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

6#
ID:844772 发表于 2023-7-3 08:01 | 只看该作者
1.累加的原因是没清零,但我觉得连续累加这也是一个功能吧。
2.没有优先级是程序问题,建议使用堆栈处理数据,同时解决只能一位运算的问题。
回复

使用道具 举报

7#
ID:1053359 发表于 2023-7-3 12:57 | 只看该作者
在您提供的代码中,存在以下问题:  chuankou_chushihua() 函数中缺少对串口引脚的配置。在8051单片机中,需要设置相应的引脚(如P3.0和P3.1)为串口通信功能。  在主函数 main() 中,调用 chuankou_chushihua() 函数时没有传入任何参数,但是函数定义中有一个参数。  在 uart() 中断函数中,nm 变量用于记录接收到的字符数量,但未进行初始化。需要在主函数中添加类似 nm = 0; 的语句。  在 panduan_jisuan() 函数中,判断数字范围的条件语句错误。正确的条件应为 '0' <= rec_data[i] && rec_data[i] <= '9'。此外,该条件语句也需要修正为 rec_data[i] 而不是 rec_data[0]。  在 panduan_jisuan() 函数中,返回值 ansi 应在最后的 switch 语句之后进行赋值,而不是在进入循环时
回复

使用道具 举报

8#
ID:1087948 发表于 2023-7-31 12:30 | 只看该作者
我注意到了几个可能的问题:  在 uart() 中断函数中,你在接收到数据后立即发送了相同的数据回去,这可能不是你想要的行为。  在 panduan_jisuan() 函数中,你的代码假设每个数字和运算符都是由单个字符表示的,且每个数字和运算符之间没有任何空格或其他字符。如果输入的表达式不满足这些条件,你的代码可能无法正确地解析和计算它。  同样在 panduan_jisuan() 函数中,你的代码只处理了第一个运算符和等号之后的字符,对于等号之后的字符,你的代码并没有进行处理。  你的代码没有处理除数为0的情况,如果输入的表达式包含除以0的操作,你的代码可能会产生错误。  在 main() 函数中,你使用了一个名为 flag 的变量来判断是否已经接收到数据,但是你并没有在任何地方初始化这个变量。如果这个变量的初始值不是0,你的代码可能会在接收到任何数据之前就开始尝试进行计算。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表