找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

rs485 16路繼電器控制板 仿modbus通信協(xié)議控制有上下位機(jī)程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主

Modbus十六路繼電器輸出控制板

一、應(yīng)用場(chǎng)合

  • 工業(yè)控制需要擴(kuò)展輸出口的場(chǎng)合
  • PLC輸出接口擴(kuò)展
  • 組態(tài)觸摸屏控制
  • 簡(jiǎn)要說(shuō)明
  • 尺寸:長(zhǎng)152mmX163mmX25mm
  • 通訊協(xié)議:MODBUS_RTU模式
  • 工作電壓:直流12(另有24V)
  • 掉電后保存繼電器狀態(tài)
  • 有看門(mén)狗復(fù)位功能
、特點(diǎn)
  • RS485標(biāo)準(zhǔn)接口
  • 16路輸出光隔離控制繼電器
  • 標(biāo)準(zhǔn)11.0592M晶振,9600波特率、八位數(shù)據(jù)位、一位停止位、一位校驗(yàn)位(偶校驗(yàn))
  • 上電復(fù)位和手動(dòng)復(fù)位。
  • MODBUS_RTU標(biāo)準(zhǔn)協(xié)議控制
  • 輸出16繼電器LED指示。
  • 通過(guò)軟件指令設(shè)定地址等參數(shù)
  • 可控制交流220V/10A下設(shè)備
  • 有程序下載口,可隨意更改程序。
  • 可按客戶要求定制協(xié)議

注:顧客可以根據(jù)需要選擇相應(yīng)的產(chǎn)品,我們公司有兩路開(kāi)關(guān)量2路輸入輸出、4路開(kāi)關(guān)量輸入輸出、8路開(kāi)關(guān)量輸入輸出、8路模擬量輸入4路開(kāi)關(guān)量輸出、15路開(kāi)關(guān)量輸入輸出、30路輸入輸出等繼電器控制板,有需要請(qǐng)聯(lián)系我們,選擇您滿意的產(chǎn)品!

四、工作環(huán)境

  • 工作環(huán)境溫度:-20℃~65℃
  • 相對(duì)濕度:95%(無(wú)凝結(jié))

五、引腳描述

名稱

描述

名稱

描述

VCC

12V電源正極

OUT7

第七路繼電器公共端和常開(kāi)端

GND

電源負(fù)極

OUT8

第八路繼電器公共端和常開(kāi)端

A+

RS485數(shù)據(jù)A+

OUT9

第九路繼電器公共端和常開(kāi)端

B-

RS485數(shù)據(jù)B-

OUT10

第十路繼電器公共端和常開(kāi)端

OUT1

第一路繼電器公共端和常開(kāi)端

OUT11

第十一路繼電器公共端和常開(kāi)端

OUT2

第二路繼電器公共端和常開(kāi)端

OUT12

第十二路繼電器公共端和常開(kāi)端

OUT3

第三路繼電器公共端和常開(kāi)端

OUT13

第十三路繼電器公共端和常開(kāi)端

OUT4

第四路繼電器公共端和常開(kāi)端

OUT14

第十四路繼電器公共端和常開(kāi)端

OUT5

第五路繼電器公共端和常開(kāi)端

OUT15

第十五路繼電器公共端和常開(kāi)端

OUT6

第六路繼電器公共端和常開(kāi)端

OUT16

第十六路繼電器公共端和常開(kāi)端

五、硬件連接

  • 電源的連接

  • RS485的連接

注:RS485建議采用雙絞線連接,采用帶屏蔽的雙絞線連接,并將屏蔽層接地,總線上掛多個(gè)模塊時(shí),采用手拉手不的連接方式。

  • 繼電器輸出的連接

六、軟件協(xié)議

6.1串口通信定義

  • 串口波特率:1位起始位、8位數(shù)據(jù)位 、1位停止位 、偶校驗(yàn)
  • 默認(rèn)地址:0x01
  • 通訊接口:RS485

6.1指令功能表

功能

從機(jī)地址

0x01~0xff

命令

寄存器地址

高字節(jié)、低字節(jié)

數(shù)據(jù)域

CRC校驗(yàn)

高低字節(jié)

長(zhǎng)度

1個(gè)字節(jié)

1個(gè)字節(jié)

2個(gè)字節(jié)

2個(gè)字節(jié)

讀取繼電器狀態(tài)

Addr

0x02

0x0001

高字節(jié):0x00

