stm32f407 uart + dma高频率一段时间后不接收,假死,但MCU工作正常的BUG

stm32f407 uart + dma高频率一段时间后不接收,假死,但MCU工作正常的BUG

使用场景及情况

  • 硬件:stm32f407
  • 使用CUsart类进行实例化该串口(这个类是前辈写的)
  • 声明一个uint8_t的数组,长度比实际收到的值要大一点(对象实例的时候用到)
  • 例如测试程序里面的长度是5,我实际发送的是1个字节
  • 用普通的串口工具发送,波特率等等都是对的情况下,连续发送,间隔为20ms, 过几秒, 该usart挂掉了,收不到数据了,而且我的判断是,收到0xAA, 就回复0x05, 0x04, 0x03, 0x02, 0x01,结果收不到回复,但是407还在继续工作,我在收到的判断后面通过udp抛出收到的字节,开始收得到,后面也不行了。
  • 数组的地址给到DMA的地址寄存器,数组的长度给到NDTR传输数目寄存器。
  • 综合判断该串口挂掉了,具体原因开始查。

change1

  • 将数组长度改为20,其他条件不变,连续发送,不挂。
  • 但是发现了奇怪的地方

change2

  • 保持change1条件,更改发送时间间隔为10ms,usart挂掉。

阅读手册1

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

  • 软件优先级,可以给陀螺仪的优先级高一点。
    在这里插入图片描述
    在这里插入图片描述
  • 重新使能数据流的时候,应该将所有的中断状态寄存器中的位为1的置0

寄存器打印

在这里插入图片描述

  • 对应的寄存器的位,是半传输中断标志
    在这里插入图片描述
  • 继续狂发,发现如下
    在这里插入图片描述

示波器观察

  • 已经排除IC的问题,用示波器在407和IC之间的RX线上,发现有数据,但是NTDR寄存器以然不递减,各个EN位重新使能进行数据流再次更新,但是无数据

打印USART6-DR

  • 打印DR寄存器,发现数据在死掉的时候是不变的
  • 如果我发送AA,没有问题,因为这时候我的测试程序还要进行发送,还要用到DR(20ms也不会死掉了),但是不发AA,即我的程序不返回,用到TX,那么程序还是会死掉。
    在这里插入图片描述

bug解决

在这里插入图片描述

  • 读完SR再读DR,无论发什么都可以了
    在这里插入图片描述

阅读手册2

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

  • 我们并没有对这个DMAR位软件清零
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
针对您的问题,我可以给出以下回答: STM32F407UART4可以通过DMA方式进行数据传输,这种方式可以大大减轻CPU的负担,提高系统的效率。具体实现方法如下: 1. 配置UART4的GPIO口和USART外设,使其能够正常工作。 2. 配置UART4的DMA发送和接收通道,使其能够通过DMA方式进行数据传输。 3. 在主程序中调用UART4_DMA_Begin_Send()函数,将需要发送的数据传入该函数,即可通过DMA中断方式将数据发送出去。 下面是具体的实现代码: 引用: ```c // UART4 启动DMA发送初始化程序 void UART4_DMA_Begin_Send(uint8_t *send_buffer , uint16_t nSendCount) { GPIO_UART4_RS485_SEND_enable(); // 使能RS485发送使能口 if (nSendCount < UART4_DMA_TX_BUFFER_MAX_LENGTH) { // 数据长度小于DMA缓存区长度 memcpy(UART4_DMA_TX_Buffer , send_buffer , nSendCount); // 将数据拷贝到DMA缓存区 DMA_Cmd(DMA1_Stream4 , DISABLE); // 关闭DMA传输 while (DMA_GetCmdStatus(DMA1_Stream4) != DISABLE); // 确保DMA可以被设置 DMA_SetCurrDataCounter(DMA1_Stream4 , nSendCount); // 设置数据传输量 DMA_Cmd(DMA1_Stream4 , ENABLE); // 开启DMA传输 } } ``` 引用: ```c // 主程序 void main(void) { UART4_Configuration(); // 配置UART4 UART4_DMA_Tx_Configuration(); // 配置UART4的DMA发送通道 UART4_DMA_Rx_Configuration(); // 配置UART4的DMA接收通道 while (1) { // 在合适的时候调用UART4_DMA_Begin_Send()函数,将需要发送的数据传入该函数,即可通过DMA中断方式将数据发送出去 } } ```
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值