数码之家

 找回密码
 立即注册
搜索
查看: 2016|回复: 6

[C51] 求助,51单片机串口接收缓存数据错乱问题,求助高手帮忙解答!不胜感...

[复制链接]
发表于 2020-2-23 23:42:10 | 显示全部楼层 |阅读模式
本帖最后由 黄继临2 于 2020-2-23 23:57 编辑
  1. 以下程序,通过串口助手发送一串组件,识别帧头为0XFF,接收后存入缓存,并进行判定,当判定正确返回一串数据。此时通过查询缓存数据,如果没有加入delay(100); 这个代码,数据会乱码,加入后不会乱码,百思不得其解,具体程序如下:硬件采用Proteus 8 进行模拟,不知道是不是和这个软件有关系,因疫情关系手头暂时没有实物硬件。
  2. <div>uchar seg_table2[24]={0x00};</div><div>void main()
  3. </div>{

  4.         TMOD = 0X20;              
  5.         TH1 = 0XFD;         
  6.         TL1 = 0XFD;         
  7.         SM0 = 0;
  8.         SM1 = 1;        
  9.         TR1 = 1;        
  10.         REN = 1;
  11.         EA=1;
  12.         ES=1;        
  13.         n = 0;
  14.         BZ=1;
  15.          
  16.         while(1)
  17.         {
  18.         
  19.                 if(IN1 == 0 && i == 0)        ////查询缓存
  20.                 {
  21.                         i == 1;
  22.                         for(j=0;j<25;j++)
  23.                                 {
  24.                                         SBUF =seg_table2[j];
  25.                                         delay(5);                                       
  26.                                         if(TI==1)  
  27.                                                 TI = 0;         
  28.                                 
  29.                                 }               
  30.                 }
  31.                 else i=0;
  32.                
  33.                
  34.                 if(seg_table2[0] == 0xff  )//<数据正确则发送25个0x01

  35.                 {
  36.                         delay(100);        //此处不加延时就会出错,时间短了也出错
  37.                         for(i=0;i<25;i++)//返回数据
  38.                         {
  39.                                 SBUF = 0X01;
  40.                                 delay(5);                                       
  41.                                 if(TI==1)  
  42.                                         TI = 0;         
  43.                         
  44.                         }        
  45.                         seg_table2[0] = 0x00;//对查询位清零,避免重复发送</span>
  46.                 }
  47.                
  48.         }
  49. }


  50. void UART_Interrupt(void) interrupt 4
  51. {

  52.                 if(RI==1)        //
  53.                 {
  54.                     SBUF_data=SBUF;
  55.                                  RI = 0;

  56.                 }

  57.                 if(SBUF_data == 0xff )
  58.                 {
  59.                         BZ=0;//接收数据标志位
  60.                    }

  61.                 if(BZ == 0)
  62.                 {
  63.                         seg_table2[n++]=SBUF_data;//缓存数据
  64.                
  65.                     if(n > 24)//25个数据
  66.                         {
  67.                                 n = 0;
  68.                                 BZ=1; //
  69.                         }
  70.                 }                          
  71. }
复制代码

 楼主| 发表于 2020-2-23 23:58:33 | 显示全部楼层
乱码重新编辑了下,麻烦管理员重新审核,谢谢
回复 支持 反对

使用道具 举报

发表于 2020-2-24 14:47:50 | 显示全部楼层
35行  .这个判断不严谨.业务逻辑应该是收完一个数据帧,且帧头为0xFF才进行处理.
如果是发现帧头就处理,执行到47行代码时,串口还未接收完成,就会破坏串口中断程序的逻辑状态.
另外 22行,这代码无意义.也许应该是  i = 1;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-25 10:12:32 | 显示全部楼层
谢谢,我在改了试试,22行应该是我上传程序的时候弄错的,正确是是i=1,按你讲的我应该要有一个判断数据接收完的逻辑,我在更改下程序了试试,非常感谢回复
回复 支持 反对

使用道具 举报

发表于 2020-2-25 11:36:16 | 显示全部楼层
以前在串口通讯遇到过三个问题,
1. 缓冲寄存器操作后,后续延时不够;
2.波特率用错;
3.串口芯片和单片机,因为使用不同供电,没有共地,导致通讯时好时坏
回复 支持 反对

使用道具 举报

发表于 2020-2-26 01:29:07 | 显示全部楼层
将P3.1设为推挽模式试一下看看。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-3 10:50:27 | 显示全部楼层
谢谢各位解答,目前程序已经调试好,主要做了以下改机,这次算是系统的学习了一遍
1、增加了帧头、帧尾识别
2、中断接收在网上学习后重新写了
3、增加了数据异或校验
4、还有一个问题就是数组溢出,这个查了好久查查到,定的数组是24个元素,在返回的时候是25个元素
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-26 04:36 , Processed in 0.109200 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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