而后对串口部分做参数配置,波特率等按要求配置好,很简单在此不多说了。接下来编写测试代码。
static void Test_UART_Configuration(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength =UART_WORDLENGTH_8B;
huart1.Init.StopBits =UART_STOPBITS_1;
huart1.Init.Parity =UART_PARITY_NONE;
huart1.Init.Mode =UART_MODE_TX_RX;
huart1.Init.HwFlowCtl =UART_HWCONTROL_NONE;
huart1.Init.OverSampling =UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) !=HAL_OK)
{
Error_Handler();
}
定义一个简单的类Modbus通讯协议,采用中断方式来实现数据接收。中断处理函数如下:
voidUSART1_ReceiveDataHandle(void)
{
if(ozonatorRxLength>=RETURNING_DATA_LENGTH)
{
ozonatorRxLength=0;
}
/*接收寄存器为空,等待字节被对应的串口完全接收*/
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET)
{
uint8_t rData;
/*获取接收到的字节*/
HAL_UART_Receive(&huart1,&rData,1,1000);
TestRxBuffer[ozonatorRxLength++] = rData;
}
}
对接收到的信息进行解析,并根据请求命令完成放回信息的编码并回传。
/*解析接收到的信息,并返回合成的回复信息和信息的字节长度,通过回调函数*/
uint16_t ParsingMasterAccessCommand(uint8_t *receivedMessage,uint8_t*respondBytes,uint16_t rxLength)
{
uint16_t respondLength=0;
/*判断是否是本站,如不是不处理*/
uint8_tslaveAddress=*receivedMessage;
if(slaveAddress!=StationAddress)
{
return 0;
}
/*判断功能码是否有误*/
FunctionCodefc=(FunctionCode)(*(receivedMessage+1));
if(CheckFunctionCode(fc)!=MB_OK)
{
return 0;
}
/*信息校验,如不正确则为错误信息不用处理*/
uint16_t dataLength=8;
if((fc==WriteMultipleCoil)||(fc==WriteMultipleRegister))
{
dataLength=(uint16_t)(*(receivedMessage+6))+9;
if(rxLength尚未接收完整
{
return 65535;
}
}
boolchechMessageNoError=CheckRTUMessageIntegrity(receivedMessage,dataLength);
if(!chechMessageNoError)
{
return 0;
}
uint16_tstartAddress=(uint16_t)(*(receivedMessage+2));
startAddress=(startAddress<<8)+(uint16_t)(*(receivedMessage+3));
uint16_tquantity=(uint16_t)(*(receivedMessage+4));
quantity=(quantity<<8)+(uint16_t)(*(receivedMessage+5));
uint8_tindex=(fc>0x08)?(fc-0x09):(fc-0x01);
respondLength=HandleMasterCommand[index](startAddress,quantity,receivedMessage,respondBytes);
return respondLength;
}
3、测试结果
通过USB转RS232接口的模块接入电脑通过AccessPort和串口出手来对通讯进行测试。下图是在AccessPort中监控到的数据收发状态: