Embedded 微控制器中确定系统时间的标准方法

Embedded 微控制器中确定系统时间的标准方法,embedded,arm,microcontroller,rtos,cortex-m,Embedded,Arm,Microcontroller,Rtos,Cortex M,每隔一段时间,我就开始一个裸机微控制器项目,最后用一个随机定时器实现一个系统时间测量 我现在正在使用ARM Cortex-M设备工作一段时间(虽然时间很短),通常使用SysTick(“系统滴答”)中断来创建1ms分辨率计时器。它最近无意中发现了一篇帖子,该帖子建议链接两个可编程中断计时器(在Kinetis KL25Z设备上),以创建一个中断小于32位毫秒的计时器,但是牺牲了两个PIT中断,这可能会在以后派上用场 因此,我想知道是否有一些(某种)标准方法来确定微控制器上的系统时间-最好是针对Kin

每隔一段时间,我就开始一个裸机微控制器项目,最后用一个随机定时器实现一个系统时间测量

我现在正在使用ARM Cortex-M设备工作一段时间(虽然时间很短),通常使用
SysTick
(“系统滴答”)中断来创建1ms分辨率计时器。它最近无意中发现了一篇帖子,该帖子建议链接两个可编程中断计时器(在Kinetis KL25Z设备上),以创建一个中断小于32位毫秒的计时器,但是牺牲了两个
PIT
中断,这可能会在以后派上用场


因此,我想知道是否有一些(某种)标准方法来确定微控制器上的系统时间-最好是针对Kinetis KL2xZ设备,因为我目前正在使用这些设备,但不一定如此。

您所说的标准方法与您所做的完全相同-使用systick。即Cortex-M架构定义的单定时器设备;任何其他定时器硬件都是核心外部的,并且是特定于供应商的

某些部件(例如STM32F2)包括32位计时器/计数器硬件,因此不需要将两个部件连接起来

最好的方法是通过定义一个通用的计时器API来抽象计时器服务,您可以为所有需要的部分实现该API,这样所有部分的应用程序层都是相同的。例如,在这种情况下,您可以简单地实现标准库并定义
每秒时钟数

如果使用两个自由运行的级联定时器,则在组合两个计数器值时,必须确保高/低字一致性:

#include <time.h>

