[STM32]STM32双机串口通信
上一篇的通信方案在发送端高强度通信下寄了,发现是函数HAL_UART_Transmit()的锅,一个函数居然能跑0.3s左右。。。于是打算选用DMA收发数据,但是DMA在接收数据时遇到一些玄学问题,于是改用DMA发送数据,串口IDLE中断接收数据的策略。
cubeMX配置
接收端部分
开启USART1,打开全局中断。
发射端部分
开启USART1,开启全局中断,打开TX的DMA通道,为normal模式,内存地址自增,并打开DMA_TX的中断。
代码部分
接收端
usart.c:
/* USER CODE BEGIN 0 */
#include "string.h"
#include "main.h"
uint8_t aRxBuffer;
uint8_t Uart_RxBuff[256];
uint8_t Uart_Rx_Cnt;
uint8_t Uart_RxFlag;
uint8_t cAlmStr[] = "Warning!\r\n";
int rxUpdateFlag = 0;
int startReadFlag = 0;
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
if(huart == &huart1 && rxUpdateFlag == 0)
{
if(Uart_Rx_Cnt >= 255) // 溢出判断
{
Uart_Rx_Cnt = 0;
memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
}
else // 没有溢出
{
if(aRxBuffer == '@')
{
startReadFlag = 1;
}
if(startReadFlag == 1)
{
Uart_RxBuff[Uart_Rx_Cnt++] = aRxBuffer; // 接收数据转存
if((Uart_RxBuff[Uart_Rx_Cnt-1] == 0x0A)&&(Uart_RxBuff[Uart_Rx_Cnt-2] == 0x0D)) //判断结束
{
startReadFlag = 0;
rxUpdateFlag = 1; // 数据更新
}
}
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中???
}
/* USER CODE END 1 */
usart.h:
/* USER CODE BEGIN Prototypes */
extern uint8_t aRxBuffer;
extern uint8_t Uart_RxBuff[256];
extern uint8_t Uart_Rx_Cnt;
extern uint8_t Uart_RxFlag;
extern int rxUpdateFlag;
/* USER CODE END Prototypes */
main.c:
/* USER CODE BEGIN Includes */
#include "string.h"
#include "stdio.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
char rxStr[256];
char drawBuffer1[256]; // 提取出的数据变量
char drawBuffer2[256];
char drawBuffer3[256];
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
//Not include 'start' and 'end'
void get_Data(const char* str, char* dst, char start, char end)
{
int i = 0, j = 0;
while(str[i++] != start);
while(str[i] != end)
{
dst[j] = str[i];
j++;
i++;
}
dst[j] = '\0';
}
/* USER CODE END PFP */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
if(rxUpdateFlag == 1) // 收到新数据,开始处理数据
{
strcpy(rxStr, (char *)Uart_RxBuff);
//printf("%s\r\n", rxStr);
// 处理数据
get_Data(rxStr, drawBuffer1, 'a', 'b');
get_Data(rxStr, drawBuffer2, 'b', 'c');
get_Data(rxStr, drawBuffer3, 'c', 'd');
// 清除标志位,缓存等
memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
rxUpdateFlag = 0;
Uart_Rx_Cnt = 0;
}
/* USER CODE END 3 */
发射端
- 记住,MX的代码生成完毕后一定要把MX_DMA_Init放到MX_UARTx_UART_Init之前
然后使用HAL_UART_Transmit_DMA函数发送即可。
注意,不要连续调用这个函数,因为DMA搬运数据也是需要时间的,需要判断DMA通道是否空闲再发送。
通信格式:“@axxxxbxxxxcxxxxdxxxx”(xxxx为数字)
标签:DMA,CODE,Uart,uint8,STM32,RxBuff,USER,串口,双机 From: https://www.cnblogs.com/Asaka-QianXiang/p/17539328.html