低字節(jié):0x0f(16個(gè)繼電器狀態(tài))

CRCH

CRCL

控制多路繼電器

Addr

0x0F

0x0000~0x000f

繼電器個(gè)數(shù)

高:0x00

低:0x01~0x0f

字節(jié)個(gè)數(shù)

(1個(gè)字節(jié))

0x01~0x02

數(shù)據(jù)域

對(duì)應(yīng)位為1:開(kāi)

對(duì)應(yīng)位為0:關(guān)

CRCH

CRCL

控制單個(gè)繼電器

Addr

0x05

0x0000~0x000f

高:0xff  低:0x00 吸合

高:0x00 低:0x00 斷開(kāi)

CRCH

CRCL

設(shè)定模塊地址

Addr

0x06

0x0010

要修改的地址兩個(gè)字節(jié)

CRCH

CRCL

6.2指令示例及詳解

  • 讀取16路繼電器狀態(tài)(地址0x01

地址

功能

繼電器起始地址

讀取個(gè)數(shù)

CRC校驗(yàn)

0x01

0x02

高:0x00

低:0x01

高:0x00

低:0x0F

0x69

0xCE

從機(jī)回應(yīng)

地址

功能

字節(jié)數(shù)

返回繼電器狀態(tài)

CRC校驗(yàn)

0x01

0x02

0x02

高:0x00

低:0x00

0xB9

0xB8

注:返回的十六路狀態(tài)0為斷開(kāi),1為吸合

  • 控制多路繼電器

a.控制所有繼電器全開(kāi)主機(jī)發(fā)送:

地址

功能

繼電器起始地址

控制繼電器個(gè)數(shù)

字節(jié)個(gè)數(shù)

數(shù)據(jù)域

CRC校驗(yàn)

0x01

0x0F

高:0x00

低:0x00

高:0x00

低:0x0F

0x02

0xff 0xff

0xE4

0x44

從機(jī)回應(yīng):

地址

功能

繼電器起始地址

控制繼電器個(gè)數(shù)

CRC校驗(yàn)

0x01

0x0F

高:0x00

低:0x00

高:0x00

低:0x0F

0x15

0xCF

注:控制多路時(shí)數(shù)據(jù)域中二進(jìn)制數(shù)對(duì)應(yīng)位為1是打開(kāi)某一路繼電器,為0關(guān)閉某一路繼電器

b控制所有繼電器全關(guān)主機(jī)發(fā)送:

地址

功能

繼電器起始地址

控制繼電器個(gè)數(shù)

字節(jié)個(gè)數(shù)

數(shù)據(jù)域

CRC校驗(yàn)

0x01

0x0F

高:0x00

低:0x00

高:0x00

低:0x0F

0x02

0x00 x00

0xE5

0xF4

從機(jī)回應(yīng):

地址

功能

繼電器起始地址

控制繼電器個(gè)數(shù)

CRC校驗(yàn)

0x01

0x0F

高:0x00

低:0x00

高:0x00

低:0x0F

0x15

0xCF

注:控制多路時(shí)數(shù)據(jù)域中二進(jìn)制數(shù)對(duì)應(yīng)位為1是打開(kāi)某一路繼電器,為0關(guān)閉某一路繼電器

  • 控制單個(gè)繼電器狀態(tài)

控制第一路繼電器開(kāi)主機(jī)發(fā)送:

地址

功能

繼電器地址

打開(kāi)繼電器

CRC校驗(yàn)

0x01

0x05

高:0x00

低:0x00

高:0xFF

低:0x00

0x8C

0x3A

從機(jī)回應(yīng):

地址

功能

繼電器地址

打開(kāi)繼電器

CRC校驗(yàn)

0x01

0x05

高:0x00

低:0x00

高:0xFF

低:0x00

0x8C

0x3A


控制第一路繼電器關(guān)主機(jī)發(fā)送:

地址

功能

繼電器地址

打開(kāi)繼電器

CRC校驗(yàn)

0x01

0x05

高:0x00

低:0x00

高:0x00

低:0x00

0xCD

0xCA

從機(jī)回應(yīng):

地址

功能

繼電器地址

打開(kāi)繼電器

CRC校驗(yàn)

0x01

0x05

高:0x00

低:0x00

高:0x00

低:0x00

0xCD

0xCA

6.3上位機(jī)測(cè)試軟件

上位機(jī)簡(jiǎn)介

  • 上位機(jī)編譯環(huán)境:vs2008.net
  • 使用語(yǔ)言是vb.net
  • 使用該軟件需要安裝framwork3.5軟件(一般win7系統(tǒng)都已安裝)
  • 打開(kāi)該軟件前請(qǐng)先把數(shù)據(jù)線和控制板連接好,控制板供電

上位機(jī)軟件可控制七個(gè)十六路繼電器輸出控制板,如要需要控制更多從機(jī)設(shè)備,需要更改上位機(jī)軟件,

產(chǎn)品展示

附錄:


單片機(jī)源程序如下:
  1. /********************************************************************
  2.                             匯誠(chéng)科技
  3. 實(shí)現(xiàn)功能:串口控制繼電器程序
  4. 使用芯片:AT89S52
  5. 晶振:11.0592MHZ
  6. 波特率:9600
  7. 編譯環(huán)境:Keil
  8. 【聲明】此程序僅用于學(xué)習(xí)與參考,引用請(qǐng)注明版權(quán)和作者信息!
  9. *********************************************************************/
  10. #include<reg52.h>                 //庫(kù)文件
  11. #include <intrins.H>
  12. #include<EEPROM.h>
  13. #define uchar unsigned char//宏定義無(wú)符號(hào)字符型
  14. sbit K1=P2^0;
  15. sbit K2=P2^1;
  16. sbit K3=P2^2;
  17. sbit K4=P2^3;
  18. sbit K5=P2^4;
  19. sbit K6=P2^5;
  20. sbit K7=P2^6;
  21. sbit K8=P2^7;
  22. sbit K9=P1^0;
  23. sbit K10=P1^1;
  24. sbit K11=P1^2;
  25. sbit K12=P1^3;
  26. sbit K13=P1^4;
  27. sbit K14=P1^5;
  28. sbit K15=P1^6;
  29. sbit K16=P1^7;

  30. sbit RS485_DIR=P3^7;
  31. uchar dat;
  32. uchar t,r,ii;
  33. uchar add;    //掉電保持485的地址
  34. uchar j=0;
  35. bit flag_zx=0;
  36. uchar sendBuf[10];          //發(fā)送緩沖區(qū)
  37. uchar receBuf[10];    //接收緩沖區(qū)
  38. bit busy;
  39. bit bz1=0;
  40. bit bz2=0;
  41. bit bz3=0;
  42. bit bz4=0;
  43. bit bz5=0;
  44. bit bz6=0;
  45. bit bz7=0;
  46. bit bz8=0;
  47. /********************************************************************
  48.                             延時(shí)函數(shù)
  49. *********************************************************************/
  50. void delay(uchar t)
  51. {
  52.   uchar i,j;
  53.    for(i=0;i<t;i++)
  54.    {
  55.             for(j=13;j>0;j--);
  56.          { ;
  57.          }
  58.    }
  59. }

  60. /********************************************************************
  61.               功能:串口初始化,波特率9600,方式1
  62. *********************************************************************/
  63. void Init_Com(void)
  64. {
  65. TMOD = 0x20;
  66. PCON = 0x00;
  67. SCON = 0x50;
  68. TH1 = 0xFd;
  69. TL1 = 0xFd;
  70. TR1 = 1;
  71. ES=1;
  72. EA=1;
  73. }

  74. /****************發(fā)送函數(shù)*********************/
  75. void senduart2()
  76. {          
  77. RS485_DIR=1;
  78. SBUF=sendBuf[0];while(!TI);TI=0;
  79. SBUF=sendBuf[1];while(!TI);TI=0;
  80. SBUF=sendBuf[2];while(!TI);TI=0;
  81. SBUF=sendBuf[3];while(!TI);TI=0;
  82. SBUF=sendBuf[4];while(!TI);TI=0;
  83. RS485_DIR=0;
  84. }
  85. /*****************清空發(fā)送緩沖區(qū)*************************/
  86. void clear_receBuf()
  87. {
  88.     uchar i;
  89.         for(i=0;i<5;i++)
  90.         {
  91.             receBuf[i]=0;
  92.         }
  93. }
  94. /********************************************************************
  95.                             主函數(shù)
  96. *********************************************************************/
  97. void main()
  98. {
  99. Init_Com();//串口初始化
  100. add = EEPROMReadByte(0);
  101. //add = 0X00;
  102.     P2=0XFF;
  103.         P1=0XFF;
  104.         RS485_DIR=0;
  105. while(1)
  106. {

  107. /********************************************************************
  108.                             接收數(shù)據(jù)判斷函數(shù)
  109. *********************************************************************/
  110. if(RI)  //如果有接收
  111.            {
  112.              RI=0; //接收標(biāo)志清零
  113.              receBuf[r++&0x0F]=SBUF;     //把接受的數(shù)據(jù)存儲(chǔ)到BUT數(shù)組中
  114.                  if(receBuf[0]!=0xaa){r=0;}
  115.                  if(r>=5)
  116.                  {        r=0;

  117.                     flag_zx=1;
  118.                  }
  119.            }
  120.            if(flag_zx==1)
  121.            {                     

  122.                 flag_zx=0;
  123.                     //0         1       2       3        4               
  124.                         //起始位   地址位  功能位   數(shù)據(jù)位  結(jié)束位
  125.                         if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add))          //如果開(kāi)始位和結(jié)束位,還有地址都正確,進(jìn)行下一步判斷
  126.                         {
  127.                            if(receBuf[2]==0x01)  //修改板子地址
  128.                            {
  129.                                 add=receBuf[3];
  130.                                         EEPROMSectorErase(0);//擦除扇區(qū)
  131.                                 EEPROMWriteByte(0,add);//寫(xiě)入新的地址
  132.                            }
  133.                            else if(receBuf[2]==0x02)  //打開(kāi)單路繼電器
  134.                            {
  135.                                        switch(receBuf[3])
  136.                                         {
  137.                                             case 0x01: K1=0; break;
  138.                                                 case 0x02: K2=0; break;
  139.                                             case 0x03: K3=0; break;
  140.                                                 case 0x04: K4=0; break;
  141.                                             case 0x05: K5=0; break;
  142.                                                 case 0x06: K6=0; break;
  143.                                             case 0x07: K7=0; break;
  144.                                                 case 0x08: K8=0; break;
  145.                                                 case 0x09: K9=0; break;
  146.                                                 case 0x0A: K10=0; break;
  147.                                             case 0x0B: K11=0; break;
  148.                                                 case 0x0C: K12=0; break;
  149.                                             case 0x0D: K13=0; break;
  150.                                                 case 0x0E: K14=0; break;
  151.                                             case 0x0F: K15=0; break;
  152.                                                 case 0x10: K16=0; break;
  153.                                                 default:break;
  154.                                         }
  155.                            }
  156.                            else if(receBuf[2]==0x03)  //關(guān)閉單路繼電器
  157.                            {
  158.                                        switch(receBuf[3])
  159.                                         {
  160.                                             case 0x01: K1=1; break;
  161.                                                 case 0x02: K2=1; break;
  162.                                             case 0x03: K3=1; break;
  163.                                                 case 0x04: K4=1; break;
  164.                                             case 0x05: K5=1; break;
  165.                                                 case 0x06: K6=1; break;
  166.                                             case 0x07: K7=1; break;
  167.                                                 case 0x08: K8=1; break;
  168.                                               case 0x09: K9=1; break;
  169.                                                 case 0x0A: K10=1; break;
  170.                                             case 0x0B: K11=1; break;
  171.                                                 case 0x0C: K12=1; break;
  172.                                             case 0x0D: K13=1; break;
  173.                                                 case 0x0E: K14=1; break;
  174.                                             case 0x0F: K15=1; break;
  175.                                                 case 0x10: K16=1; break;
  176.                                                 default:break;
  177.                                         }                       
  178.                            }
  179.                            else if(receBuf[2]==0x04)  //打開(kāi)全部繼電器
  180.                            {
  181.                                 if(receBuf[3]==0xff)
  182.                                 {
  183.                                             P2=0X00;
  184.                                             P1=0X00;
  185.                                         }  
  186.                            }
  187.                            else if(receBuf[2]==0x05)  //關(guān)閉全部繼電器
  188.                            {
  189.                                 if(receBuf[3]==0x00)
  190.                                 {
  191.                                             P2=0XFF;
  192.                                                 P1=0XFF;
  193.                                         }                       
  194.                            }
  195.                            else if(receBuf[2]==0x06)  //查詢繼電器
  196.                            {
  197.                                         sendBuf[0]=0xaa;
  198.                                         sendBuf[1]=add;
  199.                                         sendBuf[2]=0x07;
  200.                                         //sendBuf[3]=0xfe;
  201.                                         sendBuf[4]=0xbb;       
  202.                                switch(receBuf[3])
  203.                                    {
  204.                                        case 0x01: if(K1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  205.                                            case 0x02: if(K2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  206.                                        case 0x03: if(K3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  207.                                            case 0x04: if(K4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  208.                                        case 0x05: if(K5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  209.                                            case 0x06: if(K6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  210.                                        case 0x07: if(K7==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  211.                                            case 0x08: if(K8==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  212.                                        case 0x09: if(K9==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  213.                                            case 0x0A: if(K10==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  214.                                        case 0x0B: if(K11==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  215.                                            case 0x0C: if(K12==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  216.                                        case 0x0D: if(K13==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  217.                                            case 0x0E: if(K14==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  218.                                        case 0x0F: if(K15==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  219.                                            case 0x10: if(K16==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
  220.                                            default:break;
  221.                                    }  
  222.                                    senduart2();
  223.                            }
  224.                            else if(receBuf[2]==0x08)  //查詢輸入
  225.                            {
  226.                                         sendBuf[0]=0xaa;
  227.                                         sendBuf[1]=add;
  228.                                         sendBuf[2]=0x09;
  229.                                         //sendBuf[3]=0xfe;
  230.                                         sendBuf[4]=0xbb;
  231.                                
  232.                                switch(receBuf[3])
  233.                                    {
  234.                                        case 0x01: sendBuf[3]=0xFF;break;

  235.                                            default:break;
  236.                                    }  
  237.                                         senduart2();
  238.                            }                          
  239.                         }
  240. ……………………

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


所有資料51hei提供下載:
該板配套參考程序.rar (141.45 KB, 下載次數(shù): 263)
仿modbus通信協(xié)議控制.rar (47.45 KB, 下載次數(shù): 233)
modbus上下位機(jī)程序.rar (857.01 KB, 下載次數(shù): 261)
使用手冊(cè).docx (2.25 MB, 下載次數(shù): 193)


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

使用道具 舉報(bào)

沙發(fā)
ID:47652 發(fā)表于 2018-4-9 10:44 | 只看該作者
不錯(cuò),收藏,謝謝LZ
回復(fù)

使用道具 舉報(bào)

板凳
ID:322178 發(fā)表于 2018-5-8 17:10 | 只看該作者
學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

地板
ID:147570 發(fā)表于 2018-7-28 22:57 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

5#
ID:607314 發(fā)表于 2019-9-4 18:58 | 只看該作者
有l(wèi)abview程序嗎
回復(fù)

使用道具 舉報(bào)

6#
ID:503472 發(fā)表于 2019-9-6 10:36 | 只看該作者
信息量很大
回復(fù)

使用道具 舉報(bào)

7#
ID:57896 發(fā)表于 2019-9-7 10:03 | 只看該作者
非常好的modbus資料,收藏了
回復(fù)

使用道具 舉報(bào)

8#
ID:428400 發(fā)表于 2019-9-17 19:39 | 只看該作者
這個(gè)連不了觸摸屏的
回復(fù)

使用道具 舉報(bào)

9#
ID:821299 發(fā)表于 2020-9-20 23:22 | 只看該作者
非常實(shí)用的資料。
回復(fù)

使用道具 舉報(bào)

10#
ID:795427 發(fā)表于 2020-9-21 10:00 來(lái)自手機(jī) | 只看該作者
沒(méi)有物料清單
回復(fù)

使用道具 舉報(bào)

11#
ID:97678 發(fā)表于 2020-9-21 15:04 | 只看該作者
好東西! 能不能提供原理圖 和PCB文件?
回復(fù)

使用道具 舉報(bào)

12#
ID:315554 發(fā)表于 2020-9-26 11:20 | 只看該作者
謝謝分享,很好的資料,modbus慢慢學(xué)了,
回復(fù)

使用道具 舉報(bào)

13#
ID:361341 發(fā)表于 2020-11-6 10:37 | 只看該作者
好東西謝謝分享
回復(fù)

使用道具 舉報(bào)

14#
ID:811405 發(fā)表于 2020-11-17 15:33 | 只看該作者
收藏,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

15#
ID:1108581 發(fā)表于 2024-1-20 20:15 | 只看該作者
感謝大佬分享資源,剛好想學(xué)習(xí)下這個(gè),就是不知道文件里面有沒(méi)有提供原理圖和PCB文件之類的
回復(fù)

使用道具 舉報(bào)

16#
ID:228452 發(fā)表于 2024-1-21 06:23 | 只看該作者
schematics and PCB files are not included ...
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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