STM32 HAL库 串口DMA接收不定长数据

STM32 HAL库 串口DMA接收不定长数据

整体思路:我是用的CUBEMX软件生成的工程,使能了两个串口,串口2用来接收不定长的数据,串口1用来发送串口2接收到的数据;串口2我找了一个UBLOX卫星模块,每秒输出不定长的定位信息数据;
首先肯定要先打开串口空闲中断,cubemx里面没有这个空闲中断的开启图形界面,需要自己敲代码打开。
然后开启DMA接收;
最后串口接收到空闲中断标志后会跳进中断函数,然后再进行处理就可以了。

串口2接收采用循环接收方式
NVIC配置
NVIC也顺便改一下,默认是0的话有时候用库自带延时函数会卡死。

main函数
在你的串口初始化后加入两行代码
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
使能串口空闲中断
HAL_UART_Receive_DMA(&huart2, temp, BUFF_SIZE);
这个是把dma接收到的数据放到temp里面,BUFF_SIZE是空间大小,可以在前面宏定义(#define BUFF_SIZE 1024),由于ublox每秒输出的信息比较多,所以缓存开的比较大;
完成上面的步骤,串口接收到数据就进入中断了。由于中断函数里没有空闲中断的处理函数,所以我们要自己在stm32f4xx_it.c文件中加
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */

/* USER CODE END USART2_IRQn 0 /
HAL_UART_IRQHandler(&huart2);
/
USER CODE BEGIN USART2_IRQn 1 /
MY_UART_IDLE_IRQHandler(&huart2);//这个是我们自己定义的空闲中断服务函数
/
USER CODE END USART2_IRQn 1 */
}
然后在main文件里把空闲中断服务函数写出来

void MY_UART_IDLE_IRQHandler(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART2)
{
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
//清除中断标志
HAL_UART_DMAStop(&huart2);
//停止dma接收
uint16_t DMA_RECEIVE = BUFF_SIZE -__HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
计算出接收到的字节数
HAL_UART_Transmit(&huart1, temp, DMA_RECEIVE, 1000);//从串口1将收到的数据发出
memset(temp,0,DMA_RECEIVE);
将缓存区重新初始化
HAL_UART_Receive_DMA(&huart2, temp,BUFF_SIZE);
重新开启DMA接收
}
}
}
需要注意的是,__HAL_DMA_GET_COUNTER(&hdma_usart2_rx)这个函数是表示DMA接收剩余的字节数;我们刚开始的时候开启DMA接收的时候是1024个字节,然后进入空闲中断后,这个函数统计到我们内存还剩XX个字节,也就是说我们实际收到的字节是1024减去内存剩下的字节数。
DMA_RECEIVE这个要根据你实际字节去定义大小,我开始定义的是uint8_t,输出结果怎么都不对,最后发现1024-x这个肯定要大于uint8_t,所以改成了uint16_t。
本人也是刚学习没几天,所以写的很基础,希望能帮到正在学习的人。

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丐帮专业打狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值