欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2183|回復: 4
打印 上一主題 下一主題
收起左側(cè)

關(guān)于單片機RS485程序的問題

[復制鏈接]
回帖獎勵 3 黑幣 回復本帖可獲得 3 黑幣獎勵! 每人限 1 次
跳轉(zhuǎn)到指定樓層
樓主
ID:253579 發(fā)表于 2022-2-19 11:31 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
關(guān)于手把手教51的教程里,關(guān)于485那章程序有個疑問

這個串口驅(qū)動函數(shù)里 len = UartRead(buf, sizeof(buf)-2); //將接收到的命令讀取到緩沖區(qū)中這行為什么要把sizeof(buf)-2呢


/* 串口驅(qū)動函數(shù),監(jiān)測數(shù)據(jù)幀的接收,調(diào)度功能函數(shù),需在主循環(huán)中調(diào)用 */
void UartDriver()
{
    unsigned char len;
    unsigned char pdata buf[40];

    if (flagFrame) //有命令到達時,讀取處理該命令
    {
        flagFrame = 0;
        len = UartRead(buf, sizeof(buf)-2); //將接收到的命令讀取到緩沖區(qū)中
        UartAction(buf, len);  //傳遞數(shù)據(jù)幀,調(diào)用動作執(zhí)行函數(shù)
    }
}


