TC397 STM(System Timer)

STM系统定时器的使用与中断处理
本文档详细介绍了STM(System Timer Module)的特性,如64位计数器、同步读取和复位功能。STM在应用程序复位后自动开始计数,并可通过捕获寄存器实现一致性读取。STM还可以通过比较寄存器产生服务请求。示例程序展示了如何获取系统时间并转换为天、小时、分钟和秒。同时,STM_Interrupt.c文件中提供了中断服务例程,用于设置STM比较触发中断,并在中断服务中更新比较寄存器和LED状态。

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

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "STM_System_Time.h"
#include "IfxStm.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define DAY_IN_SECONDS      86400                                   /* Define the number of seconds in one day      */
#define HOURS_IN_SECONDS    3600                                    /* Define the number of seconds in one hour     */
#define MIN_IN_SECONDS      60                                      /* Define the number of seconds in one minute   */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
systemTime g_time;                                      /* Instance of the structure time to store the system time  */

/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* This function gets the system time and converts it in days hours minutes and seconds */
void getTime(void)
{
    /* Get the system time (since the last reset of the microcontroller) in seconds */
    g_time.totalSeconds = IfxStm_get(&MODULE_STM0) / IfxStm_getFrequency(&MODULE_STM0);

    /* Calculate the number of days */
    g_time.days = g_time.totalSeconds / DAY_IN_SECONDS;

    /* Calculate the number of hours */
    g_time.hours = (g_time.totalSeconds - (g_time.days * DAY_IN_SECONDS)) / HOURS_IN_SECONDS;

    /* Calculate the number of minutes */
    g_time.minutes = (g_time.totalSeconds - (g_time.days * DAY_IN_SECONDS) - (g_time.hours * HOURS_IN_SECONDS)) / MIN_IN_SECONDS;

    /* Calculate the number of 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_

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "Ifx_Types.h"

/*********************************************************************************************************************/
/*-------------------------------------------------Data Structures---------------------------------------------------*/
/*********************************************************************************************************************/
typedef struct
{
    uint64 totalSeconds;                            /* Total seconds since the last reset of the microcontroller    */
    uint64 days;                                    /* Number of days                                               */
    uint64 hours;                                   /* Number of hours                                              */
    uint64 minutes;                                 /* Number of minutes                                            */
    uint64 seconds;                                 /* Number of seconds                                            */
} systemTime;

/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void getTime(void);

#endif /* STM_SYSTEM_TIME_H_ */


STM_Interrupt.c

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "STM_Interrupt.h"
#include "Bsp.h"
#include "IfxPort.h"
#include "IfxStm.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define ISR_PRIORITY_STM        40                              /* Priority for interrupt ISR                       */
#define TIMER_INT_TIME          500                             /* Time between interrupts in ms                    */

#define LED                     &MODULE_P13,0                   /* LED toggled in Interrupt Service Routine (ISR)   */
#define STM                     &MODULE_STM0                    /* STM0 is used in this example                     */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
IfxStm_CompareConfig g_STMConf;                                 /* STM configuration structure                      */
Ifx_TickTime g_ticksFor500ms;                                   /* Variable to store the number of ticks to wait    */

/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void initLED(void);
void initSTM(void);

/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* Macro to define Interrupt Service Routine.
 * This macro makes following definitions:
 * 1) Define linker section as .intvec_tc<vector number>_<interrupt priority>.
 * 2) define compiler specific attribute for the interrupt functions.
 * 3) define the Interrupt service routine as ISR function.
 *
 * IFX_INTERRUPT(isr, vectabNum, priority)
 *  - isr: Name of the ISR function.
 *  - vectabNum: Vector table number.
 *  - priority: Interrupt priority. Refer Usage of Interrupt Macro for more details.
 */
IFX_INTERRUPT(isrSTM, 0, ISR_PRIORITY_STM);

void isrSTM(void)
{
    /* Update the compare register value that will trigger the next interrupt and toggle the LED */
    IfxStm_increaseCompare(STM, g_STMConf.comparator, g_ticksFor500ms);
    IfxPort_setPinState(LED, IfxPort_State_toggled);
}

/* Function to initialize the LED */
void initLED(void)
{
    IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);    /* Initialize LED port pin                      */
    IfxPort_setPinState(LED, IfxPort_State_high);                   /* Turn off LED (LED is low-level active)       */
}

