硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1169|回复: 7
收起左侧

[技术讨论] STM32F4系列DMA串口收发问题

[复制链接]

3

主题

8

回帖

17

积分

新手上路

积分
17
发表于 2022-10-13 13:30:46 | 显示全部楼层 |阅读模式
本帖最后由 xbdsx 于 2022-10-13 13:36 编辑

    关于stm32DMA串口收发使用过程中的一些问题,和大家探讨一下。
1、DMA接收必须调用HAL_UART_Receive_DMA()函数。
2、串口DMA发送过程中HAL_UART_Transmit_DMA(),可能触发接收中断,导致接受到发送的数据。   
3、对于定时发送的串口数据,容易产生数据接收混乱。
4、串口全双工通信,为何芯片设计不能同步收发,还是使用有问题?

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2022-10-13 15:33:10 | 显示全部楼层
没问题,发送和接收是独立的。

大概率是程序处理问题。
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2022-10-14 14:14:53 | 显示全部楼层

如果在串口空闲中断中启用接收发送,这样是不会有问题。如果把发送HAL_UART_Transmit_DMA(&husartx,Uart1TxBuf,UART1_TX_BUF_LEN)放到主循环中,这样会影响接收的数据。
image.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2022-10-14 15:29:57 | 显示全部楼层
xbdsx 发表于 2022-10-14 14:14
如果在串口空闲中断中启用接收发送,这样是不会有问题。如果把发送HAL_UART_Transmit_DMA(&husartx,Uart1 ...

使用空闲中断,现在有专门的空闲DMA API,调用下,不需要用户处理了

HAL_UARTEx_ReceiveToIdle_DMA
回复

使用道具 举报

6

主题

641

回帖

659

积分

金牌会员

积分
659
QQ
发表于 2022-10-15 20:01:33 | 显示全部楼层
标准库时整理的USART+DMA+IDLE驱动代码,切换LL库后还是移植继续保存同样的风格,习惯了,不喜欢直接适用HAL库
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2022-10-18 13:51:29 | 显示全部楼层
最终还是把两块MCU之间的DMA发送改成阻塞发送(HAL_UART_Transmit)才稳定下来
回复

使用道具 举报

5

主题

65

回帖

80

积分

初级会员

积分
80
发表于 2022-10-18 17:52:35 | 显示全部楼层
void USART2_IRQHandler(void)                        //串口1中断服务程序
{
        u8 Res;
        if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
        {
                Res = USART2->SR;
                Res = USART2->DR;
                DMA_Cmd(DMA1_Stream5, DISABLE);                                                                                                                                                                                         //关闭DMA,防止处理其间有数据
                U2_RX_LEN = 1024 - DMA_GetCurrDataCounter(DMA1_Stream5);                                                //一帧数据长度,DMA计算是递减的,所以要用最大值去减
                DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//情掉所有标志
                DMA1_Stream5->NDTR = 1024;                                                                                                                                                                        //更新新的1024长度,建议主板设置4096,尽量大点,要加,否则DMA关掉之后就没有长度和目标地址XHC
                DMA1_Stream5->M0AR = (u32)USART2_RX_BUF;                                                                                                                                                        //更新DMA的目标地址,一定要加XHC
                DMA_Cmd(DMA1_Stream5, ENABLE);                                                                                                                                                                                     //打开DMA,        
        }
        USART_ClearITPendingBit(USART2, USART_IT_ORE_RX | USART_IT_RXNE | USART_IT_IDLE);
}
虽然是标准库,但是我这个是没问题的。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2022-10-19 09:52:09 | 显示全部楼层
xhc281358765 发表于 2022-10-18 17:52
void USART2_IRQHandler(void)                        //串口1中断服务程序
{
        u8 Res;

这种写法很容易被优化掉,使用要注意。
Res = USART2->SR;
Res = USART2->DR;
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-18 20:07 , Processed in 0.323482 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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