你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL_UART_Receive_DMA 接收缓冲区将被重写

[复制链接]
LC2047a 提问时间:2019-7-17 15:29 /
本帖最后由 LC2047a 于 2019-7-18 13:05 编辑

我想构建一个串口控制台。
接收缓冲区为32字节。(HAL_UART_Receive_DMA)
我希望它接受0字+回车,至31字+回车,然后传送到电脑。。

但是当输入超过32个字时,接收缓冲区将被重写。


如:

发送29个字节
输入 : 12345678901234567890123456789
输出 : 12345678901234567890123456789+'\0'

发送31个字节
输入 : 1234567890123456789012345678901
输出 : 1234567890123456789012345678901+'\0'

发送33个字节
输入 : 1234567890123456789012345678901AB
输出 : AB+'\0'
而我想要的是删除超过31个字所有东西
输出 : 1234567890123456789012345678901+'\0'

补充一点,假设用户使用复制和粘贴消息(字符串)进行输入

请帮忙解决它。





SW - Console_1.rar

下载

3.25 MB, 下载次数: 15, 下载积分: ST金币 -1

串口控制台

收藏 评论12 发布时间:2019-7-17 15:29

举报

12个回答
radio2radio 回答时间:2019-7-19 12:34:18
LC2047a 发表于 2019-7-19 08:35
但我真的有这样的问题。
你能建议我一些上位机的软件吗?

SSCOM
LC2047a 回答时间:2019-7-19 08:35:30
radio2radio 发表于 2019-7-18 13:54
另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一 ...

但我真的有这样的问题。
你能建议我一些上位机的软件吗?
radio2radio 回答时间:2019-7-18 21:51:52
LC2047a 发表于 2019-7-18 21:23
用打字样式输入逐一字符,每个字符之间有一段时间。
但是我认为用粘贴字符串进行输入,STM32可以一次捕获 ...

必须可以一次捕获所有字符,长度不是问题。
比如要输入加密密钥,有几百上千个字节,打字肯定不行了。
再长,粘贴也不方便了,就得把字符串放到文件里面,一样可以发给UART。
LC2047a 回答时间:2019-7-18 21:23:25
radio2radio 发表于 2019-7-18 13:54
另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一 ...

用打字样式输入逐一字符,每个字符之间有一段时间。
但是我认为用粘贴字符串进行输入,STM32可以一次捕获所有字符。
LC2047a 回答时间:2019-7-18 21:07:10
radio2radio 发表于 2019-7-18 13:33
要保留缓冲区第一个的内容而不是被覆盖,你始终都要开一大的缓冲区,一般是一个“二级缓冲区”,用来保存 ...

好的! 我尝试修改代码以一个字一个字地捕获字符串。
radio2radio 回答时间:2019-7-18 13:54:38
另外,是否可以进行“粘贴字符串输入”,与UART的接收端的处理没有关系。在UART的RX线看来,字符都是一串一串进来的,你不知道进来的是不是粘贴的。

是否可以粘贴,与上位机的软件有关!

radio2radio 回答时间:2019-7-18 13:33:32
LC2047a 发表于 2019-7-18 08:53
谢谢你!

增加缓冲区大小,但始终它仍然有限。

要保留缓冲区第一个的内容而不是被覆盖,你始终都要开一大的缓冲区,一般是一个“二级缓冲区”,用来保存一次输入的全部字符!二级缓存与UART的接收缓存,可以是互相独立的。 每次接收1个字符的UART也能用。

上面是原理,真正做起来很简单的,使用c语言系统函数scanf():

    char str[INPUT_BUFF_SIZE]; //此二级缓存,一定要大于可能出现的最大输入字符数

    scanf("%s", str); //waiting input string
    printf("Input = %s\r\n", str);

怎么样让scanf()函数动起来,你自己在论坛上面找吧。
LC2047a 回答时间:2019-7-18 12:35:27
本帖最后由 LC2047a 于 2019-7-18 12:36 编辑
radio2radio 发表于 2019-7-18 10:51
如果知道可能发生缓冲区溢出,就要:
1. 使用环形缓冲区。
2. 前面输入进来的字符要及时处理,即处理输入 ...

谢谢大家!
该程序[HAL_UART_Receive_DMA()],可以从粘贴中捕获字符串。
此功能很好用,但长时间操作无法避免/检测到缓冲区将被重写问题,然后系统发生错误。

如果减小缓冲区大小(仅允许输入一个字符)并逐个检查它。 这可以阻止输入错误,但不接受粘贴字符串输入。

似乎问题出现在HAL_UART_Receive_DMA()内部。 当缓冲区变满时,计数器将返回零(缓冲区的开始)。

在市场上其他人是怎么做?

请指教!
radio2radio 回答时间:2019-7-18 10:51:50
LC2047a 发表于 2019-7-18 08:53
谢谢你!

增加缓冲区大小,但始终它仍然有限。对,增加缓冲区大小能够减少32字节的失败问题。

如果知道可能发生缓冲区溢出,就要:
1. 使用环形缓冲区。
2. 前面输入进来的字符要及时处理,即处理输入的速度要快过字符进来的速度。
3. 如果受到某些限制,不能及时处理,就要考虑降低UART的波特率。
4. 考虑输入的需求,限制非法输入,比如超长度的字串。
5. 是否需要溢出后放弃,和请求重发。

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

LC2047a 回答时间:2019-7-18 08:53:01
本帖最后由 LC2047a 于 2019-7-18 10:35 编辑
radio2radio 发表于 2019-7-17 18:16
接收缓冲区开大一些有困难吗,64/128/256如何。

谢谢你!

增加缓冲区大小,但始终它仍然有限。
对,增加缓冲区大小能够减少32字节的失败问题。
但输入65字(129/257字)时会是什么。
缓冲区溢出,开头的内容将被覆盖。

问题是如何保留缓冲区第一个的内容而不是被覆盖。
补充一点,假设用户使用复制和粘贴消息(字符串)进行输入。

请帮忙!


radio2radio 回答时间:2019-7-17 18:16:22
接收缓冲区开大一些有困难吗,64/128/256如何。
bl2019 回答时间:2019-7-17 15:41:44
不会,帮顶

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版