1.?基本的通訊方式
基本的通訊方式有并行通訊和串行通訊兩種。
并行通信:是指數據的各位同時進行傳送的通信方式。
串行通信:是指數據一位一位順序傳送的通信方式。
2.?串行通訊的兩種方式
串行通信的兩種基本形式:同步通信和異步通信。
異步通信所傳輸的數據幀格式是由1個起始位、1~9個數據位、1~2個停止位組成,依靠起始位和停止位保持同步;
同步通信所傳輸數據幀格式是由多個字節組成的一個幀,每個幀都有兩個(或一個)同步字符作為起始位以觸發同步時鐘開始發送或接收數據。
3.?根據傳送方向分類
根據信息的傳送方向,串行通訊可以進一步分為單工、半雙工和全雙工三種。? 如果在通信過程的任意時刻,信息只能由一方A傳到另一方B,則稱為單工。如果在任意時刻,信息既可由A傳到B,又能由B傳A,但只能由一個方向上的傳輸存在,稱為半雙工傳輸。如果在任意時刻,線路上存在A到B和B到A的雙向信號傳輸,則稱為全雙工。
4.?串行通訊接口
串行通訊物理接口按電氣標準及協議來分包括RS-232、RS-422、RS485等,這里主要講一些最常用的RS485接口。
5. RS485接口電路
作為一個經常被應用到的SP485R芯片的示范電路,可以被直接嵌入實際的RS-485應用電路中。微處理器的標準串行口通過RXD 直接連接SP485R 芯片的RO 引腳,通過TXD直接連接SP485R 芯片的DI 引腳。
由微處理器輸出的R/D 信號直接控制SP485R 芯片的發送器/接收器使能:R/D 信號為“1”,則SP485R 芯片的發送器有效,接收器禁止,此時微處理器可以向RS-485 總線發送數據字節;R/D 信號為“0”,則SP485R 芯片的發送器禁止,接收器有效,此時微處理器可以接收來自RS-485 總線的數據字節。此電路中,任一時刻SP485R 芯片中的“接收器”和“發送器”只能夠有1 個處于工作狀態。
連接至A 引腳的上拉電阻R7、連接至B 引腳的下拉電阻R8 用于保證無連接的SP485R芯片處于空閑狀態,提供網絡失效保護,以提高RS-485 節點與網絡的可靠性。
如果將SP485R 連接至微處理器80C51 芯片的UART 串口,則SP485R 芯片的RO 引腳不需要上拉;否則,需要根據實際情況考慮是否在RO 引腳增加1 個大約10K 的上拉電阻。
6. 串口MODBUS通訊
Modbus作為工業通信回路中數據交換的規則已經被廣泛地應用在各個領域,使得具有Modbus 通信協議的設備方便通信,例如PLC、變頻器、流量計、溫濕度、上位機組態軟件、各種傳感器儀表等。
Modbus通信協議分為兩種串行通信模式,ASCII 和RTU 通信模式。在使用時,需要先設定通信模式以及串行口RS232、RS485的通信參數(波特率,奇偶校驗,從機地址,數據位,停止位,字節順序),在Modbus 總線上的所有設備應具有相同的通信模式和串行通信參數
?modbus信息幀結構組成
地址 | 功能碼 | 數據地址 | 數據1 | 數據… | 數據n | CRC16 |
7. MODBUS命令報文
讀數據? ? ?
主站發送
地址 | 功能碼 | 數據起始地址高位 | 數據起始地址低位 | 數據個數高位 | 數據個數低位 | CRC16高位 | CRC16低位 |
? | ? | ? | ? | ? | ? | ? | ? |
?返回:
地址 | 功能碼 | 字節長度 | 數據1高位 | 數據1低位 | 數據2高位 | 數據2低位 | … | CRC16高位 | CRC16低位 |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
8. MODBUS關鍵概念
(1)上位機讀取數據每次間隔時間一般不小于100ms
(2)設備地址:MODBUS從機通訊地址,在一個網絡中不能有兩個相同的地址。(3)功能碼:MODBUS 協議規定的功能碼
(4)寄存器地址和寄存器數
?主站命令中的參數是從寄存器地址開始的寄存,讀寄存器長度的N個寄存器。(5)從站響應數據
?從站響應數據是:字節數和N個數字節數據。
9. MODBUS主站常用操作
1)讀優化:對于不連續地址的數據讀取,是否采取打包讀,則系統使用打包讀命令,一次性完成多個地址的讀取。
2)讀優化間隔:讀優化時,若地址之間小于此間隔,則會打包到一起,使用多讀命令一次讀取。
3)最大包長:一次通訊允許的最大數據長度。
4)字節順序:調整32位雙字的解碼順序。
以32位整數為例,說明字節順序的含義:
1234:表示雙字元件不做處理直接解碼,。
例如:從串口讀到的數據為0000 00 01 表示 1。
2143:表示雙字元件高低字不顛倒,但字內高低字節顛倒。
例如:從串口讀到的數據為0000 00 01 表示 0x00000100 (即256)。
3412:表示雙字元件高低字顛倒,但字內高低字節不顛倒。
例如:從串口讀到的數據為0000 00 01 表示 0x00010000 (即65536)。
4321:表示雙字元件內4個字節全部顛倒。
例如:從串口讀到的數據為00 00 00 01 表示 0x0100 0000 (即1677 721
10. C語言MODBUS程序
(1).CRC16算法:
INT16U CRC16(INT8U *puchMsg, INT16U usDataLen)
{
?? INT8U uchCRCHi = 0xFF;?????????????? /*?高CRC字節初始化?*/
?? INT8U uchCRCLo = 0xFF;?????????????? /*?低CRC?字節初始化?*/
?? INT8U uIndex;??????????????????????? /* CRC循環中的索引?*/
?? while (usDataLen--)????????????????? /*?傳輸消息緩沖區?*/
?? {
????? uIndex = uchCRCHi ^*puchMsg++;?? /*?計算CRC */
????? uchCRCHi = uchCRCLo ^auchCRCHi[uIndex];
????? uchCRCLo = auchCRCLo[uIndex];
?? }
?? return (uchCRCHi << 8 |uchCRCLo);
}
(2)發送命令程序
本例程以Mag64為核心CPU
void Read_InPut(INT8U Addr,INT16UStart,INT16U Len)
{
?? INT16U CRC;
?? SendBuffer_485[0]=Addr;????????????????? //設備地址
?? SendBuffer_485[1]=0x04;????????????????? //modbus功能碼
?? SendBuffer_485[2]=Start/256;???????????? //Start為寄存器地址
?? SendBuffer_485[3]=Start%256;
?? SendBuffer_485[4]=Len/256;?????????????? //Len為讀取寄存器長度
?? SendBuffer_485[5]=Len%256;
?? CRC=CRC16(SendBuffer_485,6);
?? SendBuffer_485[6]=CRC/256;?????????????? //CRC校驗高位
?? SendBuffer_485[7]=CRC%256;?????????????? //CRC校驗低位
? ?R485_OUT;??????????????????????????????? //使能RS485發送
?? SendLen_485=8;
?? SendNum_485=0;
?? CloseINT0();??????????????????????????? //關閉串口接受中斷
?? UCSR0B |= BIT(UDRIE0);????????????????? //打開串口發送中斷
}
(3)返回數據解析
數據接收使用串口中斷,ReceivedBuffer_485為接收數據組,ReceivedNum_485為接收到數據長度,ReceivedFlag_485接收到數據標志。函數float Datasum(INT8UBYTE1, INT8U BYTE2, INT8U BYTE3, INT8U BYTE4)把浮點數的4個字節轉換為1個浮點數。
float Datasum(INT8U FloatByte1, INT8U FloatByte2,INT8U FloatByte3, INT8U FloatByte4)
{??
?float aa;
?union IntTOFP
?? {???????
????? FP32?????? F32;
????? INT8U????? T8[4];
?? };
?? union IntTOFPaa;
? aa.T8[0] = FloatByte1;?????????????????????
aa.T8[1] = FloatByte2;
aa.T8[2] = FloatByte3;
aa.T8[3] = FloatByte4;
?return aa;
}
void Read_Lmag(INT8U Ad)
{
?? INT8U? i,j;
?? INT8U? Num1[10],BIT;
?? INT16UCRC1,CRC2;
?? FP32? Flow;???????????????????????????????? //aaa為瞬時流量數值
??ReceivedFlag_485=1;
??Open_Time1_Ms5(20);
??Read_InPut(Ad,0x1010,2);?????????????????? //發送設備地址、寄存器地址、寄存器長度
??while(ReceivedFlag_485);??????? ???????????//等待接收結束
??if((ReceivedNum_485==9)&&(ReceivedBuffer_485[0]==Ad))??? //?判斷數據是否正確
?? {
????? CRC1=CRC16(ReceivedBuffer_485,7);????????????????
?????CRC2=ReceivedBuffer_485[7]*256+ReceivedBuffer_485[8];
????? if(CRC1==CRC2)
????? {//?轉換數據為浮點數
Flow= Datasum(ReceivedBuffer_485[6], ReceivedBuffer_485[5], ReceivedBuffer_485[4] ,ReceivedBuffer_485[3]);
?????? }
}
}
11. MODBUS調試軟件MODBUS PULL
以從站地址為1,波特率9600,讀取所有實時數據為例設置方法如下:
按照表2所示:起始寄存器地址4113 ?寄存器個數為22
1. 設置采集命令包括設備地址(1)、MODBUS功能碼(04)、寄存器地址(4113)、寄存器長度(2)、采集間隔(1000)。
2.設置串口數據
根據從機串口格式(1位起始位 8位數據位 1位停止位,無校驗)設置如下圖:
3.設置數據顯示格式
4.通訊成功界面
評論
查看更多