咋看题目,貌似有点情感类文字了。呵呵,当然不是,至少不完全是。这里是指在MCU开发过程中不要完全无视或忽视复位后各模块的初始状态及各寄存器的默认初始值的意思。
我们知道,除了个别模块或寄存器在MCU复位后其初始值或初始状态是不确定的外,其它模块及相应寄存器都呈现一个确定的初始状态或初始值。由于这些复位后的初始状态或初始值可能跟我们应用开发所期待的不一致,常常在应用程序的开始部分重新根据实际需求对相关寄存器做初始化配置。其中有些寄存器对用户来说是只读的,用户程序一般不必自行手动初始化。但这也并不代表我们对这类寄存器可以完全视而不见或置之不理,比方状态寄存器。我们使用相关外设时,往往需要对相关状态寄存器的初始值加以关注或使用。 这里以某论坛上的一个咨询帖的一个案例具体聊聊。某STM32用户咨询如下: STM32F103的通用定时器,设置了TIM2的基本时基(使能了计数器溢出中断),并没有用CCRx,但是到了第一次及以后计数器溢出,TIM2_SR的CCxIF都被置'1'了。这是为什么呀!纠结了很久。。。。 void TIM2_IRQHandler(void) { TIM2->SR=~0x0001;// TIM_ClearFlag(TIM2, TIM_FLAG_Update);// GPIOB->ODR^=0X0001; } 咨询者使用STM32F103 的TIM2 作基本的计数定时功能,溢出中断里做GPIO的翻转动作。令他纠结郁闷的是,为什么都没使用IC/OC这些功能,SR里的CCxIF怎么会被置1了?!
查看手册中令咨询者感到疑惑的CCxIF位,它是定时器x通道的捕捉或比较中断标志位。该位真正状态含义取决于该通道是配置为IC还是OC。那问题来了,以通道1为例,现在用户没有配置它,那通道1在芯片复位后默认的初始状态到底是IC还是OC呢? 某定时器通道是做IC还是OC,得看TIMx_CCMRn寄存器中的CCnS位。
结合上面截图描述,一目了然,定时器CC1通道在MCU复位后默认为OC模式,那再回头看SR寄存器里的初始值及相关描述。 本来,CC1IF位复位后的初始值为0,但由于咨询者只使用基本的计数定时功能,没有开启CC功能,未对相关寄存器做额外的初始化,CC1通道维持默认的OC模式,CCR1维持默认值0;虽然CNT的值在不停的变化,但也是从0到ARR间变化。当CNT= 0时,其值与CCR1的值匹配导致CC1IF被硬件置1也就不奇怪了。
具体结合到本案,咨询者主要是纠结于想搞清是怎么回事,以解心头之郁闷。具体应用时他可以不予理睬,不开启相关中断就好。
其实,我们在MCU应用开发过程中因为忽视或无视某些寄存器的默认值而遇到些让人迷惑不解的情况还很多。这里顺便再提个比较常遇见的一个关于ST MCU 的UART 状态寄存器默认初始值的话题。
STM32各系列的UART状态寄存器的不同系列间在具体内容和标志位的清零方面还略有差异,细节请查看各系列参考手册相关部分。但芯片复位后其初始值均为0x000000C0,其中的TXE/TC标志复位后的初始值为1。在ST MCU UART应用中有时因为忽视这两个初始值,遇到麻烦一下子找不到原因。比方第一个数据发送失败;还没开始发送数据就没完没了进UART发送中断啊诸如此类的事情。
从下面两副截图可以看出STM32F0与STM32F1在UART 的TXE标志清零方式是有差异的。
这里说的都是些温馨提示,提醒在MCU产品开发过程中不要完全忽视各模块及寄存器的默认初始值,没啥高深莫测的东西。不是古语有云:天下难事做于易,天下大事做于细嘛!
诚然,目前ST MCU的开发生态系统非常强大和方便,尤其STM32CubeMxg工具和STM32Cube库让STM32 的开发变得更为简单方便,但在开发应用中遇到问题时还是不可无视技术手册,尤其是那些细节和注意事项。
很多时候产品开发过程中遇到的问题能否尽快解决,除了理论基础外,往往还跟你内心的淡定度、查看手册或线路的细致度以及做事的条理性不无关系。 写上这些,与大家分享共勉。勿忘初始,勿忘初心,祝君好运!
|