完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
目的:
为了能使UART通讯不受长度和回车等字符限制,同时也记录下自己的实施过程,方便以后查阅. 使用工具:
STM32CubeMX部分:
Keil 代码修改: Main.c 作如下修改: 添加宏定义 //UART Define #define UART1_RX_BUFFER_SIZE 128 #define UART1_TX_BUFFER_SIZE 128 #define USB_RX_BUFFER_SIZE 63 uint8_t g_USART1_RX_Buffer[UART1_RX_BUFFER_SIZE]; volatile uint8_t g_USART1_RX_Buffer_Size = 0; volatile uint8_t g_USART1_RX_Received_Flg=0; uint8_t g_USART1_DMA_RX_Buffer[UART1_RX_BUFFER_SIZE]; volatile uint8_t g_USART1_DMA_RxSize=0; Main.c中增加如下,UART IDLE中断会发生第一次无法接收到数据的问题,所以第一次使用UART接收中断处理. /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,g_USART1_DMA_RX_Buffer,1); //不开空闲中断,第一次接收数据 /* USER CODE END 2 */ usart.c增加如下代码,HAL_UART_RxCpltCallback函数仅在第一次收到数据时,接收数据使用,收到后立即改为IDLE中断接收 UART_IDLE_Callback在DMA空闲中断时调用 /* USER CODE BEGIN 1 */ //为了解决第一次IDLE中断无法接收数据问题,第一byte使用接收中断 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { static uint8_t FirstUartIT = 0; UNUSED(huart); if (huart->Instance == USART1) { if (FirstUartIT == 0) //第一次回调,转为DMA接收 { FirstUartIT++; __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除标志位 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断 g_USART1_DMA_RxSize = 1; //在g_USART1_DMA_RX_Buffer中已经有一个Byte数据,所以Size设为1 HAL_UART_Receive_DMA(&huart1, g_USART1_DMA_RX_Buffer + 1, UART1_RX_BUFFER_SIZE); //打开DMA接收,数据放在g_USART1_DMA_RX_Buffer } } } void UART_IDLE_Callback(UART_HandleTypeDef *huart) { uint32_t temp; if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET) //获取IDLE标志位,检查idle标志是否被置位 { __HAL_UART_CLEAR_IDLEFLAG(huart); //清除标志位 temp = huart->Instance->SR; //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能 temp = huart->Instance->DR; //读取数据寄存器中的数据 temp = temp; HAL_UART_DMAStop(huart); if (huart->Instance == USART1) { /* get rx data len */ //利用DMA中未传输的数据个数来计算收到的数据数目 g_USART1_DMA_RxSize += UART1_RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); if (g_USART1_DMA_RxSize > 0) { memcpy(g_USART1_RX_Buffer, g_USART1_DMA_RX_Buffer, g_USART1_DMA_RxSize); memset(g_USART1_DMA_RX_Buffer, 0x00, g_USART1_DMA_RxSize); g_USART1_RX_Buffer_Size = g_USART1_DMA_RxSize; g_USART1_DMA_RxSize = 0; } HAL_UART_Receive_DMA(&huart1, g_USART1_DMA_RX_Buffer, UART1_RX_BUFFER_SIZE); //继续接收DMA数据 } } } 在UART中断处理函数中调用UART_IDLE_Callback void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ UART_IDLE_Callback(&huart1); /* USER CODE END USART1_IRQn 1 */ } 在Main.c增加USART命令处理函数和数据发送函数 uint8_t Uart_SendData(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t Size) { static uint8_t DMA_TX_BUF_UART1[UART1_TX_BUFFER_SIZE] = {0}; if (Size == 0) return HAL_ERROR; if (huart->Instance == USART1 && (huart->hdmatx->Instance->CNDTR == 0) && Size < UART1_TX_BUFFER_SIZE) { memcpy(DMA_TX_BUF_UART1, buf, Size); return HAL_UART_Transmit_DMA(&huart1, DMA_TX_BUF_UART1, Size); } return HAL_ERROR; } void USART_Commands_Receive(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { uint8_t ReturnBuffer[USB_RX_BUFFER_SIZE]={0}; uint32_t ReturnLength=0; if (g_USART1_RX_Buffer_Size > 0) { CommandsHandle(g_USART1_RX_Buffer,g_USART1_RX_Buffer_Size,ReturnBuffer,&ReturnLength); Uart_SendData(&huart1, g_USART1_RX_Buffer, g_USART1_RX_Buffer_Size); memset(g_USART1_RX_Buffer, 0x00, g_USART1_RX_Buffer_Size); g_USART1_RX_Buffer_Size = 0; } } return; } /* USER CODE END 4 */ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1645 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1564 浏览 1 评论
992 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
691 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1610 浏览 2 评论
1871浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
656浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
526浏览 3评论
542浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
515浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 22:14 , Processed in 0.708394 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号