华芯微特开发论坛

 找回密码
 立即注册
搜索
热搜: SWM341 资料
查看: 3657|回复: 5

UART如何使用DMA接收不定长字符串。。

[复制链接]

14

主题

61

帖子

789

积分

超级版主

Rank: 8Rank: 8

积分
789
发表于 2024-1-4 20:26:46 | 显示全部楼层 |阅读模式


SWM341 等芯片中,DMA接收数据时,只有当接收到一个字(4个字节)的数据时,才会将接收到的数据写入 RAM。。因此如果将 DMA_initStruct.Unit 设定为 BYTE,,就会导致当接收到数据个数不是 4 的整数倍时,,最后几个字节被暂存在 DMA 内部,,无法取出。。

解决这个问题的方法是将 DMA_initStruct.Unit 设定为 WORD,UART 每接收到一个字节数据时,,DMA 从 UARTx->DATA 读取一个字写入 RAM,,这样每次 UART 接收到数据后都会立即被 DMA 搬运到 RAM 中,,不会产生接收数据被暂存在 DMA 内部的问题。。

具体使用代码见 gitee 上最新的例程代码: https://gitee.com/synwit-co-ltd/SWM341_Lib/tree/main/UART/SimplUART_DMA
回复

使用道具 举报

2

主题

14

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2024-1-6 11:48:25 | 显示全部楼层
没有使用过DMA,用串口都是把数据收到队列,然后超时接收就处理数据。你的dma方式感觉不错,有空再玩玩。
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2024-8-25 16:43:44 | 显示全部楼层
我现在测试DMA也是遇到非4字节整数倍有数据被DMA内部FIFO缓存情况,楼主发的这个方法会导致接收缓冲区变4倍大小了,而且数据不是字节连续的,也不是很方便,我目前使用256000波特率接收数据,如果单纯中断接收,中断压力太大了,一直都是使用DMA,奈何这个芯片的DMA数量少,而且还这么不好用。重新设置DMA也无法生效。
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2024-8-25 17:09:42 | 显示全部楼层
给大家分享一下我的曲线救国方案,现在实测数据如果非4字节整数倍,会被缓存1-3个字节在DMA内部的FIFO,且用户不可见,确定原因后测试了很多办法都没法解决,那就将错就错,目前可以通过 SRCSR 计算出实际数量,哪怕非4自己的都可以,这个寄存器会实时更新;SRCSR是实际被传输到内存的数据剩余数量,通过总数减去这个寄存器就是已经传输的,永远是4的倍数,通过这2个寄存器做减法,就能知道FIFO中还有几个字节,假设还有n个字节没有取出,此时用4-n就是还要有几个字节收到了,后面数据就会一起发过来,那么将串口切换到环回模式,发送4-n个字节岂不就把剩余的n个字节逼出来了,实测可行!

if (DMA->CH[DMA_CH1].DSTSR > DMA->CH[DMA_CH1].SRCSR)        //有数据缓存在FIFO里面了,逼出来
                        {
                                cnt2 = DMA->CH[DMA_CH1].DSTSR - DMA->CH[DMA_CH1].SRCSR;        //获取没有被传出来的数据数量
                                cnt2 = 4 - cnt2;                                                                        //计算还差几个字节凑成4字节
                                UART0->CTRL |= BIT10;        //进入环回模式
                                for (i = 0; i < cnt2; i++)        //环回模式把剩余数据逼出来
                                {
                                        UARTx_SendByte(UART_PRINTF_CH, 0);
                                }
                                //本来准备检查一下等待数据发送完成再退出换回模式,实测不需要等待
                                //UARTx_WaitSendComplete(UART_PRINTF_CH, 3);        //等待数据发送完成,检查 UARTx->CTRL & BIT0
                                UART0->CTRL &=~BIT10;        //退出环回模式
                        }
回复

使用道具 举报

0

主题

3

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2024-8-25 17:42:58 | 显示全部楼层
本帖最后由 cp1300 于 2024-8-25 17:48 编辑
cp1300 发表于 2024-8-25 17:09
给大家分享一下我的曲线救国方案,现在实测数据如果非4字节整数倍,会被缓存1-3个字节在DMA内部的FIFO,且 ...

补充一下,由于去掉了调试信息后出问题了,最终原因是环回模式,也必须等待数据发送完了,发送完了,才能接收完,接收完了才能将FIFO中的数据逼出来,判断串口的 UARTx->CTRL & BIT0  ,为1了就是发送完了
回复

使用道具 举报

0

主题

1

帖子

32

积分

新手上路

Rank: 1

积分
32
发表于 2024-11-18 22:28:31 | 显示全部楼层
刚接触这款芯片,UART使用DMA接收不定长字符串,正常使用中,各种奇葩没遇到,DMA_initStruct.Unit 设定为 BYTE一点也没有问题,更别说使用环回模式逼出来
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|华芯微特开发论坛

GMT+8, 2025-1-10 06:54 , Processed in 0.032128 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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