1. MSPM0G3507串口接收的痛点与解决方案
在实际项目中,我们经常会遇到需要接收不定长数据包的情况,比如与陀螺仪、激光测距模块或者无线模块通信时。传统的STM32单片机通常有硬件空闲中断(IDLE Interrupt)功能,可以在串口总线空闲时自动触发中断,非常方便地实现不定长数据的接收。但是当我切换到MSPM0G3507这款芯片时,发现它竟然没有硬件空闲中断功能!
这就带来了一个很实际的问题:如果使用传统的接收方式,要么只能接收固定长度的数据包,要么就需要复杂的超时判断逻辑。我在实际项目中就踩过这个坑,数据量一大就开始丢包,调试起来特别头疼。后来经过一番摸索,发现可以用定时器来模拟空闲中断的功能,效果相当不错。
这种方法的原理其实很简单:我们在串口接收中断中重置一个定时器,每次收到数据就把定时器"刷新"。如果一段时间内没有新的数据到达,定时器就会超时,这时候我们就认为一帧数据已经接收完成了。这种方法不仅稳定可靠,而且可以根据不同的波特率和应用场景灵活调整超时时间。
2. 定时器模拟空闲中断的实现原理
2.1 核心思想:用定时器检测总线空闲状态
让我用一个生活中的例子来解释这个原理。想象一下你在和朋友聊天,如果对方说完一句话后停顿了几秒钟,你通常就会认为他已经说完了,然后开始回应。定时器模拟空闲中断也是类似的道理:
- 每次收到一个字节的数据,就相当于对方说了一个词
- 重置定时器就像是重置这个"停顿计时器"
- 当定时器超时,就相当于对方已经停顿得够久了,我们认为他已经说完了一句话
在技术上,这个"停顿时间"需要精心计算。通常我们以字节传输时间为单位,一般设置成3-5个字节的传输时间。为什么不是1个字节呢?因为要考虑到字节之间的间隔以及处理器的处理延迟。
2.2 超时时间的计算方法
超时时间的计算很关键,我来详细说一下具体的计算方法。假设我们使用115200的波特率,那么每个字节的传输时间可以这样计算:
1个字节包括:1个起始位 + 8个数据位 + 1个停止位 = 10位 每位时间 = 1 / 115200 ≈ 8.68μs 每个字节时间 = 10 × 8.68μs ≈ 86.8μs
如果我们设置超时时间为5个字节的时间,那么: 超时时间 = 5 × 86.8μs ≈ 434μs
在实际应用中,我一般会设置得稍微长一点,比如500μs到1ms,这样可以确保不会因为处理延迟而误触发。对于不同的波特率,这个时间需要相应调整。比如在921600波特率下,每个字节时间只有10.8μs,5个字节时间才54μs,这就需要更精确的定时了。
3. 硬件配置与SYSCFG设置
3.1 定时器模块的配置
在MSPM0G3507中配置定时器,我推荐使用TIMG通用定时器。具体配置参数如下:
// 定时器基础配置
DL_TimerG_setPeriod(Emm_V5_Time_INST, 0xFFFF); // 设置周期
DL_TimerG_setPrescaler(Emm_V5_Time_INST, 79); // 预分频器,80MHz主频下分频为1MHz
DL_TimerG_enableCounte


491

被折叠的 条评论
为什么被折叠?



