找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 13911|回復(fù): 30
打印 上一主題 下一主題
收起左側(cè)

基于RS485主從結(jié)構(gòu)通信單片機(jī)代碼和proteus仿真

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:206075 發(fā)表于 2017-5-30 15:31 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
RS485主從結(jié)構(gòu)通信代碼,用于組網(wǎng)內(nèi)部通信

proteus仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):



單片機(jī)源程序如下:
  1. #ifndef        _485MON_H                                 // 防止485Mon.h被重復(fù)引用
  2. #define        _485MON_H

  3. #include <reg52.h>                            // 引用標(biāo)準(zhǔn)庫的頭文件
  4. #include <stdio.h>
  5. #include <string.h>

  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. #define ACTIVE          0x11
  9. #define GETDATA          0x22
  10. #define READY                  0x33
  11. #define SENDDATA        0x44        

  12. #define RECFRMMAXLEN 16                 // 接收幀的最大長度,超過此值認(rèn)為幀超長錯誤
  13. #define STATUSMAXLEN 10                        // 設(shè)備狀態(tài)信息最大長度         

  14. uchar DevNo;                                        // 設(shè)備號
  15. xdata uchar StatusBuf[STATUSMAXLEN];

  16. //為簡化起見,假設(shè)了10位固定的采集數(shù)據(jù)
  17. #define DATA0          0x10
  18. #define DATA1          0x20
  19. #define DATA2          0x30
  20. #define DATA3          0x40
  21. #define DATA4          0x50
  22. #define DATA5          0x60
  23. #define DATA6          0x70
  24. #define DATA7          0x80
  25. #define DATA8          0x90
  26. #define DATA9          0xA0
  27. sbit DE = P1^6;                        //驅(qū)動器使能,1有效
  28. sbit RE = P1^7;                        //接收器使能,0有效
  29. void init();                                        // 系統(tǒng)初始化
  30. void Get_Stat();                                // 簡化的數(shù)據(jù)采集函數(shù)
  31. bit Recv_Data(uchar *type);                // 接收數(shù)據(jù)幀函數(shù)
  32. void Send(uchar m);                                        // 發(fā)送單字節(jié)數(shù)據(jù)
  33. void Send_Data(uchar type,uchar len,uchar *buf);                                // 發(fā)送數(shù)據(jù)幀函數(shù)        
  34. void Clr_StatusBuf();                        //  清除設(shè)備狀態(tài)信息緩沖區(qū)函數(shù)   
  35. /****************************************/
  36. /* Copyright (c) 2005, 通信工程學(xué)院     */
  37. /* All rights reserved.                 */
  38. /****************************************/

  39. #include "485Mon.h"
  40. void main(void)
  41. {
  42.         uchar type;

  43.         /* 初始化 */
  44.         init();
  45.         
  46.         while (1)
  47.         {
  48.                 if (Recv_Data(&type)==0)                        // 接收幀錯誤或者地址不符合,丟棄
  49.                         continue;
  50.                 switch (type)
  51.                 {
  52.                         case ACTIVE:                                // 主機(jī)詢問從機(jī)是否在位
  53.                                 Send_Data(READY,0,StatusBuf);        // 發(fā)送READY指令
  54.                                 break;
  55.                         case GETDATA:                                // 主機(jī)讀設(shè)備請求
  56.                                 Clr_StatusBuf();
  57.                                 Get_Stat();                                // 數(shù)據(jù)采集函數(shù)
  58.                                 Send_Data(SENDDATA,strlen(StatusBuf),StatusBuf);
  59.                                 break;
  60.                         default:
  61.                                 break;                                        // 指令類型錯誤,丟棄當(dāng)前幀
  62.                 }
  63.         }
  64. }

  65. /* 初始化 */
  66. void init(void)
  67. {
  68.         P1 = 0xff;
  69.         DevNo = (P1&0x00111111);                        // 讀取本機(jī)設(shè)備號

  70.         TMOD = 0x20;
  71.         SCON = 0x50;
  72.         TH1 = 0xfd;
  73.         TL1 = 0xfd;
  74.         TR1 = 1;
  75.         PCON = 0x00;                                                // SMOD=0
  76.         EA = 0;
  77.                                                 
  78. }

  79. /* 接收數(shù)據(jù)幀函數(shù),實際上接收的是主機(jī)的指令 */
  80. bit Recv_Data(uchar *type)
  81. {
  82.         uchar tmp,rCount,i;
  83.         uchar r_buf[RECFRMMAXLEN];                        // 保存接收到的幀
  84.         uchar Flag_RecvOver;                                // 一幀接收結(jié)束標(biāo)志        
  85.         uchar Flag_StartRec;                                // 一幀開始接收標(biāo)志
  86.         uchar CheckSum;                                                // 校驗和
  87.         uchar DataLen;                                                // 數(shù)據(jù)字節(jié)長度變量
  88.                
  89.         /* 禁止發(fā)送,允許接收 */
  90.         DE = 0;
  91.         RE = 0;

  92.         /* 接收一幀數(shù)據(jù) */
  93.         rCount = 0;
  94.         Flag_StartRec = 0;
  95.     Flag_RecvOver = 0;
  96.         while (!Flag_RecvOver)
  97.         {
  98.                 RI = 0;
  99.                 while (!RI);
  100.                 tmp = SBUF;
  101.                 RI=0;

  102.                 /* 判斷是否收到字符',其數(shù)值為0x24 */         
  103.                 if ((!Flag_StartRec) && (tmp == 0x24))
  104.                 {
  105.                         Flag_StartRec = 1;        
  106.                 }

  107.                 if (Flag_StartRec)
  108.                 {
  109.                         r_buf[rCount] = tmp;
  110.                         rCount ++;               
  111.                         
  112.                         /* 判斷是否收到字符'*',其數(shù)值為0x2A,根據(jù)接收的指令設(shè)置相應(yīng)標(biāo)志位 */
  113.                         if (tmp == 0x2A)
  114.                                 Flag_RecvOver = 1;
  115.                 }

  116.                 if (rCount == RECFRMMAXLEN)                // 幀超長錯誤,返回0
  117.                         return 0;
  118.         }
  119.         
  120.         /* 計算校驗和字節(jié) */
  121.         CheckSum = 0;
  122.         DataLen = r_buf[3];
  123.         for (i=0;i++;i<3+DataLen)
  124.         {
  125.                 CheckSum = CheckSum + r_buf[i+1];
  126.         }
  127.         
  128.         /* 判斷幀是否錯誤 */
  129.         if (rCount<6)                                                // 幀過短錯誤,返回0,最短的指令幀為6個字節(jié)                                                
  130.                 return 0;
  131.         if (r_buf[1]!=DevNo)                                  // 地址不符合,錯誤,返回0
  132.                 return 0;
  133.         if (r_buf[rCount-2]!=CheckSum)                // 校驗錯誤,返回0
  134.             return 0;

  135.         *type = r_buf[2];                                        // 獲取指令類型

  136.         return 1;                                                        // 成功,返回1
  137. }

  138. /* 發(fā)送數(shù)據(jù)幀函數(shù) */
  139. void Send_Data(uchar type,uchar len,uchar *buf)
  140. {
  141.         uchar i,tmp;
  142.         uchar CheckSum = 0;
  143.         
  144.         /* 允許發(fā)送,禁止接收 */
  145.         DE = 1;
  146.         RE = 1;
  147.         
  148.         /* 發(fā)送幀起始字節(jié) */
  149.         tmp = 0x24;
  150.         Send(tmp);
  151.         
  152.         Send(DevNo);                                                // 發(fā)送地址字節(jié),也即設(shè)備號
  153.         CheckSum = CheckSum + DevNo;

  154.         Send(type);                                                        // 發(fā)送類型字節(jié)
  155.         CheckSum = CheckSum + type;

  156.         Send(len);                                                        // 發(fā)送數(shù)據(jù)長度字節(jié)
  157.         CheckSum = CheckSum + len;

  158.         /* 發(fā)送數(shù)據(jù) */
  159.         for (i=0;i<len;i++)                        
  160.         {
  161.                 Send(*buf);
  162.                 CheckSum = CheckSum + *buf;
  163.                 buf++;
  164.         }
  165.         
  166.         Send(CheckSum);                                                // 發(fā)送校驗和字節(jié)

  167.         /* 發(fā)送幀結(jié)束字節(jié) */
  168.         tmp = 0x2A;
  169.         Send(tmp);
  170. }

  171. /* 采集數(shù)據(jù)函數(shù)經(jīng)過簡化處理,取固定的10個字節(jié)數(shù)據(jù) */
  172. void Get_Stat(void)
  173. {
  174.         StatusBuf[0]=DATA0;
  175.         StatusBuf[1]=DATA1;
  176.         StatusBuf[2]=DATA2;
  177.         StatusBuf[3]=DATA3;
  178. ……………………

  179. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
RS485通信程序.rar (72.5 KB, 下載次數(shù): 676)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂4 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:72951 發(fā)表于 2017-10-25 08:25 | 只看該作者
謝謝樓主分享
回復(fù)

使用道具 舉報

板凳
ID:96474 發(fā)表于 2017-11-7 13:07 | 只看該作者
謝謝樓主,正需要呢
回復(fù)

使用道具 舉報

地板
ID:284987 發(fā)表于 2018-2-23 15:27 | 只看該作者
謝謝樓主分享,借鑒下。
回復(fù)

使用道具 舉報

5#
ID:282795 發(fā)表于 2018-4-4 11:13 | 只看該作者
謝謝樓主。借鑒中。。。
回復(fù)

使用道具 舉報

6#
ID:47652 發(fā)表于 2018-4-9 10:33 | 只看該作者
謝謝分享!
回復(fù)

使用道具 舉報

7#
ID:47652 發(fā)表于 2018-4-9 10:33 | 只看該作者
謝謝分享!
回復(fù)

使用道具 舉報

8#
ID:308735 發(fā)表于 2018-4-16 09:26 | 只看該作者
這個是如何使用的?
回復(fù)

使用道具 舉報

9#
ID:365727 發(fā)表于 2018-7-5 20:05 | 只看該作者
謝謝樓主了哈~
回復(fù)

使用道具 舉報

10#
ID:301544 發(fā)表于 2018-7-5 21:50 | 只看該作者
缺少頭文件啊,樓主
回復(fù)

使用道具 舉報

11#
ID:369814 發(fā)表于 2018-7-17 12:31 | 只看該作者
厲害厲害
回復(fù)

使用道具 舉報

12#
ID:66287 發(fā)表于 2018-7-20 10:08 | 只看該作者
好東東,謝謝分享!
回復(fù)

使用道具 舉報

13#
ID:196319 發(fā)表于 2018-9-29 10:00 | 只看該作者
正好項目用到,幫助很大
回復(fù)

使用道具 舉報

14#
ID:407357 發(fā)表于 2018-10-10 09:08 | 只看該作者
很受益,挺好,
回復(fù)

使用道具 舉報

15#
ID:407021 發(fā)表于 2018-10-10 10:46 | 只看該作者
謝謝樓主,學(xué)習(xí)中
回復(fù)

使用道具 舉報

16#
ID:407378 發(fā)表于 2018-10-10 10:46 | 只看該作者
謝謝樓主~~!
回復(fù)

使用道具 舉報

17#
ID:407378 發(fā)表于 2018-10-10 10:54 | 只看該作者
謝謝樓主分享,借鑒下。
回復(fù)

使用道具 舉報

18#
ID:409168 發(fā)表于 2018-11-9 16:21 | 只看該作者
正需要,謝謝樓主
回復(fù)

使用道具 舉報

19#
ID:224177 發(fā)表于 2018-12-18 22:37 | 只看該作者
樓主,請問下,這個是兩個單片機(jī)之間進(jìn)行通訊嗎?想設(shè)計一塊單片機(jī)走modbus協(xié)議和工控屏通訊,請問proteus中圖應(yīng)該怎么改進(jìn)
回復(fù)

使用道具 舉報

20#
ID:350791 發(fā)表于 2019-1-14 14:19 | 只看該作者
樓主怎樣實現(xiàn)的
回復(fù)

使用道具 舉報

21#
ID:151749 發(fā)表于 2019-1-28 00:48 | 只看該作者
好,謝謝提供!
回復(fù)

使用道具 舉報

22#
ID:507538 發(fā)表于 2019-4-9 08:55 | 只看該作者
謝謝提供
回復(fù)

使用道具 舉報

23#
ID:505762 發(fā)表于 2019-4-13 19:22 | 只看該作者
謝謝分享,感謝
回復(fù)

使用道具 舉報

24#
ID:563476 發(fā)表于 2019-6-16 10:54 | 只看該作者
怎么輸入不了
回復(fù)

使用道具 舉報

25#
ID:563476 發(fā)表于 2019-6-16 10:55 | 只看該作者
tik8436 發(fā)表于 2017-11-7 13:07
謝謝樓主,正需要呢

怎么在軟件上操作啊
回復(fù)

使用道具 舉報

26#
ID:155141 發(fā)表于 2020-2-2 14:18 | 只看該作者
厲害了。能夠完美仿真485,傳輸字符串無壓力。
有點可惜不能傳輸中文。
回復(fù)

使用道具 舉報

27#
ID:155141 發(fā)表于 2020-2-2 14:24 | 只看該作者
缺少的頭文件不影響功能,厲害了,樓主
回復(fù)

使用道具 舉報

28#
ID:308785 發(fā)表于 2020-2-28 15:07 | 只看該作者
寫寫分享 我可以借鑒一下思想了
回復(fù)

使用道具 舉報

29#
ID:748018 發(fā)表于 2020-5-26 10:20 來自手機(jī) | 只看該作者
謝謝樓主
回復(fù)

使用道具 舉報

30#
ID:122089 發(fā)表于 2020-8-15 10:58 | 只看該作者
有多從機(jī)的仿真嗎?
回復(fù)

使用道具 舉報

31#
ID:903594 發(fā)表于 2021-4-14 21:43 | 只看該作者
怎么實現(xiàn)的呀,實驗現(xiàn)象是什么

回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表