绝大多数STM32系列里的RTC都具有亚秒【或称子秒】计数单元。为了了解亚秒特性及功能,不妨先看RTC的功能框图。本文中的有关截图若无特别说明均来自STM32L4系列参考手册。
RTC的时钟源【RTCCLK】可以是LSE、LSI或者HSE/32,由RTCCLK最终变成日历的秒脉冲驱动信号经过了2次分频。先经过上图中A处的异步分频单元,默认分频系数是128,形成ck_apre时钟,默认情况下该时钟频率为256Hz;然后该时钟脉冲来到图中B处的同步分频单元,默认分频系数为256,最终形成1Hz的秒脉冲【ck_spre】到日历单元。关于两分频单元分频系数的配置,通过对RTC_PRER寄存器的相关位编程实现。
其中异步分频系数配置位【PREDIV_A】有7位,同步分频系数【PREDIV_S】有15位。另外,同步分频单元还包括采用向下计数方式的亚秒计数器,它基于异步分频后的时钟ck_apre进行计数,溢出时的重装值等于PREDIV_S。一般来讲,它的一个计数周期就是1s,其计数分辨率或精度为【1/(PREDIV_S+1)】秒。与之配套的亚秒寄存器,实时记录亚秒计数器的计数值,有效数据位乃16位,比PREDIV_S多1位,多出的1位另有它用,此处不表。
显然,当有了这个亚秒计数器后,我们就可以获得少于1秒的时间,或说秒的小数部分---亚秒,其精度由同步分频系数PREDIV_S决定,某时刻的亚秒数通过亚秒寄存器获取,对应的亚秒时间可以通过上图中第2个红色方框内的算式求得【提醒:亚秒计数器采用向下计数方式】。
关于RTC的亚秒概念及基本特性就介绍到这里。稍微小结下:
1、亚秒是对少于1秒的时间称谓,范围在0到1秒,并非固定的值;
2、亚秒精度【分辨率】可调,由PREDIV_S参数决定,即【1/(PREDIV_S+1)】秒;
3、亚秒寄存器【RTC_SSR】实时记录亚秒计数器的值,具体由SS[15:0]体现;
4、亚秒时间通过算式(PREDIV_S-SS)/(PREDIV_S+1)求得;
我们知道RTC除了提供基本的日历功能外,还有很好的低功耗特性,常用于低功耗的唤醒。有些低功耗应用场合,虽然系统需要周期性的唤醒,但对唤醒周期的一致性要求往往并不严格、很多时候的周期值往往远达不到秒级,比方在10个毫秒上下、几十个毫秒左右、100毫秒量级不等。像这种场合,我们可以考虑使用RTC的亚秒特性和ALARM功能实现周期性唤醒。
假设某STM32用户有这样的需求,他的系统涉及低功耗,需要周期性地做休眠与唤醒的切换。他希望系统进入休眠后每隔50±20ms的时间范围内被唤醒,唤醒后做些基本的检测处理后又进入休眠。要实现这个需求,对于很多带LPTIM的STM32系列也很方便实现。
关键字:STM32
引用地址:
STM32片内RTC亚秒特性的应用示例(上)
推荐阅读最新更新时间:2024-11-11 21:48
STM32串口打印printf发送中文乱码问题
1、首先要确保使用keil程序正确编译,并且程序经过调试,已经可以正常发送英文字符,但是发送中文字符时乱码。 2、使用记事本打开main.c文件(或其他主程序),点击另存为,在右下方选择编码方式为ANSI,替换原文件即可
[单片机]
STM32学习记录8:DMA
官方的例子:STM32F10x_StdPeriph_Lib_V3.1.2\Project\STM32F10x_StdPeriph_Examples\DMA\FLASH_RAM /* DMA1 channel6 configuration */ DMA_DeInit(DMA1_Channel6); //peripheral base address 外设地址是自己的一个定义 //例如#define SPI1_DR_Addr ( (u32)0x4001300C ) DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer; //memory base
[单片机]
STM32之SPI通信
之前一直对SPI通信一知半解,所以想抽空把它搞得明白一些。考虑到之前是结合Flash芯片来学的,十分不直观,而且主要把时间和精力都花在Flash芯片的datasheet和驱动上了,SPI通信也没学好。所以这次就考虑用4位数码管显示模块,模块是直接买的现成的,如下图所示,这样可以简化操作,把精力聚焦到学习的核心–SPI通信本身上来。 该模块是用2片74HC595串联驱动的,一片用来控制数码管的位选(U1),一片用来控制数码管的段选(U2)。接口比较简单,总共5个引脚,2个引脚分别接VCC和GND,DIO用来接收串行数据的输入,SCLK用来接收同步时钟,每个SCLK上升沿74HC595内部的移位寄存器会移一位,RCLK用
[单片机]
STM32死机 调试时进入HardFault_Handler定位错误的方法
STM32在运行不正常的时候我们一般会进行调试看看问题出在了哪里。但是当STM32卡死后进行调试的时候会发现进入到了一个HardFault_Handler函数里,这是一个硬件错误处理函数。通过它和MDK配合可以定位程序最后卡死的原因。 STM32卡死的原因有以下几种:数组越界操作;内存溢出,访问越界;堆栈过小;中断处理错误;电压供电异常。 现在实验一个堆栈过小的错误,让MDK来检测这个问题然后定位错误。 这个程序基于UCOSII 系统 #define TFTLCD_STK_PRIO 8 //任务的优先级 #define TFTLCD_STK_SIZE 2 //任务的堆栈大小 OS_STK TFTLCD_TASK_S
[单片机]
stm32 EXTI中断BUG,无法进入外部中断的问题
我在调试程序时,发现有个EXTI中断怎样都无法进入,虽然查了网上各种经验,但对我的程序都没有帮助,后来终于发现问题了,原因是官方库函数有些问题。 情况是这样的。我的程序中有两个EXTI外部中断,假设为EXTI1和EXTI2,由于功能需要,在某个地方,我需要关闭EXTI1,一段代码之后再打开EXTI1。 void EXTI_Config2(void) { EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line1; EXTI_InitStructure.EXTI_LineCmd = DISABLE; EXTI_Clear
[单片机]
STM32学习之启动代码注释
;Reset_Handler 子程序开始 Reset_Handler PROC ;输出子程序Reset_Handler到外部文件 EXPORT Reset_Handler ;从外部文件引入__main函数 IMPORT __main ;从外部文件引入SystemInit函数 IMPORT SystemInit ;把SystemInit函数调用地址加载到通用寄存器R0 LDR R0, =SystemInit ;跳转到R0中保存的地址执行程序(调用SystemInit函数) BLX R0 ;把main函数调用地址加载到通用寄存器R0 LDR R0, =__main ;跳转到R0中保存的地址执
[单片机]
STM32 FSMC控制LCD功能讲解
在做项目的过程中遇到了这个问题,感觉文章写得不错,共享给对FSMC的使用怀有疑惑的同伴们! LCD有如下控制线: CS:Chip Select片选,低电平有效 RS:Register Select寄存器选择 WR:Write写信号,低电平有效 RD:Read读信号,低电平有效 RESET:重启信号,低电平有效 DB0-DB15:数据线 假如这些线,全部用普通IO口控制。根据LCD控制芯片手册(大部分控制芯片时序差不多): 如果情况如下: DB0-DB15的IO全部为1(表示数据0xff),也可以为其他任意值,这里以0xff为例。 CS为0(表示选上芯片,CS拉低时,芯片对传入的数据才会有效) RS为1(表示DB0-15上传递的是
[单片机]
stm32虚拟串口安装失败的原因
本人在网上也看到了好多说,按照以下步骤可以解决问题,但是不幸的是我的盗版系统不行: 将mdmcpq.inf复制到c:\windows\inf 将usbser.sys复制到c:\windows\system32\drivers 但是,还是借助于这个思路去找一些原因最后发现,在c:\windows\inf 文件夹下,有一个名叫mdmcpq2.inf的文件,突发奇想将2去掉试试可不可以,后来一试可以了,成功安装了!
[单片机]