日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于Modbus/TCP的西门子1200PLC和STM32通信

發(fā)布時間:2023/12/10 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Modbus/TCP的西门子1200PLC和STM32通信 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.前言
對于工控而言,有時候會需要和單片機(jī)進(jìn)行通信,最近就測試了一下市面上常見的西門子PLC和STM32F103VET6的單片機(jī)進(jìn)行通信。
2.硬件架構(gòu)
STM32+W5500+ModbusTCP+西門子1200PLC 中間需要交換機(jī)來互聯(lián)網(wǎng)口
首先通信是要基于協(xié)議的,對于單片機(jī)和PLC而言之間的通信協(xié)議可以有很多,串口232,485,ModbusRTU/TCP等等。現(xiàn)在工控都是組網(wǎng)時代了,ModbusTCP作為一款開源的協(xié)議資料也很多便于第三方移植。
PLC端現(xiàn)在大多數(shù)支持網(wǎng)口,西門子1200,1500系列PLC自帶網(wǎng)口,支持Modbus協(xié)議,通信起來也方便一些。
單片機(jī)端選擇需要帶網(wǎng)口,我用的是野火指南者開發(fā)板,本身自己沒有帶網(wǎng)口,但是現(xiàn)在以太網(wǎng)模塊很多,這里選擇W5500的以太網(wǎng)模塊來實現(xiàn)組網(wǎng)。W5500可以實現(xiàn)基于硬件的TCP/IP協(xié)議,可以避免解析復(fù)雜的TCP/IP協(xié)議,例程也多方便移植。其實本質(zhì)就是基于W5500模塊的ModbusTCP移植。這部分有很多參考資料,主要參考這篇文章,十分感謝https://blog.csdn.net/jordan20052009/article/details/46967451?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160744407419726891153872%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160744407419726891153872&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-25-46967451.pc_search_result_cache&utm_term=freemodbus%20tcp
3.移植分析
需要理解Modbus協(xié)議的相關(guān)內(nèi)容,W5500的使用,PLC端主站的建立。
其實分3大塊:
1.Modbus協(xié)議源碼移植
2.W5500TCP/IP移植
3.PLC端主站代碼的編寫
熟悉PLC的朋友應(yīng)該知道,第3點其實不難,而且是在PLC里面寫跟單片機(jī)其實沒有太大關(guān)系,實際上在單片機(jī)跑通之后,就可以用Modbus scan32一類的工具去測試連接了,只要調(diào)試助手能讀取成功就證明單片機(jī)端代碼沒有問題。
那就只剩下第1,2點。我是這么做的,先單獨完成Modbus RTU的移植,這樣可以方便了解Modbus協(xié)議的工作原理,再單獨完成W5500TCP/IP的協(xié)議移植這樣可以理解W5500的使用方法,最后再兩者結(jié)合,就可以實現(xiàn)。不了解的同學(xué)可以嘗試分步實現(xiàn)。一定要理解Modbus 因為我們就是在W5500的函數(shù)基礎(chǔ)上添加Modbus內(nèi)容。TCP/IP實現(xiàn)底層的收發(fā),Modbus再對其進(jìn)行處理。
4.移植流程
1.W5500可以直接參考官方的例程,下面是main函數(shù)