/* Function to initialize the STM */
void initSTM(void)
{
    IfxStm_initCompareConfig(&g_STMConf);           /* Initialize the configuration structure with default values   */

    g_STMConf.triggerPriority = ISR_PRIORITY_STM;   /* Set the priority of the interrupt                            */
    g_STMConf.typeOfService = IfxSrc_Tos_cpu0;      /* Set the service provider for the interrupts                  */
    g_STMConf.ticks = g_ticksFor500ms;              /* Set the number of ticks after which the timer triggers an
                                                     * interrupt for the first time                                 */
    IfxStm_initCompare(STM, &g_STMConf);            /* Initialize the STM with the user configuration               */
}

/* Function to initialize all the peripherals and variables used */
void initPeripherals(void)
{
    /* Initialize time constant */
    g_ticksFor500ms = IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, TIMER_INT_TIME);
    
    initLED();                                      /* Initialize the port pin to which the LED is connected        */
    initSTM();                                      /* Configure the STM module                                     */
}


STM_Interrupt.h

#ifndef STM_INTERRUPT_H_
#define STM_INTERRUPT_H_ 1

/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void initPeripherals(void);

#endif /* STM_INTERRUPT_H_ */


### TC387芯片中STM2_TIM寄存器配置与使用方法 TC387 是英飞凌(Infineon)AURIX™系列的高性能32位三核锁步微控制器,广泛应用于汽车电子和工业控制领域。该芯片中的定时模块 STMSystem Timer Module)包含多个通道,其中 **STM2** 是其中一个独立的系统定时器单元,其核心功能是提供高精度的时间基准、中断生成以及触发其他外设操作。 #### STM2 寄存器概述 STM2 的寄存器组主要包括以下关键寄存器: - **STM2_CLC**:时钟控制寄存器,用于使能或关闭模块时钟。 - **STM2_TIM0 / STM2_TIM1**:当前计数值寄存器,分别记录两个通道的计数状态。 - **STM2_CMP0 / STM2_CMP1**:比较寄存器,用于设置触发事件的时间点。 - **STM2_ICR**:中断控制寄存器,配置中断源及优先级。 - **STM2_ISR**:中断状态寄存器,反映当前激活的中断标志。 - **STM2_OMR**:输出匹配控制寄存器,用于选择输出行为(如翻转、置位、清零等)。 - **STM2_KRSTx**:复位控制寄存器,用于软件复位模块。 #### 基本配置流程 在使用 STM2 模块时,通常需要完成以下几个步骤: 1. **初始化时钟**:通过设置 `STM2_CLC` 寄存器使能模块时钟。 2. **设定初始计数值**:将期望的起始值写入 `STM2_TIM0` 或 `STM2_TIM1`。 3. **设定比较值**:将目标时间点写入 `STM2_CMP0` 或 `STM2_CMP1`。 4. **配置中断行为**:在 `STM2_ICR` 中启用所需中断源,并设置中断优先级。 5. **清除中断标志**:读取或写入 `STM2_ISR` 来清除已处理的中断标志。 6. **启动计数器**:通过 `STM2_OMR` 配置输出匹配动作并启动计数。 #### 示例代码:配置STM2以生成周期性中断 以下是一个基于 AURIX™ TC387 的示例代码片段,展示了如何配置 STM2 以生成每毫秒一次的中断信号: ```c #include <tc38x/TC387.h> void Init_STM2(void) { // 启用模块时钟 STM2_CLC.B.DISR = 0; // 0: enable module clock // 设置比较值(假设主频为 200MHz,则1ms对应200,000个周期) STM2_CMP0.U = 200000 - 1; // 配置中断:启用比较匹配中断 STM2_ICR.B.CMP0EN = 1; STM2_ICR.B.TIMEREN = 1; // 清除中断标志 STM2_ISR.B.CMP0IR = 1; // 启动计数器 STM2_OMR.B.MS0 = 0b10; // 设置比较后行为:触发中断 STM2_OMR.B.OPS0 = 1; // 开启输出匹配功能 } // 中断服务程序应在此处定义并注册到中断向量表中 ``` 上述代码实现了 STM2 定时器的基本配置,能够每毫秒触发一次中断请求。用户可根据实际需求调整比较值、中断响应方式及其他参数。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值