今天在使用STM32中的RTC时钟时,发现了一件奇怪的事情:配置好RTC时钟后,读取时钟发现时间并不会更新

不过之前在STM32F103中测试时是可以正常读取的,而且HAL库中读取RTC时钟十分方便,按理来说不应该如此。


HAL_RTC_GetTime(&hrtc,&Mytime,FORMAT_BCD);

HAL库获取RTC时间代码

  为了解决这个问题仔细查看一下STM32中关于RTC部分的参考手册。

 手册中提出,只要供电电压合适,RTC时钟就永远不会停止,但是无论是纽扣电池供电,还是电源直接供电,都无法正常读取时间,因此主要的可能是代码的问题。

 在用户手册中有这样子关于用户读取寄存器的描述:RTC的日期值和时钟值通过影子寄存器访问,在每个时钟周期后,RTC时钟的值被复制入影子寄存器。默认情况下我们访问的都是影子寄存器,当然这里提供了一种方法让我们直接读取存放日历值的寄存器。

  因此通过HAL库读取的当是影子寄存器的内容,而问题大概率可能是影子寄存器的值并没有更新而导致的。

  在后续关于读写的详细描述中,我找到了真相:

在读取SSR寄存器之后会锁定影子寄存器的值,直到读取RTC_DR寄存器后才会解锁。

  而SSR寄存器Sub-Second Register是亚秒寄存器,用来获取更精准的时间。

 而HAL_RTC_GetTime中便是对RTC_SSR的读操作,从而导致之后影子寄存器被锁住,在HAL库中的注释中我们也可以看到这个注意事项:

必须在调用HAL_RTC_GetTime之后调用获取日期的函数,以解锁RTC更新。

  因此我们在读取时间之后调用HAL_RTC_GetDate便可以解决RTC日期不更新的问题

为了解释这个问题,我们查看手册:

STM32是为了确保这三个值的一致性从而出现的这个机制。

  读时间的瞬间,硬件会冻结当前的「时间+日期」状态,防止用户在读时间的时候,导致的日期偷偷的跨天。而这样子的好处就是在跨天/月/年的时候先读时间,就可以锁住日期,这样子就不会导致日期的撕裂

  例如10月1日晚上23:59:59我读取了时间,然后日期更新成了10月2日,从而导致显示的就是10月2日晚23:59:59。时间和日期必须‘成对食用’,顺序错了就等着吃数据过期套餐吧!”


嘉立创PCB

还没有评论,抢个沙发!