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

STM32H7/L4定时器更改周期之后的前两个周期输出异常

[复制链接]
邓达达 提问时间:2023-5-8 11:11 / 未解决

将STM32定时器计数周期设为0xFF(累加256次溢出),比较值设为0x7F,在某一时刻将新的计数周期0x7F与比较值0x3F加载到影子寄存器(即,在当前计数周期结束后,新的周期值将自动加载,也就是不立即更新)。当正在进行的一个周期结束后,经示波器测量确实可以看到其下一个周期发生了变化,但其周期明显与预设值对应不上!再次经过一个周期,定时器才可安照预设值稳定输出。

目前已在H7/L4上发现此问题,定时器分频系数为1。此外,使用定时器输出PWM时也有相同情况出现,即改变PWM频率后的前两个周期输出不对。也有网友提及但未解决。

可简单通过cubeMX配置定时器,随后在比较中断内翻转IO,经示波器测量复现此问题。

收藏 评论30 发布时间:2023-5-8 11:11

举报

30个回答
邓达达 回答时间:2023-5-12 11:00:38
xmshao 发表于 2023-5-11 07:49
[md]昨天我找STM32L4开发板做了测试,用TIM1-CHI1.

按照你目前给出的操作步骤,输出是合理的、正确的。 ...

感谢提供帮助
昨天我复现了一下问题,按照步骤操作确实不存在任何问题
这是我的疏忽,实在抱歉,,,

仅将第一步中“开启比较中断”,放到第二步中设定ARR、CCR之后,即可复现这个问题,仅需将源码改动一行即可!

---------------------------------------------------------------------------------------------------------------------------------------------------------

确实利用在了特殊用途,简单看看就好,不作为讨论内容
邓达达 回答时间:2023-5-12 11:10:40
xmshao 发表于 2023-5-11 07:49
[md]昨天我找STM32L4开发板做了测试,用TIM1-CHI1.

按照你目前给出的操作步骤,输出是合理的、正确的。 ...

[md]感谢提供帮助
昨天我复现了一下问题,按照步骤操作确实不存在任何问题
这是我的疏忽,实在抱歉,,,

*仅将第一步中“开启比较中断”,放到第二步中设定ARR、CCR之后,即可复现这个问题,仅需将源码改动一行即可!***

---

确实利用在了特殊用途,简单看看就好,不作为讨论内容
邓达达 回答时间:2023-5-9 14:00:34

xmshao 发表于 2023-5-9 09:43
为了保证输出波形完整性,建议你开启ARR及CCR的预装功能,在CubeMx配置时选择下即可。</p>
<p>开启预装后,修 ...

[md]首先感谢回答。您的建议在之前已有考虑,问题并未解决


首先是ARR与CCR的预装载使能/失能问题,可使用如下2个宏函数接口实现

使能预装载

image.png

失能预装载

image.png

当然亦可通过CUBEMX内的配置项自动生成初始化代码


关于函数调用时间,在此均采用了ST提供的HAL库宏函数接口更新CCR/ARR的值,在确保程序可读性及可移植性的情况下,最大限度的节约寄存器操作时间

image.png


此问题的简单复现方案如下

第一步:

1 - 关闭预装载(ARR/CCR)

2 - 设定ARR=CCR=0xFF

3 - 开启比较中断(连接到示波器可查看周期)

第二步:

1 - 设置触发(延迟一段时间拉高某个IO引脚以触发示波器采集,注意使用位带操作节省操作时间)

2 - 立即清空CNT

3 - 使能预装载

4 - 设定ARR=0X7F,CCR=0X3F

5 - 再次拉低IO,IO高电平持续时间即为寄存器操作总耗时

简要解释:清空CNT后,定时器仍按之前参数运行,在当前计数周期结束后将同步更新ARR/CCR的值,随后根据新的参数运行

现象:本周期结束后其计数周期确实会相应改变,但改变之后的前两个周期明显与设定值不符,经过2个周期后才可稳定输出

可查看示波器输出,寄存器操作总耗时远远小于定时器先前与当前的计数周期。所以并不是操作时间过长导致。


还请大神不吝赐教,感谢!

image.png
xmshao 回答时间:2023-5-8 11:51:12
为了保证输出波形完整性,建议你开启ARR及CCR的预装功能,在CubeMx配置时选择下即可。


开启预装后,修改ARR及CCR的值,生效时间点最长可能延后1个计数周期。


不过这里要注意下,你修改ARR及CCR的值最好在一个计数周期内完成,不要一个在某更新事件之前


完成赋值,另一个则在该更新事件之后完成赋值。
xmshao 回答时间:2023-5-9 09:43:50

为了保证输出波形完整性,建议你开启ARR及CCR的预装功能,在CubeMx配置时选择下即可。

开启预装后,修改ARR及CCR的值,生效时间点最长可能延后1个计数周期。

不过这里要注意下,你修改ARR及CCR的值最好在一个计数周期内完成,不要一个在某更新事件之前完成赋值,另一个则在该更新事件之后完成赋值。

xmshao 回答时间:2023-5-9 16:06:13
提醒下你,你第一步设置的ARR=CCR=0xff,此时设置完就生效了。


第2步,先对 计数器清零并开启预装功能,然后修改ARR=CCR=7F,3F,这两个数据还不能
立即生效。


这两个数据要等计数器刚才清零开始后一直计到之前的FF后 发生更新事件才能令新值7F,3F生效。


后面的输出才是按照ARR=7FF,CCR=3F运行。


这里的核心就是预装问题,你不妨好好琢磨下。
邓达达 回答时间:2023-5-9 18:06:41
xmshao 发表于 2023-5-9 16:06
提醒下你,你第一步设置的ARR=CCR=0xff,此时设置完就生效了。


