介绍
本博文基于stm32F407,利用uart3发送数据,并由uart3接收ROS通过串口发送的数据后由uart1发送回ROS。以下,主要针对于调试过程中的问题的总结
发送数据错位
发送协议:
初始化:
MYDMA_Config_Inter(DMA1_Stream3,DMA_Channel_4,
(u32)&USART3->DR,(u32)TxBuffer,
TxBufferSize,DMA1_Stream3_IRQn, DMA_DIR_MemoryToPeripheral);
主函数使能uart3发送
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
MYDMA_Enable(DMA1_Stream3, TxBufferSize);
在代码中要注意初始化发送的大小应该和在主函数使能发送的大小应该一致,如果不一致会出现数据错位,导致ROS在解析数据的过程中会把后续接收的数据过程中,直接认为数据不对而直接丢弃数据。
uart接收
在调试过程中,一开始只开启了空闲中断,但是一直出现ROS第一次发送的数据无法接收,而后续的数据可以接收到。后面才发现空闲中断无法接收第一次发送的数据。
解决方法:
初始化时开启接收中断,进入接收中断后在开启空闲中断并关闭接收中断
void USART3_IRQHandler(void) {
// 空闲中断
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) {
DMA_Cmd(DMA1_Stream1, DISABLE);
DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1|DMA_FLAG_FEIF1|DMA_FLAG_DMEIF1
|DMA_FLAG_TEIF1|DMA_FLAG_HTIF1);
DMA_SetCurrDataCounter(DMA1_Stream1, USART_REC_LEN);
DMA_Cmd(DMA1_Stream1, ENABLE);
}
// 接收中断
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
DMA_Cmd(DMA1_Stream1, DISABLE);
DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1|DMA_FLAG_FEIF1
|DMA_FLAG_DMEIF1|DMA_FLAG_TEIF1|DMA_FLAG_HTIF1);
DMA_SetCurrDataCounter(DMA1_Stream1, USART_REC_LEN);
DMA_Cmd(DMA1_Stream1, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
}
}
以下是接收数据后直接开启UART1,并通过UART1发送,并通过长度判断来实现对不定长的数据的接收
void DMA1_Stream1_IRQHandler() {
// clear flag, and waiting for finishing receiving
if (DMA_GetFlagStatus(DMA1_Stream1, DMA_FLAG_TCIF1) != RESET) {
DMA_Cmd(DMA1_Stream1, DISABLE); // close DMA, forbidden having other data flow in
UART3_ReceiveSize = USART_REC_LEN - DMA_GetCurrDataCounter(DMA1_Stream1);
if (UART3_ReceiveSize != 0) {
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
MYDMA_Enable(DMA2_Stream7, UART3_ReceiveSize);
}
DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1|DMA_FLAG_FEIF1|DMA_FLAG_TEIF1|DMA_FLAG_HTIF1|DMA_FLAG_DMEIF1);
DMA_SetCurrDataCounter(DMA1_Stream1, USART_REC_LEN);
DMA_Cmd(DMA1_Stream1, ENABLE);
}
}
ROS端部分程序
while (ros::ok()) {
if (ser.available()) {
ser.read(r_buffer, rBUFFERSIZE);
if (data_analyse(r_buffer) != 0) {
for (int i = 0; i < 4; ++i){
posx.cvalue[i] = r_buffer[2+i];
posy.cvalue[i] = r_buffer[6+i];
vx.cvalue[i] = r_buffer[10+i];
vy.cvalue[i] = r_buffer[14+i];
angular_v.cvalue[i] = r_buffer[18+i];
pose_angular.cvalude[i] = r_buffer[22+i];
}
ROS_INFO("posx: [%f],posy: [%f],vx: [%f],vy.: [%f],angular_v: [%f],pose_angular: [%f]", posx.fvalue,posy.fvalue,vx.fvalue,vy.fvalue,angular_v.fvalue,pose_angular.fvalue);
}
ros::spinOnce();
}
}
后续会公开代码,请期待我的代码分享,谢谢!