以下是單片機原代碼
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. sbit RS485_DIR = P1^7;  //RS485方向選擇引腳

  4. bit flagFrame = 0;  //幀接收完成標志,即接收到一幀新數(shù)據(jù)
  5. bit flagTxd = 0;    //單字節(jié)發(fā)送完成標志,用來替代TXD中斷標志位
  6. unsigned char cntRxd = 0;   //接收字節(jié)計數(shù)器
  7. unsigned char pdata bufRxd[64];  //接收字節(jié)緩沖區(qū)

  8. extern void UartAction(unsigned char *buf, unsigned char len);

  9. /* 串口配置函數(shù),baud-通信波特率 */
  10. void ConfigUART(unsigned int baud)
  11. {
  12.     RS485_DIR = 0; //RS485設(shè)置為接收方向
  13.     SCON  = 0x50;  //配置串口為模式1
  14.     TMOD &= 0x0F;  //清零T1的控制位
  15.     TMOD |= 0x20;  //配置T1為模式2
  16.     TH1 = 256 - (11059200/12/32)/baud;  //計算T1重載值
  17.     TL1 = TH1;     //初值等于重載值
  18.     ET1 = 0;       //禁止T1中斷
  19.     ES  = 1;       //使能串口中斷
  20.     TR1 = 1;       //啟動T1
  21. }
  22. /* 軟件延時函數(shù),延時時間(t*10)us */
  23. void DelayX10us(unsigned char t)
  24. {
  25.     do {
  26.         _nop_();
  27.         _nop_();
  28.         _nop_();
  29.         _nop_();
  30.         _nop_();
  31.         _nop_();
  32.         _nop_();
  33.         _nop_();
  34.     } while (--t);
  35. }
  36. /* 串口數(shù)據(jù)寫入,即串口發(fā)送函數(shù),buf-待發(fā)送數(shù)據(jù)的指針,len-指定的發(fā)送長度 */
  37. void UartWrite(unsigned char *buf, unsigned char len)
  38. {
  39.     RS485_DIR = 1;  //RS485設(shè)置為發(fā)送
  40.     while (len--)   //循環(huán)發(fā)送所有字節(jié)
  41.     {
  42.         flagTxd = 0;      //清零發(fā)送標志
  43.         SBUF = *buf++;    //發(fā)送一個字節(jié)數(shù)據(jù)
  44.         while (!flagTxd); //等待該字節(jié)發(fā)送完成
  45.     }
  46.     DelayX10us(5);  //等待最后的停止位完成,延時時間由波特率決定
  47.     RS485_DIR = 0;  //RS485設(shè)置為接收
  48. }
  49. /* 串口數(shù)據(jù)讀取函數(shù),buf-接收指針,len-指定的讀取長度,返回值-實際讀到的長度 */
  50. unsigned char UartRead(unsigned char *buf, unsigned char len)
  51. {
  52.     unsigned char i;

  53.     if (len > cntRxd)  //指定讀取長度大于實際接收到的數(shù)據(jù)長度時,
  54.     {                  //讀取長度設(shè)置為實際接收到的數(shù)據(jù)長度
  55.         len = cntRxd;
  56.     }
  57.     for (i=0; i<len; i++)  //拷貝接收到的數(shù)據(jù)到接收指針上
  58.     {
  59.         *buf++ = bufRxd[i];
  60.     }
  61.     cntRxd = 0;  //接收計數(shù)器清零

  62.     return len;  //返回實際讀取長度
  63. }
  64. /* 串口接收監(jiān)控,由空閑時間判定幀結(jié)束,需在定時中斷中調(diào)用,ms-定時間隔 */
  65. void UartRxMonitor(unsigned char ms)
  66. {
  67.     static unsigned char cntbkp = 0;
  68.     static unsigned char idletmr = 0;

  69.     if (cntRxd > 0)  //接收計數(shù)器大于零時,監(jiān)控總線空閑時間
  70.     {
  71.         if (cntbkp != cntRxd)  //接收計數(shù)器改變,即剛接收到數(shù)據(jù)時,清零空閑計時
  72.         {
  73.             cntbkp = cntRxd;
  74.             idletmr = 0;
  75.         }
  76.         else                   //接收計數(shù)器未改變,即總線空閑時,累積空閑時間
  77.         {
  78.             if (idletmr < 30)  //空閑計時小于30ms時,持續(xù)累加
  79.             {
  80.                 idletmr += ms;
  81.                 if (idletmr >= 30)  //空閑時間達到30ms時,即判定為一幀接收完畢
  82.                 {
  83.                     flagFrame = 1;  //設(shè)置幀接收完成標志
  84.                 }
  85.             }
  86.         }
  87.     }
  88.     else
  89.     {
  90.         cntbkp = 0;
  91.     }
  92. }
  93. /* 串口驅(qū)動函數(shù),監(jiān)測數(shù)據(jù)幀的接收,調(diào)度功能函數(shù),需在主循環(huán)中調(diào)用 */
  94. void UartDriver()
  95. {
  96.     unsigned char len;
  97.     unsigned char pdata buf[40];

  98.     if (flagFrame) //有命令到達時,讀取處理該命令
  99.     {
  100.         flagFrame = 0;
  101.         len = UartRead(buf, sizeof(buf)-2); //將接收到的命令讀取到緩沖區(qū)中
  102.         UartAction(buf, len);  //傳遞數(shù)據(jù)幀,調(diào)用動作執(zhí)行函數(shù)
  103.     }
  104. }
  105. /* 串口中斷服務(wù)函數(shù) */
  106. void InterruptUART() interrupt 4
  107. {
  108.     if (RI)  //接收到新字節(jié)
  109.     {
  110.         RI = 0;  //清零接收中斷標志位
  111.         if (cntRxd < sizeof(bufRxd)) //接收緩沖區(qū)尚未用完時,
  112.         {                            //保存接收字節(jié),并遞增計數(shù)器
  113.             bufRxd[cntRxd++] = SBUF;
  114.         }
  115.     }
  116.     if (TI)  //字節(jié)發(fā)送完畢
  117.     {
  118.         TI = 0;   //清零發(fā)送中斷標志位
  119.         flagTxd = 1;  //設(shè)置字節(jié)發(fā)送完成標志
  120.     }
  121. }

復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:161164 發(fā)表于 2022-2-19 15:17 | 只看該作者
因為Modbus的尾2Byte是CRC驗證用的
回復

使用道具 舉報

板凳
ID:1003077 發(fā)表于 2022-2-19 19:54 | 只看該作者
就是讀回來數(shù)據(jù)不做CRC校驗,2個字節(jié)不用
回復

使用道具 舉報

地板
ID:293363 發(fā)表于 2022-2-19 21:34 | 只看該作者
就是不對數(shù)據(jù)進行CRC校驗
回復

使用道具 舉報

5#
ID:1003226 發(fā)表于 2022-2-23 10:37 | 只看該作者
crc校驗的關(guān)系
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表