1. 程式人生 > >單片機MODBUS通信源代碼

單片機MODBUS通信源代碼

完整 取數據 間隔 ssi 觸摸 註意 包含 電路 0ms

好久沒有寫些什麽了,最近在出差也沒做關於Linux的東西。由於是做自動化的因此最近做了一塊單片機的板子要作為MODBUS從站來與上面的觸摸屏進行顯示功能還不是很完善但是MODBUS功能的模塊程序已經寫好經過測試基本可以用。 具體要求是下面有2個AI和4個DO量需要檢測和控制,我使用的是90C52單片機模擬量采集部分用的OP07的放大器電路,這裏就不詳細說明了(有需要的可以留言,有圖紙),最麻煩的就是MODBUS通訊部分。 一開始我根據MODBUS標準協議規定來做了程序但是不能通訊經過總結主要問題出在二個地方 第一:crc校驗計算不正確 第二:發送的程序太大導致發送時間過長主站端認為超時(我自己認為的原因)

經過仔細研究發現CRC校驗的程序我根本寫不出來也理解不了網絡上有很多現成的可以直接拿來來用就很好了,經過精簡程序是可以進行通信了但是還有一個很重要的問題是超時判斷的問題一直沒能處理所以進行了以下時間問題的總結
Modbus字符與數據幀間隔時間問題
1、MODBS協議中的規定如下
在RTU模式,報文有時間長至少3.5個字符時間的空間間隔區分如下圖

整個報文必須以連續的字符流發送,如果兩個字符之間的空閑大於1.5個字符時間,則報文幀認為不完整,應該被接收點丟棄。

需要註意的是RTU接收驅動程序的實現,由於1.5T和3.5T的定時,隱含著大量對中斷的管理。在高通信速率下,導致CPU負擔加重,因此在<=19200pbs時這兩個定時必須嚴格遵守;對於>19200pbs的情形應該使用2個定時的固定值,建議字符間的超時時間t1.5為750us;幀間超時時間為1.75ms

上面是MODBUS協議中的規定,但在實際使用中1.5T都沒有必要關註。而幀與幀之間的3.5T則需要程序處理一下。由於RTU模式沒有起始符和結束符,兩個數據包之間只能靠時間間隔來區分。在儀表在工廠實際使用過程中一般都是間隔40ms、50ms甚至更長時間讀一次數據,這個間隔完全超過了T3.5;
假設現在波特率是9600bps要發送取數據的請求:
01 03 00 01 00 01 D5 CA (格式為8個數據位1個停止位)
那麽每個字節包含一個起始位一個停止位也就是10位
那麽發送這串命令要花費時間為:8×10/9600×1000=8.3ms
即第一幀發送時間為8.3ms而3.5T的時間為3.5×10/9600×1000=3.65ms
所以第二幀數據開始發送的時間至少是第12ms開始(8.3+3.65=11.95ms)
之後修改程序後終於可以達到預期的效果但是我用三個軟件進行調試都可以讀到數據(串口調試助手,MODBUSSIM,modscan)其中只有modscan接收數據的時候閃一下紅但是能讀到數據不知道為什麽調節了他的poll時間還是不行其他兩個軟件正常也可以寫數據。想了一下覺得這兩天也就幹了這麽些事。程序是用keil寫的有需要的可以聯系我,可以直接用。

單片機MODBUS通信源代碼