- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
STM32定时器更新事件可以暂停否?
有人使用STM32的定时器的输出比较功能,具体就是输出4个通道的PWM信号。不过 他需要不定时地调整4个通道的占空比,即调整他们的CCR值。但现在有个小问题,那就是新的CCR值的获得往往会能跨越多个目前定时器的计数周期,这样的话,即使开启各个通道CCR值的预装功能,似乎也很保证做到一次性修改。因为它希望新的CCR值被同时更新。换句话说,他担心不同通道新的CCR值分散在不同计数周期生效,可能给应用带来些麻烦。
我们知道,STM32定时器的预装寄存器的值到影子寄存器的更新往往离不开更新事件。一般来讲,只要启动了定时器,更新事件会随着计数器的溢出而自然产生。
既然这样,比方若是在下面四个时刻获得了新的CCR值,有没有办法让这几个值同时实施更新,而不是分布在不同时刻生效呢?
其实是可以的。有两种方法可以参考,但有个共同的前提,就是开始做新数据准备时,先把定时器更新事件的产生允许关闭,因为STM32定时器更新事件最终是否产生是可以软件控制的,我们可以等数据都准备好了再允许定时器更新事件的产生。通过对TIMER控制寄存器的UDIS位置1或清零达到关闭或允许更新事件的产生的目的。
在这个前提下,我们可以有两种做法。
第一种,在准备新数据时,先通过对UDIS写1禁止更新事件的产生,同时开启CCR的预装功能,然后就可以悠闲地给各通道的CCR寄存器写新值了,不必担心它会生效,此时我们只是写进了CCR的预装寄存器。等到4个通道的新值都写进各自CCR预装寄存器后,再将更新事件位UDIS清零以允许定时器更新事件产生,数据更新的事就交给后续更新事件来完成,不必担心生效先后问题。
还有一种做法,那就是用户根本不直接对CCR进行改写操作,而是先将4个通道的新数据放在连续的内存里,借助定时器事件的DMABurst传输功能一次性完成修改。
大致流程是,先通过对UDIS写1禁止更新事件产生,然后将4个通道的新的CCR数据按照CCR1、CCR2、CCR3、CCR4的顺序放在内存,配置基于定时器更新事件的DMA Burst传输功能。即一个定时器事件可以触发DMA完成多个定时器寄存器与内存间的一次性传输。
此时,4个通道的CCR寄存器的预装功能可以开启,也可以不开启,但是几个通道的配置要保持一致,不要有的通道开启、有的不开启,否则反而不能保证几个通道参数的同步修改。
针对第2种做法,这里简单示范下实现过程。这里以STM32G4系列的TIM4来设计的。
上图中红线配置提示开启了CCR寄存器的预装功能。前面说了也可以同时都不开启。
使用CubeMx配置后生成HAL库工程代码,添加用户代码。我定义一个4字大小的数组
CCR_Data【4】用来存放新的CCR数据。下面代码实际上是我模拟反复调用的,在别的地方动态修改NewDataOK的值。
if(NewDataOK)
{
//Prohibit Update event ’generation since now
TIM4-CR1|=(TIM_CR1_UDIS);
NewDataOK =0;
CCR_Data[0]=CCR1_Value;
CCR_Data[1]=CCR2_Value;
CCR_Data[2]=CCR3_Value;
CCR_Data[3]=CCR4_Value;
HAL_DMA_Abort(hdma_tim4_up);
htim4.DMABurstState= HAL_DMA_BURST_STATE_READY;
HAL_TIM_DMABurst_WriteStart(htim4,TIM_DMABASE_CCR1, TIM_DMA_UPDATE,CCR_Data[0],TIM_DMABURSTLENGTH_4TRANSFERS);
__HAL_TIM_CLEAR_FLAG(htim4,TIM_FLAG_UPDATE);
//Update event generation allowed now
TIM4-CR1 =~(TIM_CR1_UDIS);
}
其中,HAL_TIM_DMABurst_WriteStart()函数是Cube库里现存的,它实现从内存到定时器寄存器的BURST传输。还有一个函数HAL_TIM_DMABurst_ReadStart()实现从定时器寄存器到内存的BURST传输。
下面截图是测试结果,各个通道同步变化:
我给的测试数据4个通道都是一样的,示波器只接了3个通道。
上面重点分享了定时器更新事件的产生可以通过软件关闭或开启的这个特性,我们可以在以后STM32开发应用中灵活运用。 不过,请不要把定时器更新事件是否可以产生跟更新事件源混为一谈。这里讨论的是更新事件产生的允许问题,而更新事件源则讨论的是更新事件怎么来的,它可以因计数器的溢出、工作在复位模
原创力文档


文档评论(0)