打印
[STM32F1]

串口DMA接收的问题

[复制链接]
1356|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
djz1992|  楼主 | 2020-8-28 15:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用HTTP下载bin文件,服务器不分段,一下子几十k的文件就下发过来。
现在是DMA+串口空闲中断。问题来了。
接收是来连续的,串口不会空闲,远超缓冲区大小的数据,怎么办 ?
想用双缓冲区来切换接收,然后接受完一部分立马处理,避免数据被覆盖。
但是问题是中间不停顿,空闲中断会触发吗?DMA完成中断会触发吗?

如果DMA的接收BUF长度是1024。当接收满1024后会不会触发完成中断?
@dirtwillfly @m564522634 @xyz549040622

使用特权

评论回复
沙发
gyh974| | 2020-8-28 15:25 | 只看该作者
这么大的文件传输数据,最终你是要保存文件在哪里?还是收完再作处理?

使用特权

评论回复
板凳
xyz549040622| | 2020-8-28 15:31 | 只看该作者
只要DMA传输完成中断使能,满1024肯定会触发中断的。
双缓存区是软件机制,和硬件没关系的。你需要做的是两种接收方式配合使用。

使用特权

评论回复
地板
djz1992|  楼主 | 2020-8-28 15:42 | 只看该作者
xyz549040622 发表于 2020-8-28 15:31
只要DMA传输完成中断使能,满1024肯定会触发中断的。
双缓存区是软件机制,和硬件没关系的。你需要做的是两 ...

我现在想的是串口空闲中断负责接收处理一些短的数据。DMA完成中断负责接收处理那些超长内容。但是最后一帧肯定又不会正好是1024,还得靠空闲中断来?

好麻烦啊,直接1字节1字节接收得了,简单方便。

使用特权

评论回复
5
djz1992|  楼主 | 2020-8-28 15:43 | 只看该作者
gyh974 发表于 2020-8-28 15:25
这么大的文件传输数据,最终你是要保存文件在哪里?还是收完再作处理?

收完一帧就写到flash里,OTA升级么

使用特权

评论回复
6
djz1992|  楼主 | 2020-8-28 16:19 | 只看该作者
void UsartReceive_IDLE(UART_HandleTypeDef *huart,UartBufferTypedef *UartxRT )
{
        uint32_t temp;
        if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))                                //获取IDLE标志位,如果idle标志被置
        {
                __HAL_UART_CLEAR_IDLEFLAG(huart);                                                                        //清除标志
                HAL_UART_DMAStop(huart);
                temp=__HAL_DMA_GET_COUNTER(huart->hdmarx);                                                        //获取DMA中未传输的数据个
                UartxRT->RxLen =  MAX_UART_BUFFER - temp;                                                        //总计数减去未传输的数据个数,得到已经接收的数据个
                memcpy(UartxRT->RxBuf ,UartxRT->RxDMA_Buf ,UartxRT->RxLen );
                UartxRT->rx_idle_flag=1;                                                                                        //接受完成标志位置1
                HAL_UART_Receive_DMA(huart,UartxRT->RxDMA_Buf,MAX_UART_BUFFER);                //重新启串口DMA接收
        }
}

void DMA1_Channel5_Receive_Complete(UART_HandleTypeDef *huart,UartBufferTypedef *UartxRT)
{
        static uint8_t witchbuf=1;

        if(        __HAL_DMA_GET_FLAG(&hdma_usart1_rx,DMA_FLAG_TC5)!= RESET)                                //DMA接收完成标志
        {
                __HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx,DMA_FLAG_TC5);                                                //清除中断标志
                HAL_UART_DMAStop(huart);
                if(witchbuf==1)                                                                                                //之前用的buf1,切换为2
                {
                        memcpy(UartxRT->RxBuf ,UartxRT->RxDMA_Buf ,MAX_UART_BUFFER);
                        UartxRT->rx_idle_flag=1;               
                        witchbuf=2;                                                                                            
                        HAL_UART_Receive_DMA(huart,UartxRT->RxDMA_Buf2,MAX_UART_BUFFER);        //重启串口DMA接收到buf2
                }
                else if(witchbuf==2)                                                                             //之前用的buf2,切换为buf1
                {
                        memcpy(UartxRT->RxBuf ,UartxRT->RxDMA_Buf2 ,MAX_UART_BUFFER);
                        UartxRT->rx_idle_flag=1;               
                        witchbuf=1;                                                                                            
                        HAL_UART_Receive_DMA(huart,UartxRT->RxDMA_Buf,MAX_UART_BUFFER);                //重启串口DMA接收到buf1
                }
        }
}
@xyz549040622 以上这样写,好像每次收完复制到一个地方,会很慢吧。是不是应该传递指针?不复制又容易丢

使用特权

评论回复
7
djz1992|  楼主 | 2020-8-28 16:43 | 只看该作者
xyz549040622 发表于 2020-8-28 15:31
只要DMA传输完成中断使能,满1024肯定会触发中断的。
双缓存区是软件机制,和硬件没关系的。你需要做的是两 ...

