EPIT ( Enhanced Periodic Interrupt Timer):增强的周期中断定时器
set-and-forget 模式:
只要计数器计数到 0,那么就会从加载寄存器 EPITx_LR 中重新加载数据到计数器中
free-running 模式:
当计数器计数到0以后会重新从0XFFFFFFFF开始计数
配置寄存器 EPITx_CR
CLKSRC(bit25:24): EPIT 时钟源选择位(ipg_clk=66MHz)
PRESCALAR(bit15:4): EPIT 时钟源分频值(12位)
RLD(bit3):工作模式:set-and-forget,free-running
OCIEN(bit2):比较中断使能位,
ENMOD(bit1):为 1 的时候来源于加载寄存器
EN(bit0): EPIT 使能位
EPITx_SR
OCIF(bit0) :中断标志位,此位是写 1 清零的。
Tout = ((frac +1 )* value) / Tclk;
Tclk: 输入时钟(66M)
frac: 分频值
value: 加载寄存器
Tout: 输出
使用定时器来实现按键消抖,防止按键中断内部出现延时函数。
上图中 t1 - t3 时间之内是,按键抖动。
t1, t2, t3 会触发按键中断。按键中断处理函数内开 10ms 的定时器中断。
因t1-t2, t2-t3的时间小于10ms,不会触发定时器中断。
t3后10ms,触发定时器中断,内部做原来的按键中断处理。
按键中断函数:
void filtertimer_restart(unsigned int value)
{
EPIT1->CR &= ~(1<<0); /* 先关闭定时器 */
EPIT1->LR = value; /* 计数值 */
EPIT1->CR |= (1<<0); /* 打开定时器 */
}
void gpio1_16_31_irqhandler(void)
{
filtertimer_restart(66000000/100); /* 开启定时器 */
gpio_clearintflags(GPIO1, 18); /* 清除中断标志位 */
}
GPT(General Purpose Timer) 通用用途定时器。比EPIT更具有通用性。
可实现的功能:测量时间间隔、生成定时脉冲、执行时间相关的操作。
时钟选择:ipg_clk_24M、 GPT_CLK(外部时钟)、ipg_clk、ipg_clk_32k 和 ipg_clk_highfreq。
选择 ipg_clk=66MHz
重新启动(restart)模式和自由运行(free-run)模式
重新启动(restart)模式
当计数值和比较寄存器中的值相等的话计数值就会清零,
比较通道 1 才有此模式
自由运行(free-run)模式
当比较事件发生以后并不会复位计数器,而是继续计数,直到计数值为 0XFFFFFFFF,然后重新回滚到 0X00000000。
SWR(bit15):复位 GPT 定时器,写 1 复位 GPT 定时器
FRR(bit9):运行模式,restart / free-run
CLKSRC(bit8:6):钟源选择位 001(ipg_clk)
ENMOD(bit1): 关闭后是否计数清零
EN(bit): GPT 使能位
PRESCALER(bit11:0),这就是 12 位分频值,可设置 0~4095,分别对应 1~4096 分频
ROV(bit5): 回滚标志位,计数值从 0XFFFFFFFF 回滚到 0 的时候此位置 1
IF2~IF1(bit4:3):输入捕获标志位
OF3~OF1(bit2:0):输出比较中断标志位,比较事件发生以后此位置 1
保存着 GPT 定时器的当前计数值
三个比较寄存器,GPTx_OCR1-3,存放这三路比较值。可用于触发中断。
设置计数频率为1M,ipg_clk=66MHz,设置 66 分频
GPTx_CNT 计数周期为 1us。
void delayus(unsigned int usdelay)
{
unsigned long oldcnt,newcnt;
unsigned long tcntvalue = 0; /* 走过的总时间 */
oldcnt = GPT1->CNT;
while(1)
{
newcnt = GPT1->CNT;
if(newcnt != oldcnt)
{
if(newcnt > oldcnt) /* GPT 是向上计数器,并且没有溢出 */
tcntvalue += newcnt - oldcnt;
else /* 发生溢出 */
tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;
oldcnt = newcnt;
if(tcntvalue >= usdelay) /* 延时时间到了 */
break; /* 跳出 */
}
}
}