clock_t clock( void )
{
    uint16_t low_word = 0 ;
    uint16_t hi_word = 0 ;

    do
    {
        hi_word = readTimerH() ; 
        lo_word = readTimerL() ;

    } while( hi_word != readTimerH() ) ;

    return (clock_t)(hi_word << 16 | lo_word) ;
}
#包括
时钟(无效)
{
uint16\u t low\u word=0;
uint16\u t hi\u word=0;
做
{
hi_word=readTimerH();
lo_word=readTimerL();
}while(hi_word!=readTimerH());

return(clock_t)(hi_word您所说的规范方法与您所做的完全相同-使用systick。这是Cortex-M架构定义的单定时器设备;任何其他定时器硬件都是核心外部的,并且是特定于供应商的

某些部件(例如STM32F2)包括32位计时器/计数器硬件,因此不需要将两个部件连接起来

最好的方法是通过定义一个通用的计时器API来抽象计时器服务,您可以为所有需要的部件实现该API,以便所有部件的应用程序层都是相同的。例如,在这种情况下,您可以简单地实现标准库并定义
CLOCKS\u PER\u SEC

如果使用两个自由运行的级联定时器,则在组合两个计数器值时,必须确保高/低字一致性:

#include <time.h>

clock_t clock( void )
{
    uint16_t low_word = 0 ;
    uint16_t hi_word = 0 ;

    do
    {
        hi_word = readTimerH() ; 
        lo_word = readTimerL() ;

    } while( hi_word != readTimerH() ) ;

    return (clock_t)(hi_word << 16 | lo_word) ;
}
#包括
时钟(无效)
{
uint16\u t low\u word=0;
uint16\u t hi\u word=0;
做
{
hi_word=readTimerH();
lo_word=readTimerL();
}while(hi_word!=readTimerH());

return(clock_t)(hi_word我刚刚查阅了KL25子系列参考手册。 在第34章实时时钟(RTC)第34.3.2节时间计数器中(可能与文件版本不同)。 我发现RTC中有两个定时器计数器寄存器

  • 32位秒计数器
  • 每32.768 kHz时钟周期递增一次的16位预分频器寄存器

  • 参考手册上说

    在写入秒寄存器之前,始终写入预分频器寄存器, 因为秒寄存器在预分频器第14位的下降沿递增 注册。 这意味着要计算系统时间,请读取rtc_sec_计数器并添加14位prescalar_reg 您甚至可以创建一个宏,通过rtc_secu_计数器和prescalar_reg或sec(显然是通过rtc_secu_计数器)的组合,以uSec和mSec表示系统时间

    对于16位prescalar REG,系统时钟为32.768 Khz,使用此时钟,我们可以创建宏以uSec和mSec表示时间

    #define PRESCALAR_TICK 32768
    #define KHZ            1000
    #define MHZ            1000000
    
    /// Here first we extract 14bit value of prescalar_reg and than multiply it with MHZ to get better precision 
    /// but this value will not go more than 14 Bit
    #define GET_SYS_US     ((((prescalar_reg & 0x03FFF)*MHZ)/PRESCALAR_TICK))
    #define GET_SYS_MS     (GET_SYS_US)/KHZ)
    
    if you need time in milliseconds up to 32 bit use below macro 
    #define GET_SYS_US_32bit ((rtc_sec_counter * 0x3FFF) + GET_SYS_US)
    #define GET_SYS_MS_32bit ((rtc_sec_counter * 0x3FFF) + GET_SYS_MS)
    

    但要使用这些信息,您必须初始化您的RTC micro(显然)

    我刚刚查阅了KL25子系列参考手册。 在第34章实时时钟(RTC)第34.3.2节时间计数器中(可能与文件版本不同)。 我发现RTC中有两个定时器计数器寄存器

  • 32位秒计数器
  • 每32.768 kHz时钟周期递增一次的16位预分频器寄存器

  • 参考手册上说

    在写入秒寄存器之前,始终写入预分频器寄存器, 因为秒寄存器在预分频器第14位的下降沿递增 注册。 这意味着要计算系统时间,请读取rtc_sec_计数器并添加14位prescalar_reg 您甚至可以创建一个宏,通过rtc_secu_计数器和prescalar_reg或sec(显然是通过rtc_secu_计数器)的组合,以uSec和mSec表示系统时间

    对于16位prescalar REG,系统时钟为32.768 Khz,使用此时钟,我们可以创建宏以uSec和mSec表示时间

    #define PRESCALAR_TICK 32768
    #define KHZ            1000
    #define MHZ            1000000
    
    /// Here first we extract 14bit value of prescalar_reg and than multiply it with MHZ to get better precision 
    /// but this value will not go more than 14 Bit
    #define GET_SYS_US     ((((prescalar_reg & 0x03FFF)*MHZ)/PRESCALAR_TICK))
    #define GET_SYS_MS     (GET_SYS_US)/KHZ)
    
    if you need time in milliseconds up to 32 bit use below macro 
    #define GET_SYS_US_32bit ((rtc_sec_counter * 0x3FFF) + GET_SYS_US)
    #define GET_SYS_MS_32bit ((rtc_sec_counter * 0x3FFF) + GET_SYS_MS)
    

    但要使用这些信息,您必须初始化micro的RTC(显然)

    不幸的是,开发板配备了8 MHz石英,但RTC需要外部32.x kHz石英。可以使用内部32k振荡器,但这可能不是解决方案。否则,这是个好主意。不幸的是,开发板配备了8 MHz石英,但RTC需要外部32.x kHz石英。有是一个内部32k振荡器,可以使用,但这可能不是解决方案。好主意,否则。