双缓冲区的时候,dma设置成normal还是循环?

使用特权

评论回复
8
djz1992|  楼主 | 2020-8-28 17:12 | 只看该作者
xyz549040622 发表于 2020-8-28 15:31
只要DMA传输完成中断使能,满1024肯定会触发中断的。
双缓存区是软件机制,和硬件没关系的。你需要做的是两 ...

memcpy(UartxRT->RxBuf ,UartxRT->RxDMA_Buf ,UartxRT->RxLen );
HAL_UART_Receive_DMA(huart,UartxRT->RxDMA_Buf2,MAX_UART_BUFFER);        //重启串口DMA接收到buf2


HAL_UART_Receive_DMA(huart,UartxRT->RxDMA_Buf2,MAX_UART_BUFFER);        //重启串口DMA接收到buf2
memcpy(UartxRT->RxBuf ,UartxRT->RxDMA_Buf ,UartxRT->RxLen );


这两句的前后关系影响接收吗?
如果执行完HAL_UART_Receive_DMA,DMA就立马开始工作,cpu可以自己copy自己的,不用管串口,那就应该先打开dma,再开始复制,然后处理。

其实最好是配置完dma为buf2后,直接用buf1进行处理,都不需要复制。但是其他c文件里也有调用buf的处理部分。
要么用if来控制处理的buf还是buf2,要么传递指针过去。
传递指针的话,像buf[2]这种该怎么写?*(p+2)?
C语言差。。。

使用特权

评论回复
9
zchong| | 2020-8-28 21:24 | 只看该作者
HTTP,串口,具体是啥过程,没看明白

使用特权

评论回复
10
dirtwillfly| | 2020-8-29 12:42 | 只看该作者
不懂,这个数据传输过程,是服务器端控制传输的,还是下位机控制传输的?
这样一下子传输那么多,中间没有验证,很容易出错的

使用特权

评论回复
11
cooldog123pp| | 2020-8-29 21:38 | 只看该作者
默默的围观吧,是不是数据量传输太大了,缓存不够?不懂,不敢瞎哔哔。

使用特权

评论回复
12
cooldog123pp| | 2020-8-29 21:38 | 只看该作者
默默的围观吧,是不是数据量传输太大了,缓存不够?不懂,不敢瞎哔哔。

使用特权

评论回复
13
djz1992|  楼主 | 2020-8-30 07:29 | 只看该作者
dirtwillfly 发表于 2020-8-29 12:42
不懂,这个数据传输过程,是服务器端控制传输的,还是下位机控制传输的?
这样一下子传输那么多,中间没有 ...

http下载文件,就是直接在tcp的连接基础上,按http的请求格式去get文件。
没有做相应的上位机,所以没有分包和校验。

使用特权

评论回复
14
bald| | 2020-8-31 00:24 | 只看该作者
可以用定时中断。读取指针与DMA传输指针之间够一帧即转存一次。这样根本不需要关注串口的传输,只要监视缓冲区里的内容即可。这里主要问题是巡查窗口周期的选择。

使用特权

评论回复
15
djz1992|  楼主 | 2020-8-31 17:11 | 只看该作者
STM32串口空闲中断,接收一帧数据,会进两次空闲中断。数据乱了,这咋整啊@dirtwillfly @m564522634 @xyz549040622

使用特权

评论回复
16
djz1992|  楼主 | 2020-8-31 17:12 | 只看该作者
@xyz549040622

使用特权

评论回复
17
djz1992|  楼主 | 2020-8-31 21:11 | 只看该作者
bald 发表于 2020-8-31 00:24
可以用定时中断。读取指针与DMA传输指针之间够一帧即转存一次。这样根本不需要关注串口的传输,只要监视缓 ...

假设dma读取长度设置的是128。现在还没读取完,怎么查看DMA已经读取到哪个位置了?

使用特权

评论回复
18
bald| | 2020-8-31 22:05 | 只看该作者
djz1992 发表于 2020-8-31 21:11
假设dma读取长度设置的是128。现在还没读取完,怎么查看DMA已经读取到哪个位置了? ...

DMA本身有一个传输指针,自己在缓冲区设置一个读取指针,两个指针之差大于等于128进行一次存储操作。DMA传输指针是工作在循环模式的。读取指针当然也要进行循环操作

使用特权

评论回复
19
djz1992|  楼主 | 2020-9-1 08:17 | 只看该作者
bald 发表于 2020-8-31 22:05
DMA本身有一个传输指针,自己在缓冲区设置一个读取指针,两个指针之差大于等于128进行一次存储操作。DMA ...

DMA传输指针是
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
这个里面的*pData吗?

使用特权

评论回复
20
天意无罪| | 2020-9-1 08:20 | 只看该作者
STM32做主还是从啊,如果做主,直接get或定时get数据,还不用开buffer,数据校验也好做。如果STM32是做从,你靠DMA中断来接收数据,数据正确率不好控制吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:人生苦短,冬日苦长,正是青葱,却无骄阳

115

主题

620

帖子

5

粉丝