OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4881|回复: 5

关于H7的DMA的疑问,数据长度竟然影响接收?

[复制链接]

54

主题

351

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1109
金钱
1109
注册时间
2022-4-20
在线时间
380 小时
发表于 2022-8-11 16:20:40 | 显示全部楼层 |阅读模式
10金钱
我上个月遇到一个DMA的问题,电脑上串口重复发送短数据,比如200个字节一条数据的时候,DMA能正常接收,后续的处理也能正常处理,但是我把这个数据量翻了一倍之后,DMA能正常搬运一会儿,然后就没有后续的数据处理,进入调试发现前面几次都是正常的,后面每发送一条数据,DMA都只把第一个字节搬到了数组里,其余的数据全部遗失了。这是DMA配置的代码,感觉不到异常呢?
  1. UART1RxDMA_Handler.Instance=DMA2_Stream3;                           //数据流选择
  2.         UART1RxDMA_Handler.Init.Request=DMA_REQUEST_USART1_RX;                                                        //USART1接收DMA
  3.         UART1RxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器
  4.         UART1RxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
  5.         UART1RxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
  6.         UART1RxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
  7.         UART1RxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
  8.         UART1RxDMA_Handler.Init.Mode=DMA_NORMAL;                            //外设流控模式
  9.         UART1RxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
  10.         UART1RxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
  11.         UART1RxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
  12.         UART1RxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
  13.         UART1RxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
  14.         HAL_DMA_DeInit(&UART1RxDMA_Handler);   
  15.         HAL_DMA_Init(&UART1RxDMA_Handler);
  16.         __HAL_LINKDMA(&Uart1_Handle,hdmarx,UART1RxDMA_Handler);    //将DMA与USART1联系起来(接收DMA)
复制代码


这是空闲中断的处理
  1. if(__HAL_UART_GET_FLAG(&Uart1_Handle,UART_FLAG_IDLE) != RESET)//idle标志被置位
  2.                 {
  3.                 HAL_UART_AbortReceive(&Uart1_Handle);                     //先停止DMA,暂停接收
  4.                 __HAL_UART_CLEAR_IDLEFLAG(&Uart1_Handle);  //清除标志位
  5.    if(firstflag == 1)
  6.    {
  7.     Usart1RecCnt = UDP_RX_SIZE-__HAL_DMA_GET_COUNTER(&UART1RxDMA_Handler);
  8.     USART1_IRQ_RevEnable = true;
  9.     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11, GPIO_PIN_SET);//RXD灯亮
  10.     RXD=120;//灯亮时长
  11.     memcpy(USARTA_DMA_RX_BUF,TXBUF_t.rx_buffer,UDP_RX_SIZE);
  12.    }
  13.    firstflag = 1;
  14.                 }
  15.         HAL_UART_Receive_DMA(&Uart1_Handle,TXBUF_t.rx_buffer,UDP_RX_SIZE);//重新打开DMA接收
  16.         HAL_UART_IRQHandler(&Uart1_Handle);
复制代码


又菜又爱指点
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

465

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1734
金钱
1734
注册时间
2021-4-11
在线时间
320 小时
发表于 2022-8-11 17:16:51 | 显示全部楼层
帮顶               
回复

使用道具 举报

54

主题

351

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1109
金钱
1109
注册时间
2022-4-20
在线时间
380 小时
 楼主| 发表于 2022-8-12 09:39:30 | 显示全部楼层
自顶一下
回复

使用道具 举报

0

主题

84

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2021-2-25
在线时间
100 小时
发表于 2022-8-12 11:28:14 | 显示全部楼层
帮你顶一下
回复

使用道具 举报

4

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2017-9-4
在线时间
31 小时
发表于 2022-8-12 14:40:34 | 显示全部楼层
本帖最后由 陈祎 于 2022-8-12 14:44 编辑

问题应该出在你空闲中断的处理上 ,存在以下疑问,因为我看不到库里的函数1)停止DMA接收,是只关了串口寄存器的DMA吗?有没有关掉DMA这边的。
2 )重新开始DMA接收,有没有确定DMA的计数寄存器有更新值。
3)你的DMA设置的是普通模式的,为什么不进入空闲中断时,直接关掉DMA,然后后期再打开DMA就是了,也就是只对DMA使能那一位做处理。我不明白你关掉串口DMA的原因
回复

使用道具 举报

54

主题

351

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1109
金钱
1109
注册时间
2022-4-20
在线时间
380 小时
 楼主| 发表于 2022-8-12 16:29:32 | 显示全部楼层
陈祎 发表于 2022-8-12 14:40
问题应该出在你空闲中断的处理上 ,存在以下疑问,因为我看不到库里的函数1)停止DMA接收,是只关了串口寄 ...

1)只关闭了接收的DMA传输,因为发送的DMA要经常使用,关闭之后发送就异常了。
2)有更新值,时而大时而小,多数情况为1,。
3)同一
又菜又爱指点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-8 21:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表