在這里插入代碼片int main( void ) {eMBErrorCode eStatus; systick_init(72); // 初始化滴答定時器USART1_Config(); // 初始化USART1:115200@8-N-1 reset_break_gpio_init(); // 復(fù)位與中斷管腳初始化spi_gpio_init(); // SPI管腳初始化spiinitailize(); // SPI配置初始化printf("\r\n 煒世科技--WIZnet W5500官方代理商。全程技術(shù)支持,價格優(yōu)勢大!\r\n\r\n");reset_w5500(); // w5500硬件復(fù)位 PHY_check(); // 網(wǎng)線檢測程序set_w5500_mac(); // 設(shè)置w5500MAC地址set_w5500_netinfo(); // 設(shè)置w5500網(wǎng)絡(luò)參數(shù)socket_buf_init(txsize, rxsize); // 初始化4個Socket的發(fā)送接收緩存大小printf("\r\n W5500為TCP Server,建立偵聽。等待PC作為TCP Client建立連接。\r\n");printf(" TCP Server IP:%d.%d.%d.%d。\r\n",remote_ip[0],remote_ip[1],remote_ip[2],remote_ip[3]);printf(" TCP Server Port:%d。\r\n",remote_port);printf(" 正常現(xiàn)象:連接成功,TCP Client發(fā)送數(shù)據(jù)給W5500,W5500將返回對應(yīng)數(shù)據(jù)。\r\n");eStatus = eMBTCPInit( 2 ); //Modbus相關(guān)TCP初始化eStatus =eMBEnable(); //Modbus協(xié)議棧使能 while(1){ modbus_tcps(); //主函數(shù)} }

這其實是官方的例程,Modbus是后添加的,while中的循環(huán)函數(shù)我也進(jìn)行了修改,是跟Modbus相關(guān)的。其實執(zhí)行到最后一條Prtinf語句后,W5500就已經(jīng)配置完成了,已經(jīng)可以ping通了,這就可以證明W5500運轉(zhuǎn)正常了,之后再去做下一步動作。官方的例程基本不需要修改,拿來直接用就可以,只是SPI部分的硬件接線要根據(jù)自己實際板子來修改部分代碼。關(guān)于W5500可以參考官網(wǎng)的教程和網(wǎng)絡(luò)資料也比較多,這里不多說。說一下IP地址

/*MAC地址首字節(jié)必須為偶數(shù)如果多塊w5500網(wǎng)絡(luò)適配板在同一現(xiàn)場工作,請使用不同的MAC地址 */ uint8 mac[6]={0x00,0x08,0xdc,0x11,0x11,0x11};/*定義默認(rèn)IP信息*/ uint8 local_ip[4] = {192,168,1,8}; // 定義w5500默認(rèn)IP地址 uint8 subnet[4] = {255,255,255,0}; // 定義w5500默認(rèn)子網(wǎng)掩碼 uint8 gateway[4] = {192,168,1,1}; // 定義w5500默認(rèn)網(wǎng)關(guān) uint8 dns_server[4] = {114,114,114,114}; // 定義w5500默認(rèn)DNSuint16 local_port = 502; // 定義本地端口

注意單片機(jī)IP要和本地PLC在同一網(wǎng)段。端口號要和PLC端一致,常用502.
mac地址如果是多設(shè)備注意不要重復(fù)。下面是while中的函數(shù)。和RTU不同,TCP是一直處在監(jiān)聽狀態(tài),一旦建立了連接就會一直查詢,檢測到數(shù)據(jù)長度ucTCPRequestLen>0就開始接受數(shù)據(jù),接受到數(shù)據(jù)之后,再驅(qū)動empoll函數(shù)即可 進(jìn)入到Modbus的內(nèi)部處理流程,處理完了再通過send函數(shù)發(fā)送出去。Send和recv都是W5500的庫函數(shù)。

void modbus_tcps(void) { uint16 len=0; switch(getSn_SR(SOCK_TCPS)) // 獲取socket的狀態(tài){case SOCK_CLOSED: // socket處于關(guān)閉狀態(tài)socket(SOCK_TCPS ,Sn_MR_TCP,local_port,Sn_MR_ND); // 打開socketbreak; case SOCK_INIT: // socket已初始化狀態(tài)listen(SOCK_TCPS); // socket建立監(jiān)聽break;case SOCK_ESTABLISHED: // socket處于連接建立狀態(tài)if(getSn_IR(SOCK_TCPS) & Sn_IR_CON){setSn_IR(SOCK_TCPS, Sn_IR_CON); // 清除接收中斷標(biāo)志位}ucTCPRequestLen=getSn_RX_RSR(SOCK_TCPS); // 定義len為已接收數(shù)據(jù)的長度if(ucTCPRequestLen>0){recv(SOCK_TCPS,ucTCPRequestFrame, ucTCPRequestLen); //W5500接收數(shù)據(jù)xMBPortEventPost(EV_FRAME_RECEIVED); //發(fā)送EV_FRAME_RECEIVED事件,以驅(qū)動eMBpoll()函數(shù)中的狀態(tài)機(jī)eMBPoll(); //處理EV_FRAME_RECEIVED事件eMBPoll(); //處理EV_EXECUTE事件if(bFrameSent) { bFrameSent = FALSE; //W5500發(fā)送Modbus應(yīng)答數(shù)據(jù)包 send(SOCK_TCPS,ucTCPResponseFrame,ucTCPResponseLen);} }break;case SOCK_CLOSE_WAIT: // socket處于等待關(guān)閉狀態(tài)disconnect(SOCK_TCPS); // 斷開當(dāng)前TCP連接close(SOCK_TCPS); // 關(guān)閉當(dāng)前所使用socketbreak;} }

其實如果完全不了解Modbus協(xié)議的話,移植起來還是比較困難,建議一定要了解一些之后再移植,可以先做ModbusRTU的移植。

總結(jié)

以上是生活随笔為你收集整理的基于Modbus/TCP的西门子1200PLC和STM32通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。