用串口中断解析Modbus数据
状态机解析 Modbus 协议数据帧
原理:
- 中断接收到设备地址 0x01, 进入阶段 2
- 中断接收到寄存器地址, 进入阶段 3
- 中断接收到数据域长度, 进入阶段 4
- 往buf 存接收到的数据域字符,直到接收到应有的数据域长度加上 CRC
- 如果计算的 CRC 和接收到的 CRC 一致就发送信号通知任务
if (huart->Instance == USART3) {
RxBuffer_copy_U3 = RxBuffer_U3;
switch (ModbusFlag) {
case SORNON:
if(RxBuffer_copy_U3 == 0x01){
ModbusFlag = SORADD;
}
break;
case SORADD:
if(RxBuffer_copy_U3 == 0x03){
ModbusFlag = SORCMD;
RxBuffer_ARR_U3[0] = 0x01;
RxBuffer_ARR_U3[1] = 0x03;
}
break;
case SORCMD:
ModbusDalen = RxBuffer_copy_U3 + 5;
RxBuffer_ARR_U3[2] = RxBuffer_copy_U3;
ModbusFlag = SORDAT;
break;
case SORDAT:
RxBuffer_ARR_U3[Point_U3] = RxBuffer_copy_U3;
Point_U3++;
if (Point_U3 >= ModbusDalen) {
if (crc16(RxBuffer_ARR_U3, ModbusDalen - 2) == (RxBuffer_ARR_U3[17] | RxBuffer_ARR_U3[18] << 8)) {
xSemaphoreGive(xBinarySemaphore);
ModbusFlag = SORNON;
Point_U3 = 3;
} else {
ModbusFlag = SORNON;
Point_U3 = 3;
memset(RxBuffer_ARR_U3, 0, 19);
}
}
break;
default:
break;
}
HAL_UART_Receive_IT(&huart3, (uint8_t *) &RxBuffer_U3, 1);
License:
CC BY 4.0