STM32硬件定时器
总览
SYSTICK
首先我们知道,STM32F103单片机使用的是ARM内核,内核可以理解为是一个计算单元,与串口/I2C/SPI一样,作为设备由ST公司的设计师整合在一颗芯片上。STM32F103使用的ARM内核型号是Cortex-M3,该内核内部自带一个非常简化的定时器模块,仅需通过几条命令,就可以初始化该定时器并启动产生定时中断。
SYSTICK作为内核模块的一个组件,其时钟速度与内核时钟一样,STM32F1配置为72MHz
SYSTICK是向下计数 自动重载定时器,即给定LOAD寄存器初始值为999,启动定时器后,999被加载到计数寄存器中,每过1/72*1000*1000秒计数值就会自动减一,当减到-1时(寄存器发生溢出),会重新从LOAD寄存器加载数值,并进行新一轮的递减。如果CTRL开启了中断,则减到-1时,会触发SysTick_Handler中断
core_cm3.h下,包含了systick的初始化代码
/** * @brief Initialize and start the SysTick counter and its interrupt. * * @param ticks number of ticks between two interrupts * @return 1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate * periodical interrupts. */ static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ SysTick->VAL = 0; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ }
基本定时器
通用定时器
通用定时器相比于基本定时器,多了PWM、输入捕获/比较、中央计数模式等,但对于初学者来说,对通用定时器仅需掌握PWM的应用即可
PWM就是设置一个比较值,再选定一个引脚用于PWM输出当计数值小于比较值时,引脚输出低电平;当计数值大于比较值时,引脚输出高电平
因此PWM的周期就是定时器周期,PWM的占空比(高电平占整个周期的比值),则由比较值来确定。通过修改定时器的周期和比较值,就可以灵活的控制PWM的周期和占空比。
无论定时器模式为向上或向下,都可以通过比较值选择占空比
通常一个定时器有多个通道,每个通道可以理解为一个定时器子模块
RTC
Real-Time Clock是一个独立的定时器。STM32的RTC模块有一组连续计数的计数器,可提供时钟日历的功能。RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变,只要后备区域供电正常,那么 RTC 将可以一直运行。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前,先要取消备份区域(BKP)写保护。
RTC通常使用外部低速时钟(LSE)作为外设时钟源,通常LSE的使用32.768K晶振提供时钟。经过RTC的分频器分频后,产生1HZ频率信号给到RTC计数器。因此RTC计数值每1s增加一次,实现秒数的自增
RTC模块使用LSE时钟,而主控使用HSE时钟,RTC模块寄存器的改动响应速度是32KHZ,而主控访问RTC寄存器的速度则是72MHZ。在巨大的时钟差异下,主控在修改RTC寄存器的时候,需要等待RTC操作完成
时间戳(timestamp)
STM32F1的RTC计数器仅能计算秒数,那秒数如何转换成年月日时分秒呢?
UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从UTC1970年1月1日0时0分0秒起至现在的总秒数。因此我们只需要设计一个算法,可以将时间戳转换为本地时间,和本地时间转换为UNIX时间戳,就可以完成人类所理解的时间和单片机对时间的转换。
作者:orionyl