Modbus 通訊時規定主機發送完一組命令必須間隔3.5個字符再發送下一組新命令,這個3.5字符主要用來告訴其他設備這次命令(數據)已結束,而這個3.5字符的時間間隔采用以下方式計算:
1個字符包括1位起始位、8位數據位(一般情況)、1位校驗位(或者沒有)、1位停止位(一般情況下)
這樣說起來一般情況下1個字符就包括11位
那么3.5個字符就是3.5*11=38.5位
還有比如沒有校驗位的
1個字符包括1位起始位、8位數據位(一般情況)、1位停止位(一般情況下)
這樣說起來一般情況下1個字符就包括10位
那么3.5個字符就是3.5*10=35位
波特率含義是每秒傳輸的二進制位的個數
比如9600bps,意思就是說每1秒(也就是1000毫秒)傳輸9600個位,
反過來說傳輸9600個二進制位需要1000毫秒
那么傳輸38.5個二進制位需要的時間就是:
38.5/9.6=4.0104167毫秒
MODBUS RTU要求一幀數據起始和結束至少有大於等於3.5個字符的時間
在波特率為9600的情況下,只要大於4.0104167毫秒即可!
一般,為了簡單起見,可以將傳輸45Bit的時間四舍五入后的整型值作為兩個數據幀之間的時間間隔,並以此來判斷報文接收的完整性。
---------------------
作者:lusirking
來源:CSDN
原文:https://blog.csdn.net/lusirking/article/details/53212195
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
總結:
1 串口發送一幀數據時,兩個字節的間隔時間是必須小於3.5個字符 時間 否則就算兩個字節不處於同一幀數據中。
2 波特率:發送二進制數據位的速率,習慣上用 baud 表示,即我們發送一位二進制數據的持續時間=1/baud。波特率不同 ,那么 3.5個字符的時間也不同。
3 rs485串口配不一樣就會導致一個字節的bit位數不一樣就會導致3.5個字符時間不一樣。
4 總線上的接收數據長度與3.5個字符時間無關。不管你一幀數據有多長 但是字節之間的發送時間一定要滿足小於等於3.5個字符即可
//串口接收延時,適應ModBus-RTC協議
if(usart1_rx_framedata.frame_delay_flag == TRUE )
{
// if( usart1_rx_framedata.frame_delay_Count++ >= 3 ) // 字節延時時間大於3.5個字符
// 數據接收不全是不是等待的一幀的時間太短了呢
// 10us*10=100us 波特率為9600 則那么接收9.8個bit 需要1ms
/*
1個字符包括
1位起始位、
8位數據位(一般情況)、
1位校驗位(或者沒有)、
1位停止位(一般情況下)
這樣說起來一般情況下1個字符就包括11位那么3.5個字符就是3.5*11=38.5位
還有比如沒有校驗位的1個字符包括
1位起始位、
8位數據位(一般情況)、
1位停止位(一般情況下)
這樣說起來一般情況下1個字符就包括10位那么3.5個字符就是3.5*10=35位
那么傳輸38.5個二進制位需要的時間就是:
38.5/9.6=4.0104167毫秒
我們取4.5ms 10us * X =4.5 ms 推出X = 450
*/
if( usart1_rx_framedata.frame_delay_Count++ >= 450 ) // 字節延時時間大於3.5個字符
{
Refresh_Iwdg();
usart1_rx_framedata.frame_delay_flag = FALSE;
usart1_rx_framedata.frame_delay_Count = 0;
usart1_rx_framedata.frame_end_flag = TRUE; //幀結束
}
}
#endif