PIT 定时器实际上是一个定时器阵列,RT1052 内部的 PIT 定时器共有 4 个通道,可用于产生中断和触发 DMA。
PIT 定时器内部有 4 个计数器(Timer0~Timer3),也就是 4 个通道
PIT功能
1)32 位计数器(CNT),仅支持递减计数方式。
2)支持四个通道。
3)可以级联,实现超长定时(最长可组成 128 位定时器)。
4)支持中断/触发功能。
以 PIT 定时器通道 0 为例
使用函数 CLOCK_EnableClock 使能 PIT 时钟。此函数会被 PIT 定时器初始化函数 PIT_Init 调用,所以不需要我们显示的调用。
CLOCK_EnableClock(kCLOCK_Pit)
使用函数 PIT_Init 初始化 PIT 定时器
void PIT_Init(PIT_Type *base, const pit_config_t *config)
typedef struct _pit_config
{
bool enableRunInDebug; //debug 的时候 PIT 是否可以使用
} pit_config_t;
PIT_Init 的一般使用方法如下:
PIT_GetDefaultConfig(&pit_config); //初始化为默认配置
pit_config.enableRunInDebug=true; //调试模式下 PIT 继续运行
PIT_Init(PIT,&pit_config); //初始化 PIT 定时器
使用函数 PIT_SetTimerPeriod 设置通道 0 的加载值,也就是寄存器 LADVAL0 的值。
static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32_t count)
typedef enum _pit_chnl
{
kPIT_Chnl_0 = 0U, //PIT 通道 0
kPIT_Chnl_1, //PIT 通道 1
kPIT_Chnl_2, //PIT 通道 2
kPIT_Chnl_3, //PIT 通道 3
} pit_chnl_t;
使能通道 0 的中断以后,每当设置好的加载值倒计数到 0 就会产生相应的中断。
使用函数 PIT_EnableInterrupts 使能通道 0中断
static inline void PIT_EnableInterrupts(PIT_Type *base, pit_chnl_t channel, int32_t mask)
typedef enum _pit_interrupt_enable
{
kPIT_TimerInterruptEnable = PIT_TCTRL_TIE_MASK,
} pit_interrupt_enable_t;
只 有 一 个 中 断 类 型 kPIT_TimerInterruptEnable。
配置好 PIT 定时器以后需要开启定时器,开启 PIT 定时器的函数为 PIT_StartTimer
此函数原型如下;
static inline void PIT_StartTimer(PIT_Type *base, pit_chnl_t channel)
在定时器配置完了之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器
使用如下函数开启 PIT 中断并设置相应的优先级。
RT1052_NVIC_SetPriority(PIT_IRQn,6,0); //抢占优先级 6,子优先级 0
EnableIRQ(PIT_IRQn); //使能 PIT 中断
在中断产生后使用函数 PIT_GetStatusFlags 来获取中断状态,此函数就是获取 TFLG0 的 TIF 位状态,通过 TIF 位状态判断是否是通道 0 的中断。
中断状态获取函数 PIT_GetStatusFlags 原型如下:
static inline uint32_t PIT_GetStatusFlags(PIT_Type *base, pit_chnl_t channel)
此函数其实就是读取寄存器 TFLG 的值,通过这个返回值就可以知道中断是否发生。
中断状态(标志位)清除函数 PIT_ClearStatusFlags 原型如下:
static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
pit_config_t pit_config;
//初始化PIT通道0,PIT时钟源为perclk_clk_root=75MHz.
//ldval: CH0初始值,0~0xFFFFFFFF
//递减计数,当ldval==0时,产生中断.
//定时时间=ldval/PERCLK_CLK_ROOT
void PIT_CH0_Int_Init(u32 ldval)
{
PIT_GetDefaultConfig(&pit_config); //初始化为默认配置
pit_config.enableRunInDebug=true; //调试模式下PIT继续运行
PIT_Init(PIT,&pit_config); //初始化PIT定时器
PIT_SetTimerPeriod(PIT,kPIT_Chnl_0,ldval);//设置倒计时初始值
PIT_EnableInterrupts(PIT,kPIT_Chnl_0,kPIT_TimerInterruptEnable);//使能中断
RT1052_NVIC_SetPriority(PIT_IRQn,6,0); //抢占优先级6,子优先级0
EnableIRQ(PIT_IRQn); //使能PIT中断
PIT_StartTimer(PIT,kPIT_Chnl_0); //打开PIT
}
//PIT中断服务函数
void PIT_IRQHandler(void)
{
//PIT CH0中断
if((PIT_GetStatusFlags(PIT,kPIT_Chnl_0)&kPIT_TimerFlag)==kPIT_TimerFlag)
{
LED1_Toggle; //LED灯翻转
PIT_ClearStatusFlags(PIT,kPIT_Chnl_0,kPIT_TimerFlag);//清楚中断标志位
}
__DSB(); //数据同步屏蔽指令
}