找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3155|回复: 2
收起左侧

关于89C52单片机串口通信的一个莫名其妙的BUG

[复制链接]
ID:255063 发表于 2018-2-15 02:06 | 显示全部楼层 |阅读模式
代码如下,用 KEIL 仿真时没有任何问题,但是写进芯片的时候不知为何 data_len 的值就会变成 FF(还是其他的值不知道),然后单片机串口就一直发送 "Error: Command length too long!\r\nThe maximum allowable length is 10\r\n" ,当我将 data_len 的值改成 1 的时候单片机一直给上位机发 "Y",我初步怀疑是程序开始的时候不知道在哪个地方触发了一次中断,试了一晚上都试不出来结果,不得已才求助论坛。希望能解决这个问题。
  1. /*
  2. 功能:带协议的 51 串口通信
  3. 协议格式:数据长度 + 数据
  4. 数据类型:字符型(不适用于 hex 数据)
  5. 注意:一次接收的数据长度不能大于 10
  6. */
  7. #include <reg52.h>
  8. #include <string.h>

  9. #define uchar unsigned char
  10. #define uint unsigned int

  11. uchar clock[4]={11,23,34,51};
  12. char recv[11];  // 接收数据缓冲区, char 类型用于比较字符串, 长度加 1 是为了加 \0
  13. uchar data_len=0;  // 指令长度标志位
  14. uchar data_len_bak=0;
  15. bit receive_complete=0;  // 数据接收完成标志位

  16. void delay(uint i)  // 1ms 延时
  17. {
  18.         uint j;
  19.         while(i--)
  20.                 for(j=0;j<192;j++);
  21. }

  22. void init(void)
  23. {
  24.         TMOD=0x20;  // 设置定时器1为工作方式2(8位自动重载),高八位为重载常数,溢出时低八位自动从高八位取初值
  25.         TH1=0xfd;  // 9600 波特率
  26.         TL1=0xfd;
  27.         TR1=1;
  28.         EA=1;
  29.         ES=1;  // 串口中断允许
  30.         REN=1;
  31.         SM0=0;
  32.         SM1=1;
  33. }

  34. void send(uchar d)
  35. {
  36.         SBUF=d;
  37.         while(!TI);
  38.         TI=0;
  39. }

  40. void sendarr(uchar *pd, uchar len)
  41. {
  42.         // 发送一个数组
  43.         while(len--)
  44.         {
  45.                 send(*pd);
  46.                 pd++;
  47.         }
  48. }

  49. void main()
  50. {
  51.         init();
  52.         while(1)
  53.         {
  54.                 if(data_len_bak>10)
  55.                 {
  56.                         ES=0;
  57.                         sendarr("Error: Command length too long!\r\nThe maximum allowable length is 10\r\n", 69);
  58.                         delay(500);
  59.                         ES=1;
  60.                         data_len = 0;
  61.                         continue;
  62.                 }
  63.                 if(receive_complete)
  64.                 {
  65.                         ES=0;
  66.                         //recv[data_len_bak] = '\0';  // 给接收到的数据最后加上 \0 用于比较字符串
  67.                         //if(strcmp(recv, "clock")==0)  sendarr(clock, 4);
  68.                         send('Y');
  69.                         ES=1;
  70.                 }
  71.         }
  72. }

  73. void uart(void) interrupt 4 // 串口中断
  74. {
  75.         if(RI)  // 收到数据
  76.         {
  77.                 if(data_len==0)
  78.                 {
  79.                         data_len=SBUF;  // 如果 data_len 为0,即没收到数据,于是就初始化数据长度
  80.                         data_len_bak=data_len;
  81.                 }
  82.                 else
  83.                 {
  84.                         recv[data_len_bak - data_len] = SBUF;
  85.                         data_len--;
  86.                         if(data_len==0) receive_complete=1;  // 如果 data_len 减到0,即数据已接收完成
  87.                 }
  88.                 RI=0;
  89.         }
  90. }
复制代码

回复

使用道具 举报

ID:255063 发表于 2018-2-15 17:01 | 显示全部楼层
我已经解决了,是串口助手软件的问题,我自己重新写了个串口助手的工具调试了下是没有问题的,主要是用其他的串口助手软件不能方便地按照协议格式来发送数据,我自己写的串口助手程序可以根据自己的需要更改一些功能。

评分

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

查看全部评分

回复

使用道具 举报

ID:255063 发表于 2018-2-16 14:44 | 显示全部楼层
现在还有一个问题想求助一下广大的朋友,这个程序在复位之后会发送一次 “Error: Command length too long!\r\nThe maximum allowable length is 10\r\n” ,实在想不出原因,各位帮忙看下哪里的错误,谢谢。
新年快乐!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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