你的回答以及分析就是我本来想要的结果,也是理论上的结果
如你所述:“后面的输出才是按照ARR=7FF,CCR=3F运行”
实际结果是:并未安按照ARR=7FF,CCR=3F运行。。。
你可以用示波器简单进行复现,根本不会按照你的分析(亦即理论效果)去执行
xmshao 回答时间:2023-5-10 09:49:29
邓达达 发表于 2023-5-9 18:06
你的回答以及分析就是我本来想要的结果,也是理论上的结果
如你所述:“后面的输出才是按照ARR=7FF,CCR=3 ...

好,我找个L4开发板测试后 再回复你结果。
butterflyspring 回答时间:2023-5-10 11:39:56
按照手册上来说,在第五步之前(拉低IO口)增加一步,置位 UG位,这样当前开始的周期就应该是设定值~~~
xmshao 回答时间:2023-5-10 15:11:13
基于你的反馈,我这边做了些测试。结论是没有发现理论上说不通的地方。


参照你的操作手法,从你修改数据时刻算起,必须 延时一整个原计数周期,即相当于后来2个计数周期后才启用
新的配置参数。


具体修改时你是这样操作的:


先  对计数器做了清零,然后  开启预装载功能,再 修改ARR和CCR的值。这时计数器所以的ARR和CCR依然是0xff和0x7f,
而且从0开始计数并执行相应PWM输出。也就是说从修改操作时刻开始,一直要等计数0xff+1个时钟后新数据才能生效,
这个延时刚好对应2个新周期。这个2倍关系是个巧合,跟你当前设置的数据有关。


如果你不希望 一定 延时这么久,你在更新ARR和CCR时不必要清零,不知你为何这里要清零。其实你保证在上个周期
修改完即可,这样的话,最长延时虽然还是一个原周期,但不是必须或总是,具体与你修改数据的时间点有关。


还有,你为什么不一开始就开启预装功能,非要等到修改数据时开启预装呢?你这样操作不就是表示你希望开启预装,
保持波形完整性吗?
邓达达 回答时间:2023-5-10 15:32:38
butterflyspring 发表于 2023-5-10 11:39
按照手册上来说,在第五步之前(拉低IO口)增加一步,置位 UG位,这样当前开始的周期就应该是设定值~~~
...

置位UG位确实会直接产生更新,但这样做的话,那么预装载寄存器的作用将毫无意义,仍然感谢您的回答,谢谢!
xmshao 回答时间:2023-5-11 07:49:46

xmshao 发表于 2023-5-10 09:49
好,我找个L4开发板测试后 再回复你结果。

昨天我找STM32L4开发板做了测试,用TIM1-CHI1.

按照你目前给出的操作步骤,输出是合理的、正确的。即从修改时刻算起到数据生效

必须 注意是必须要等一个完整的旧周期,这里也刚好等于2个后来的新周期宽度。

如果说,抹掉第二步中的清零环节,具体延时取决于你修改参数的时间点,但不会宽过1个旧周期,

生效延时最短极限为0。

还有,你既然关心波形完整性,为何 不一开始就开启预装呢?这样更为简单。或许你有特别的应用

考量吧。

邓达达 回答时间:2023-5-15 09:56:37
xmshao 发表于 2023-5-11 07:49
[md]昨天我找STM32L4开发板做了测试,用TIM1-CHI1.

按照你目前给出的操作步骤,输出是合理的、正确的。 ...

前两天回复了两次,一直提示正在审核,在这里重新回复试一下
邓达达 回答时间:2023-5-15 10:24:33

xmshao 发表于 2023-5-11 07:49
昨天我找STM32L4开发板做了测试,用TIM1-CHI1.</p>
<p>按照你目前给出的操作步骤,输出是合理的、正确的。 ...

[md]可以回复了,前两天打了好多字,提示正在审核就没动静了

首先还是感谢提供帮助

确实抱歉,按照上述步骤确实没有问题。

若想复现之前的问题,仅更改一行代码即可。。。


将第一步中的“开启比较中断”,放到第二步中的“更改ARR、CCR之后”即可复现问题


确实是用作了特殊用途,在信号的解调以及解码方面,信号以改进的数字米勒编码进行传输,拥有起始位数据位校验位和结束位。根据每个bit传输周期的前半周期被调制还是后半周期被调制代表数字信号0或1;起始位会触发外部中断,随后通过定时器延时一个bit传输周期,然后每半个传输周期采样一次,采样点位于每半个周期的1/4处。这样就可以完成采样。

硬件电路已进行了相应处理,包括信号检波、包络信号放大、滤波等处理

程序实现方案是通过外部中断检测上升沿来判定起始位的到来,随后关闭定时器预装载功能,将定时器周期设为一个bit传输周期,比较值同样设为一个bit传输周期,CNT清零并开启定时器,此时开启预装载功能,将周期设为半个bit传输周期(半个周期采样一次),比较值设为1/8周期(半bit周期的1/4处采样),并打开中断。

定时器执行流程:定时器将在完成一个bit周期的计数后触发比较中断,此时刚刚好处在起始位之后,第一个数据位之前。当发生中断后,也意味着定时器周期变为了半个bit周期,比较值变为了半个bit周期的1/4,随后将在半个bit周期内的1/4出再次触发比较中断,完成第一个数据bit的前半段采样,随后同理,完成第一个数据bit的前后段采样,完成第二个数据bit的前半段采样,。。。。。。。

此方案已在其他MCU中验证通过,STM32的问题在于,当第一次比较中断发生后,其周期也随之改变,但不会按预装载值改变,复现此问题仅将第一步中的开启比较中断放在第二步中更改ARR、CCR之后即可。

感谢回复!

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