單片機RS485通訊的程序,工作中的成熟應用案例。分享給大家。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (29.27 KB, 下載次數(shù): 122)
下載附件
2018-2-11 18:04 上傳
0.png (52.98 KB, 下載次數(shù): 89)
下載附件
2018-2-11 18:17 上傳
由于MODBUS-RTU 要求每幀信息中的數(shù)據(jù)間隔時間不得超過1.5字符的靜止時間。
因此:
(1)、當串口產(chǎn)生接收中斷后,立即重裝“超時定時器”的初始值。(注:超時定時器的初始值和波特率有關)
問題如下:
(a)、由于要求在串口接收中斷中重裝超時定時器初始值,那么,該超時定時器就只能采用“溢出模式”,而不能采用“CTC模式”
(b)、超時定時器必須在程序初始化時就一直開啟。
我的理解對嗎?
(2)兩幀之間的3.5字符的靜止時間該如何實現(xiàn)呢?
接收到每個字節(jié)的時候,初始化定時器就行,最后一個字節(jié)后,定時器就溢出了
利用單獨的軟件定時器,來判斷一幀接收報文結束,可以防止若報文接收不完整,該幀通信任務無法結束而影響下一幀的接收。
由于一幀報文中字節(jié)與字節(jié)之間的時間間隔和幀與幀之間的時間間隔相比要小得多,因此每當接收一個新字節(jié),就啟動軟件定時器開始計時,定時器的時間設定為幀與幀的最小時間間隔。波特率不同,該時間間隔也不同。若不到預定的時間內(nèi)又接收到下一個字節(jié),則說明一幀報文未結束,定時器重新計時;若定時器順利計數(shù)到預定時間,就會觸發(fā)相應的中斷號,在該定時器中斷子程序中設定幀結束標志字節(jié),表明一幀報文接收完畢。當主程序內(nèi)檢測到一幀報文接收完畢后,會通過核查從方地址及循環(huán)冗余校驗字節(jié)是否正確來判斷該幀的有效性。若確定接收到的是一幀發(fā)送給已方的正確報文,則會根據(jù)報文內(nèi)的功能碼對該幀命令進行相應的處理,并準備發(fā)送幀。
上面就是解決以下兩個問題的方法
(1)、當前幀兩個字節(jié)之間的1.5字符靜止時間
(2)、兩幀之間3.5字符的靜止時間
這里有個SPI串口擴展芯片uCSU122P,內(nèi)置MODBUS引擎,DIP28,或許對你有用點擊此處下載 (原文件名:ucmu2_dat_v122.pdf)
其實這個時間不用這么準確啦,因為是問答式的協(xié)議,你可以以某個定時時間查詢串口緩沖區(qū)字符的長度,如果兩次讀入的長度一樣就認為一幀結束了,這個查詢間隔根據(jù)波特率微調(diào),就是3.5個字符時間。
7樓的做法不嚴格,如果第一次定時查詢的時候正在收最后一個字節(jié),第二次查顯然收完了,第三次查數(shù)據(jù)不變,那么就導致了7個字符的間隔,如果對方在3.5~7字符之間又來了數(shù)據(jù),就麻煩了;
T1.5和T3.5最嚴格的方法還是開定時器,但是可以靈活一點;低波特率(<19200)的時候嚴格定時,和波特率相關;高波特率(>19200)的時候就固定定時(T1.5=750us,T3.5=1750us),這樣降低了CPU中斷響應的負擔。
給你這個程序片段應該可以解決你的問題,我的程序經(jīng)過嚴格的測試,高掃描周期、波特率19200下連續(xù)運行了一個星期,沒出一個錯誤
#pragma interrupt_handler Timer1:iv_TIMER1_OVF
void Timer1(void)
{
unsigned short CRC;
TCNT1=65525-51*11;//65535-(11*(ubbr+1)) 波特率9600
if(CNT<8)
{
CNT++;
if(CNT==4)
{
ModBusQueryDataLong=IsrCount;
IsrCount=0;
}
else if(CNT==8)
{
if(ModBusQueryDataLong>2)
{
CRC=CRC16((unsigned char *)&ModbusFunctionUnion,ModBusQueryDataLong-2);
if((ModbusFunctionUnion.Data[ModBusQueryDataLong-2]==MSB(CRC))&&
(ModbusFunctionUnion.Data[ModBusQueryDataLong-1]==LSB(CRC)))
{
FrameStatu=1;
}
}
}
}
}
#pragma interrupt_handler UART_isr:iv_USART0_RX
void UART_isr(void)
{
CNT=0;
while(!(UCSR0A&(1<<RXC0)));
ModbusFunctionUnion.Data[IsrCount++]=UDR0;
}
單片機源程序如下:
所有資料51hei提供下載:
01.02.26通訊.rar
(77.34 KB, 下載次數(shù): 479)
2018-2-11 17:01 上傳
點擊文件名下載附件
485通訊 下載積分: 黑幣 -5
|