这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3学习整理】STM Timer 使用

共2条 1/1 1 跳转至页

【S32K3学习整理】STM Timer 使用

高工
2026-11-04 09:21:48   被打赏 42 分(兑奖)     打赏

【简介】

在开发中经常会有到软件/硬件的timer 用于监测状态及异常处理,本次使用STM 硬件timer功能。STM 的配置也比较简单只要配置工作时钟的分频和回调函数就可以工作了。

image.png

image.png

参数配置完成后生成驱动配置结构后,编写如下的测试代码初始化STM.

static int stm_init(void)
{
LOG_I("stm driver init.");
Stm_Ip_Init(0, &STM_0_InitConfig_PB);
Stm_Ip_InitChannel(0,STM_0_ChannelConfig_PB);
/* Init isr configuration */
#if (0 == CFG_INTCTRL_INIT_ENABLE)
IntCtrl_Ip_InstallHandler(STM0_IRQn, STM_0_ISR, NULL_PTR);
IntCtrl_Ip_SetPriority(STM0_IRQn, 0);
IntCtrl_Ip_EnableIrq(STM0_IRQn);
#endif
stm0_initialized = TRUE;
return 1;
}


编写如下的代码启动timer 注册timer 的回调函数,在STM 中断回调函数中触发调用。

boolean s32k3_stm_timer_start(uint8 channel, uint32 timeout_ms,
s32k3_stm_callback_t callback)
{
uint64 ticks;
uint64 divisor;

if ((channel >= STM_CHANNEL_COUNT) ||
(channel != STM_0_ChannelConfig_PB[0].hwChannel) ||
(timeout_ms == 0U) || (callback == NULL_PTR))
{
LOG_E("Invalid STM0 timer parameters.");
return FALSE;
}
if (stm0_initialized == FALSE)
{
LOG_E("STM0 driver is not initialized.");
return FALSE;
}

divisor = ((uint64)STM_0_InitConfig_PB.clockPrescaler + 1U) * 1000U;
ticks = ((uint64)timeout_ms * STM0_INPUT_CLOCK_HZ + divisor - 1U) / divisor;
if ((ticks == 0U) || (ticks > 0xFFFFFFFFULL))
{
LOG_E("STM0 timeout is out of range.");
return FALSE;
}

/* Area 39 is reentrant and is also used by Stm_Ip_StartCounting. */
SchM_Enter_Gpt_GPT_EXCLUSIVE_AREA_39();
Stm_Ip_DisableChannel(0U, channel);
stm0_callbacks[channel] = callback;
Stm_Ip_StartCounting(0U, channel, (uint32)ticks);
SchM_Exit_Gpt_GPT_EXCLUSIVE_AREA_39();
return TRUE;
}


static s32k3_stm_callback_t volatile stm0_callbacks[STM_CHANNEL_COUNT];
static boolean stm0_initialized;

/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
*================================================================================================*/

/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
*================================================================================================*/
void Stm0_Channle_Callback(uint8 channel)
{
s32k3_stm_callback_t callback;

if (channel >= STM_CHANNEL_COUNT)
{
LOG_E("Invalid STM0 channel: %u.", (unsigned int)channel);
return;
}

LOG_I("Stm0 %d Time out.",channel);
callback = stm0_callbacks[channel];
if (callback != NULL_PTR)
{
callback(channel);
}
}


  编写如下测试代码验证timer 的功能。

void stm_test_callback(uint8 channel)
{
    PRINTF("STM channel %d timeout.\r\n", channel);
}

unsigned int stm(char argc, char **argv)
{
    uint32_t time;
    if(argc == 3 && 0 == strcmp(argv[1],"start"))
    {
        time = (uint32_t)myatoi(argv[2]);
        s32k3_stm_timer_start(0, time, stm_test_callback);
    }
    else
    {
        PRINTF("Usage: stm start time\r\n");
    }
    return 0;
}

上述代码运行后启动1000ms 和 2000ms 测试,回调函数的打印时间跟预期保持一致。

image.png    


管理员
2026-11-10 00:33:54     打赏
2楼

底层定时器配置与使用笔记扎实,步骤可复用,适合驱动开发读者


共2条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]