標題: 關(guān)于89C52單片機串口通信的一個莫名其妙的BUG [打印本頁]

作者: DHC_King    時間: 2018-2-15 02:06
標題: 關(guān)于89C52單片機串口通信的一個莫名其妙的BUG
代碼如下,用 KEIL 仿真時沒有任何問題,但是寫進芯片的時候不知為何 data_len 的值就會變成 FF(還是其他的值不知道),然后單片機串口就一直發(fā)送 "Error: Command length too long!\r\nThe maximum allowable length is 10\r\n" ,當(dāng)我將 data_len 的值改成 1 的時候單片機一直給上位機發(fā) "Y",我初步懷疑是程序開始的時候不知道在哪個地方觸發(fā)了一次中斷,試了一晚上都試不出來結(jié)果,不得已才求助論壇。希望能解決這個問題。
  1. /*
  2. 功能:帶協(xié)議的 51 串口通信
  3. 協(xié)議格式:數(shù)據(jù)長度 + 數(shù)據(jù)
  4. 數(shù)據(jù)類型:字符型(不適用于 hex 數(shù)據(jù))
  5. 注意:一次接收的數(shù)據(jù)長度不能大于 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];  // 接收數(shù)據(jù)緩沖區(qū), char 類型用于比較字符串, 長度加 1 是為了加 \0
  13. uchar data_len=0;  // 指令長度標志位
  14. uchar data_len_bak=0;
  15. bit receive_complete=0;  // 數(shù)據(jù)接收完成標志位

  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;  // 設(shè)置定時器1為工作方式2(8位自動重載),高八位為重載常數(shù),溢出時低八位自動從高八位取初值
  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.         // 發(fā)送一個數(shù)組
  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';  // 給接收到的數(shù)據(jù)最后加上 \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)  // 收到數(shù)據(jù)
  76.         {
  77.                 if(data_len==0)
  78.                 {
  79.                         data_len=SBUF;  // 如果 data_len 為0,即沒收到數(shù)據(jù),于是就初始化數(shù)據(jù)長度
  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,即數(shù)據(jù)已接收完成
  87.                 }
  88.                 RI=0;
  89.         }
  90. }
復(fù)制代碼


作者: DHC_King    時間: 2018-2-15 17:01
我已經(jīng)解決了,是串口助手軟件的問題,我自己重新寫了個串口助手的工具調(diào)試了下是沒有問題的,主要是用其他的串口助手軟件不能方便地按照協(xié)議格式來發(fā)送數(shù)據(jù),我自己寫的串口助手程序可以根據(jù)自己的需要更改一些功能。
作者: DHC_King    時間: 2018-2-16 14:44
現(xiàn)在還有一個問題想求助一下廣大的朋友,這個程序在復(fù)位之后會發(fā)送一次 “Error: Command length too long!\r\nThe maximum allowable length is 10\r\n” ,實在想不出原因,各位幫忙看下哪里的錯誤,謝謝。
新年快樂!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1