STM 专为需要高精度和长周期的整体系统计时应用而设计。STM 具有以下特点:
- 自由运行的 64 位计数器
- 所有 64 位可以同步读取
- 可以同步读取 64 位计数器的不同 32 位部分
- 基于与部分STM内容比较匹配的灵活服务请求生成
- 应用程序重置后自动开始计数
- 如果 ARSTDIS.STMxDIS 位清零,则 STM 寄存器由应用复位复位。 如果 ARSTDIS.STMxDIS 位置位,则 STM 寄存器不会被应用程序复位复位,而是由系统复位复位。
特殊的STM寄存器语义以不同的分辨率提供整个64位计数器或32位子集的同步视图。 STM 是一个向上计数器,以 f(STM) 频率运行。 在应用程序复位的情况下,如果位 SCU_ARSTDIS.STMxDIS 被置零,则 STM 被复位。复位后,STM 被使能并立即开始向上计数。 在正常操作期间不可能影响定时器的内容。 定时器寄存器只能读不能写。
STM 可以选择禁用以节省电力,或暂停以进行调试。 在挂起模式下,STM 时钟停止,但所有寄存器仍然可读。
由于 STM 的 64 位宽度,不可能用一条指令读取其全部内容。 它需要用两个加载指令来阅读。 由于定时器会在两次加载操作之间继续计数,因此读取的两个值有可能不一致(由于可能在两次读取操作之间从定时器的低部分溢出到高部分)。为了实现 STM 内容的同步和一致读取,实现了捕获寄存器 (CAP)。 每次读取寄存器 TIM0 至 TIM5 之一时,它会锁存 STM 高位部分的内容。 因此,CAP 保持定时器的上限值与读取下部分的时间完全相同。 然后第二个读取操作将读取 CAP 的内容以获取完整的计时器值。
STM 也可以从七个寄存器(TIM0 到 TIM6)中分段读取,这些寄存器选择 STM 的越来越高阶的 32 位范围。 这些可以被视为单独的 32 位定时器,每个定时器具有不同的分辨率和时序范围。
64 位系统定时器的内容可以与存储在 CMP0 和 CMP1 寄存器中的两个比较值的内容进行比较。 可以在 STM 与 CMP0 或 CMP1 寄存器的比较匹配时生成服务请求。
27.3.1 to be continued
下表列出了 STM 与其他模块的接口。
获取STM时间示例程序
STM_System_Time.c
#include "STM_System_Time.h"
#include "IfxStm.h"
#define DAY_IN_SECONDS 86400
#define HOURS_IN_SECONDS 3600
#define MIN_IN_SECONDS 60
systemTime g_time;
void getTime(void)
{
g_time.totalSeconds = IfxStm_get(&MODULE_STM0) / IfxStm_getFrequency(&MODULE_STM0);
g_time.days = g_time.totalSeconds / DAY_IN_SECONDS;
g_time.hours = (g_time.totalSeconds - (g_time.days * DAY_IN_SECONDS)) / HOURS_IN_SECONDS;
g_time.minutes = (g_time.totalSeconds - (g_time.days * DAY_IN_SECONDS) - (g_time.hours * HOURS_IN_SECONDS)) / MIN_IN_SECONDS;
g_time.seconds = (g_time.totalSeconds - (g_time.days * DAY_IN_SECONDS) - (g_time.hours * HOURS_IN_SECONDS) - (g_time.minutes * MIN_IN_SECONDS));
}
STM_System_Time.h
#ifndef STM_SYSTEM_TIME_H_
#define STM_SYSTEM_TIME_H_
#include "Ifx_Types.h"
typedef struct
{
uint64 totalSeconds;
uint64 days;
uint64 hours;
uint64 minutes;
uint64 seconds;
} systemTime;
void getTime(void);
#endif
STM_Interrupt.c
#include "STM_Interrupt.h"
#include "Bsp.h"
#include "IfxPort.h"
#include "IfxStm.h"
#define ISR_PRIORITY_STM 40
#define TIMER_INT_TIME 500
#define LED &MODULE_P13,0
#define STM &MODULE_STM0
IfxStm_CompareConfig g_STMConf;
Ifx_TickTime g_ticksFor500ms;
void initLED(void);
void initSTM(void);
IFX_INTERRUPT(isrSTM, 0, ISR_PRIORITY_STM);
void isrSTM(void)
{
IfxStm_increaseCompare(STM, g_STMConf.comparator, g_ticksFor500ms);
IfxPort_setPinState(LED, IfxPort_State_toggled);
}
void initLED(void)
{
IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinState(LED, IfxPort_State_high);
}
void initSTM(void)
{
IfxStm_initCompareConfig(&g_STMConf);
g_STMConf.triggerPriority = ISR_PRIORITY_STM;
g_STMConf.typeOfService = IfxSrc_Tos_cpu0;
g_STMConf.ticks = g_ticksFor500ms;
IfxStm_initCompare(STM, &g_STMConf);
}
void initPeripherals(void)
{
g_ticksFor500ms = IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, TIMER_INT_TIME);
initLED();
initSTM();
}
STM_Interrupt.h
#ifndef STM_INTERRUPT_H_
#define STM_INTERRUPT_H_ 1
void initPeripherals(void);
#endif
|