最近有客户需求使用 LPC55 SCTimer 做一个简单的定时器,用于判断程序等待超时,这篇文章就主要介绍下,使用 SCTimer 做定时器的一些配置;LPC55 系列外设大差不差,这里笔者主要以 LPC5528 来演示,主要基于 LPC5528 HelloWord 工程进行演示;
首先是 SCTimer 的初始化配置,即配置 SCTimer 的 configuration 寄存器,可以参考 SDK 中 SCTIMER_GetDefaultConfig 结合LPC55 用户手册来对照配置,LPC55 SCTimer 可以分为两个 16bit 的计数器,或者合并为一个 32bit 的计数器,这里笔者配置的是 32bit 的计数器,因此将 UNIFY 置一;
SCTimer 时钟这里使用 System clock mode,因此不需要对该位进行特殊设置;
同时设置 auto limit,这样在定时时间到时,会自动清除定时器,或者改变计数方向(SCTimer 有两种计数方式,Up 和 Up-down),前面提到过 SCTimer 可以分为两个 16bit 的计数器,因此有很多寄存器位分为 _L 和 _H,用于分别配置两个 16bit 的计数器,当合并使用为一个 32bit 计数器时,只需要配置 _L 寄存器即可,因此这里只需配置 AUTOLIMIT_L 置一;
接下来可以参考 LPC5528 用户手册的 Fig 92. SCT event configuration and selection registers 来做进一步配置;
首先是配置 MATCH 寄存器,但 MATCH 寄存器中的值与计数寄存器的值匹配时 ,对应的 MATCH 事件产生,也就是配置定时的时间可以通过这个值设定;以匹配事件 0 为例,这里可以直接配置 MATCHREL[0] 寄存器,每个定时周期开始前,MATCH 寄存器会从其对应的 MATCHREL 寄存器加载值(前提是 NORELOAD_L 没有被设置为 1),因为前面配置了 SCTimer 为一个 32bit 的寄存器,所以在配置 MATCHREL [0] 寄存器时,可以将其当成完整的一个 32bit 的寄存器进行配置;
配置 EV0_CTRL,MATCHSEL 设置 MATCH 0,可以使用寄存器默认值;
这里应用中不需要 IO 的控制,这里不需要对 SCT_IN、SCT_OUT、IOSEL 等寄存器,看到 COMBMODE,这里配置仅匹配,设置为 0x01;
EV0_STATE 这里配置为全1,在所有状态下均允许匹配事件0 产生;
接着使能匹配事件 0 中断,并使能 SCTimer 中断;
最终的初始化代码如下:
void SCT_Init(void)
{
CLOCK_EnableClock(kCLOCK_Sct0);
SCT0->CONFIG = (1 << SCT_CONFIG_UNIFY_SHIFT) | (1 << SCT_CONFIG_AUTOLIMIT_L_SHIFT);
SCT0->MATCHREL[0] = SystemCoreClock/2;//500ms
SCT0->EV[0].CTRL= (1 << SCT_EV_CTRL_COMBMODE_SHIFT);
SCT0->EV[0].STATE=0xFFFFFFFF;
SCT0->EVEN = (1 << SCT_EVEN_IEN_SHIFT);
EnableIRQ(SCT0_IRQn);
SCT0->CTRL &= ~(SCT_CTRL_HALT_L_MASK);//Start
}
SDK 中 SCT0_IRQHandler 为弱定义函数,这里笔者为了方便测试,直接重写 SCT0_IRQHandler,这样在编译时,会覆盖原先 SDK 中的 SCT0_IRQHandler;
void SCT0_IRQHandler(void);
void SCT0_IRQHandler(void)
{
//Clears the SCTimer status flags
SCT0->EVFLAG = (1 & 0xFFFFU);
SCT0->CONFLAG = (1 & (SCT_CONFLAG_BUSERRL_MASK | SCT_CONFLAG_BUSERRH_MASK));
PRINTF("SCT0_IRQHandler\r\n");
SDK_ISR_EXIT_BARRIER;
}
编译烧录后运行,可以看到已经可以成功定时 500ms;
以上就是文章的全部内容,如果有错误或者遗漏欢迎大家点击此处留言讨论,不吝指教,感谢;
参考资料:
UM11126 LPC55S6x/LPC55S2x/LPC552x User manual
AN11538 SCTimer/PWM Cookbook