【无标题】HAL库STM32f407ZGT6实现串口空闲中断联合DMA中断接收数据,DMA非中断模式发送数据

标题HAL库STM32f407ZGT6实现串口空闲中断联合DMA中断接收数据,DMA非中断模式发送数据

我用的MCU是STM32F407ZGT6, 用的是MCU的UASRT1

首先用CubeMX配置基本的驱动代码,配置步骤参考文章链接:

https://blog.csdn.net/CSDN_Xu_xue/article/details/104403532
https://blog.csdn.net/weixin_43864631/article/details/125855290

用KEIL打开cubemx生成的工程中的 Application/User/Core 文件夹下的 stm32f4xx_it.c 文件,把DMA发送完成中断函数注释掉:

在这里插入图片描述
再打开 Application/User/Core 文件夹下的dma.c 文件,把 DMA发送完成中断 的中断配置注释掉,即不开启发送完成中断;

在这里插入图片描述

在 Application/User/Core 文件夹下的usart.c 文件中添加用来存放接收数据的数组,再加上DMA要发送的数据的长度的变量dat_len;

在这里插入图片描述
在 Application/User/Core 文件夹下的usart.h 文件中定义接收数据的数组的大小(最大是65535);

在这里插入图片描述
在 Application/User/Core 文件夹下的usart.c 文件中添加空闲中断DMA函数HAL_UARTEx_ReceiveToIdle_DMA(); 并且关闭DMA传输一半中断;

( 为什么你的库没有HAL_UARTEx_ReceiveToIdle_DMA()函数,参考这个链接: https://blog.csdn.net/weixin_46251230/article/details/126729795 )

为什么关闭传输一半中断,我是参考的这个链接:
( 链接找不到了 )

在这里插入图片描述

在 Application/User/Core 文件夹下的usart.c 文件中添加空闲中断回调函数HAL_UARTEx_RxEventCallback();

在这里插入图片描述

此外可以在main函数里面加入led翻转指示系统正常运行:

在这里插入图片描述

经过测试,发送很少数据时很快就会回传至上位机,发送很多,比如 12363 字节,就要等几秒,可能是因为串口就只有一根线,发送数据量越大,就越慢

在这里插入图片描述
在这里插入图片描述

可修改接受数组rx_buffer[arr_size]的arr_size大小来接收更多的数据,但是要在65535之内。

我参考的文章链接:

关于空闲中断函数的回调函数是哪个参考文章1

关于串口空闲中断的回调函数是哪个参考文章2

提出了使用hal库的HAL_UARTEx_ReceiveToIdle_DMA()函数,以及关闭DMA半字节中断

提出了使用hal库的HAL_UARTEx_ReceiveToIdle_DMA()函数,以及它的空闲中断回调函数

这篇文章对于DMA传输完成以及空闲中断的描述写的很好,我看了好几遍才懂

如果大家有什么地方有疑惑,喜欢可以批评指正!

keil5工程链接:
链接 https://pan.baidu.com/s/1CwIdCz-qc2BYDKCjxzoRhg?pwd=k3sx
提取码:k3sx

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32F429微控制器上,可以使用DMA(直接内存访问)和串口空闲中断实现串口数据的接收。下面是一个简单的代码示例,演示了如何配置和使用串口DMA空闲中断。 首先,你需要在CubeMX中配置串口DMA。确保你已经正确初始化了串口DMA控制器,并将DMA配置为接收数据。 然后,在代码中添加以下函数来处理DMA空闲中断: ```c // 定义接收缓冲区大小 #define RX_BUFFER_SIZE 128 // 接收缓冲区 uint8_t rx_buffer[RX_BUFFER_SIZE]; // 接收数据长度 volatile uint16_t rx_length = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 处理DMA接收完成中断 if(huart->Instance == USARTx) // 替换为你使用的串口实例 { // 获取接收数据长度 rx_length = RX_BUFFER_SIZE - hdma_usart_rx.Instance->CNDTR; // 可以在这里对接收到的数据进行处理 // ... // 重新启动DMA接收 HAL_UART_Receive_DMA(huart, rx_buffer, RX_BUFFER_SIZE); } } void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { // 发生错误时的处理 } void HAL_UART_IdleCallback(UART_HandleTypeDef *huart) { // 处理空闲中断 if(huart->Instance == USARTx) // 替换为你使用的串口实例 { // 停止DMA接收,并触发空闲中断 HAL_UART_DMAStop(huart); // 获取接收数据长度 rx_length = RX_BUFFER_SIZE - hdma_usart_rx.Instance->CNDTR; // 可以在这里对接收到的数据进行处理 // ... // 重新启动DMA接收 HAL_UART_Receive_DMA(huart, rx_buffer, RX_BUFFER_SIZE); } } ``` 在主函数中,你需要启动串口DMA接收,并启用空闲中断: ```c int main(void) { // 初始化硬件和外设 // 启动DMA接收 HAL_UART_Receive_DMA(&huart, rx_buffer, RX_BUFFER_SIZE); // 替换为你使用的串口和接收缓冲区 // 启用空闲中断 __HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE); // 替换为你使用的串口 while (1) { // 主循环代码 } } ``` 这样,当串口接收到数据时,DMA将触发空闲中断,并在回调函数中处理接收到的数据。注意替换示例代码中的USARTx、huart和hdma_usart_rx为你实际使用的串口DMA实例。 希望这能帮到你!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值