Modbus消息帧格式
起始符 | 设备地址 | 功能代码 | 数据 | 校验 | 结束符 |
---|---|---|---|---|---|
一个字符 | 2个字符 | 1个字符 | n个字符 | 2个字符 | 1个字符 |
起始符:表示一帧的开始
设备地址:用于指定需要进行信息传递的设备
功能代码: 用于指定需要完成的操作
数据: 表示需要传输的数据
校验: 用于通信中的错误校验
结束符: 表示一帧数据的结束
自定义的帧格式设定
帧头 | 设备码 | 功能码 | 帧尾 |
---|---|---|---|
0xaa | 一个字符(8bit) | 一个字符(8bit) | 0X55 |
uint8_t RxBuffer[4]; //接受缓冲区
uint8_t RxFlag = 0; //接受完成标志: 为0表示接受未完成,为1表示接受完成
uint8_t ErrFlag = 0; //指令错误标志: 为0表示指令正确,为1表示指令错误
HAL_UART_Receive_IT(&huart2, (uint8_t*)RxBuffer, 4); //使能接受中断
while(1) //帧解析代码
{
if(RxFlag == 1) //判断数据是否接受完成
{
RxFlag = 0; // 清除标志位
if(RxBuffer[0] == 0xaa && RxBuffer[3] == 0x55) //判断帧头帧尾
{
if(RxBuffer[1] == 0x01) //判断设备码
{
if(RxBuffer[2] == 0x00) //判断功能码
{
//用户操作
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
printf("LD2 is close!\r\n");
}
else if(RxBuffer[2] == 0x01) //判断功能码
{
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
printf("LED2 is open!\r\n");
}
else //功能码错误
{
ErrFlag = 1; //置位错误标志
}
}
else
{
ErrFlag = 1; //置位错误标志
}
}
else
{
ErrFlag = 1; //置位错误标志
}
if(ErrFlag == 1)
{
printf("Communication Error! Please send again!\r\n");
}
// 清除接受缓冲区和错误标志,准备下一次接受
ErrFlag = 0;
RxBuffer[0] = 0;
RxBuffer[1] = 0;
RxBuffer[2] = 0;
RxBuffer[3] = 0;
}
}
//接受中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart ->Instance == USART2) //判断发生接受中断的串口
{
RxFlag = 1; //置位接受完成标志
HAL_UART_Receive_IT(&huart2, (uint8_t*)RxBuffer, LENGTH); //使能串口中断
}
}