void Modbud_fun6() //6號功能碼處理
{
u16 Regadd;
u16 val;
u16 i,crc,j;
i=0;
Regadd=modbus.rcbuf[2]*256+modbus.rcbuf[3]; //獲取要修改的寄存器地址
val=modbus.rcbuf[4]*256+modbus.rcbuf[5]; //獲取修改后的值
Reg[Regadd]=val; //修改本設備相應的寄存器
//以下為回應主機
modbus.Sendbuf[i++]=modbus.myadd;//添加本設備地址到發送緩沖區
modbus.Sendbuf[i++]=0x06; //添加功能碼到發送緩沖區
modbus.Sendbuf[i++]=Regadd/256; //添加寄存器地址的高字節到發送緩沖區
modbus.Sendbuf[i++]=Regadd%256; //添加寄存器地址的低字節到發送緩沖區
modbus.Sendbuf[i++]=val/256; //添加修改后的值的高字節到發送緩沖區
modbus.Sendbuf[i++]=val%256; //添加修改后的值的低字節到發送緩沖區
crc=crc16(modbus.Sendbuf,i); //計算CRC校驗碼
modbus.Sendbuf[i++]=crc/256; //添加CRC校驗碼的高字節到發送緩沖區
modbus.Sendbuf[i++]=crc%256; //添加CRC校驗碼的低字節到發送緩沖區
RS485_RT_1; //設置RS485為發送模式
for(j=0;j<i;j++) //發送緩沖區中的所有數據
{
RS485_byte(modbus.Sendbuf[j]);
}
RS485_RT_0; //設置RS485為接收模式
}
Modbus協議中,CRC16校驗用于檢測通信數據的完整性。它通過對傳輸的數據進行循環冗余校驗(CRC),生成一個16位的校驗碼,附加到數據的末尾,接收方根據相同算法計算CRC碼,判斷數據是否有誤。
CRC校驗方式說明:
1. CRC16多項式:采用的是0xA001,即Modbus協議中常用的CRC16-IBM算法,初始值為0xFFFF。
2. 查表法優化:代碼使用了查表法來提高效率,通過auchCRCHi[]和auchCRCLo[]兩個數組存儲CRC的高位和低位預計算值。這樣避免了逐位移位運算,減少了處理時間。
3. 計算過程:
初始化高位和低位CRC字節為0xFF。
遍歷數據緩沖區的每一個字節,計算出當前CRC字節與當前數據字節異或的索引uIndex。
根據uIndex在auchCRCHi[]和auchCRCLo[]查找對應的高位和低位CRC值,更新uchCRCHi和uchCRCLo。
4. 結果組合:最終返回時,將高位字節uchCRCHi左移8位,與低位字節uchCRCLo合并,形成最終的16位CRC值。
這個方法有效地驗證Modbus通信中的數據完整性,一旦接收方計算出的CRC值與附加的CRC碼不一致,就說明數據傳輸過程中出現了錯誤。
在 Modbus 通信協議中,主機與設備之間通常使用 CRC16 校驗 來確保通信數據的完整性。因此,主機與上面代碼通信時,默認使用的校驗方式也是 CRC16。
具體來說,Modbus 協議有兩種主要的傳輸模式,每種模式的校驗方式不同:
1. Modbus RTU 模式:
使用 CRC 校驗:Modbus RTU(Remote Terminal Unit)是二進制通信格式,使用 CRC16 校驗。如上代碼所示,發送數據時,會計算數據的 CRC16 校驗值,并將其附加在數據幀的末尾。接收方再通過相同的算法計算出 CRC 值,驗證數據是否正確。
2. Modbus ASCII 模式:
使用 LRC 校驗:在 Modbus ASCII 模式下,校驗方式為 LRC(縱向冗余校驗,Longitudinal Redundancy Check)。這是通過對數據幀中的每個字節進行異或運算,生成一個校驗字節。
因此,如果通信采用 Modbus RTU 模式,則使用的是 CRC16 校驗,這也是上述代碼所實現的校驗方式。如果是 Modbus ASCII 模式,則會使用 LRC 校驗。
總結:
主機與上述代碼進行通信時,通常使用的是 Modbus RTU 模式的 CRC16 校驗。
通訊設置.png (68.27 KB, 下載次數: 9)
下載附件
2024-9-11 15:23 上傳
通訊設置2 .png (18.87 KB, 下載次數: 12)
下載附件
2024-9-11 15:23 上傳
觸摸屏通訊設置的485通訊參數波特率,奇/偶/N效驗,這些都是基本物理傳輸協議。 與程序中串口設置對應
/*USART初始化*/
USART_InitTypeDef USART_InitStructure; //定義結構體變量
USART_InitStructure.USART_BaudRate = 115200; //波特率
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制,不需要
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式,發送模式和接收模式均選擇
USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶校驗,不需要
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位,選擇1位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字長,選擇8位
USART_Init(USART1, &USART_InitStructure); //將結構體變量交給USART_Init,配置USART1
完成物理協議才是軟件協議觸摸屏選擇的是 Modbus RTU 模式也就決定了數據格式,效驗方式為CRC,具體數據協議為標準協議
按標準寫就行了,具體通訊報文分析我提供的文檔內都有
威綸通自由協議報文 地址 通訊 4x 15 01 03 00 0F 00 01 B4 09 數字元件 站號1、功能碼03 讀多個寄存器、 地址15 、 數量1、 效驗碼 5x 10 01 03 00 0A 00 01 A4 08 數字元件 站號1、功能碼03 讀多個寄存器、 地址10 、 數量1、 效驗碼
|