摘要:EPIT(Enhanced Periodic Interrupt Timer)是一种增强型周期性中断定时器,主要用于嵌入式系统中产生周期性的中断信号。以汽车电子系统为例,车辆中的一些传感器数据需要按照固定的周期进行采集和处理。EPIT 定时器就可以设置一个合适
EPIT(Enhanced Periodic Interrupt Timer)是一种增强型周期性中断定时器,主要用于嵌入式系统中产生周期性的中断信号。
以汽车电子系统为例,车辆中的一些传感器数据需要按照固定的周期进行采集和处理。EPIT 定时器就可以设置一个合适的周期,每隔一段时间产生一个中断。当发生中断时,处理器就可以暂停当前的任务,转而去执行数据采集程序,比如采集车速传感器的数据。
IMX6U的 EPIT 是一个32位的向下计数器,有12位的分频值。
从《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81》 可以看到EPIT 定时器框图如下:
EPIT 的时钟源可以选择 ipg_clk (66MHz),经过后面的分频器。
分频器有12位,0 ~ 4095分别代表 1 ~ 4096分频。
预分频器的输出连接到Prescaled clock,即分频后的时钟信号。
这是一个 32 位的比较寄存器,用于存储比较值。
比较寄存器的值与计数器的值通过CMP(比较器)进行比较。
通过 EPIOTx_CR 可以设置EPIT的工作模式。通过手册查询该寄存器 RLD 位置作用:
当 RLD为1时,计时器工作在 set-and-forget 模式,该模式即 “ 设置后就不用管 ”。
在此模式下,计数器从加载寄存器(EPIT_LR)获取数据;它不能直接从块数据总线写入。
每当计数器达到零时,EPIT_LR 中的值就会被加载到计数器中。然后这个值会递减到零。若要直接初始化计数器而不是等待计数达到零,需设置 EPIT 计数器覆写使能位(EPIT_CR [IOVW]),并使用所需的初始化值写入 EPIT_LR。
当RLD为0 时,计时器工作在“自由运行”模式。在这个模式下,计数器从 0000 0000h 翻转到 FFFFFFFFh,而不会从模式寄存器重新加截值,翻转之后,计数器会继续向下计数。
要直接初始化计数器,也需要设置 EPIT 计数器覆盖使能位(EPIO_EPITCL [IOVW] ),并将所需要的初始化值写入 EPIT_LR。
当 EPIT_EPITCMPR 值与 EPIT_EPITCNR 中的值相匹配时,会设置一个比较状态标志 , 如果控制寄存器中的OCIEN 位被置位,还会产生一个中断。
下图是比较事件和中断的时序:
在对设置值、产生中断时序要求非常严格的情况下,需要细致了解其时序。 一般的情况下,可能不需要了解如此清楚。
IMX6ULL 共有两个 EPIT 定时器,主要包含以下寄存器。
EPIT_CR 是EPIT的控制寄存器,主要用于配置和控制EPIT 工作模式、时钟源、分频值、中断使能等。
其主要有以下位域:
EPIT_SR 是状态寄存器,主要用于记录和提供与定时器相关的状态信息,只有bit0(OCIF) 有效,表示中断状态。 写1时清零。
当OCIF 位值为1时,表示发生中断, 值为0的时候表示中断没有发生。
处理完定时器中断,需要清除该标志位。
本实验实现 500ms 周期的定时器,在EPIT的中断服务函数中让LED闪烁。
/*** @brief EPIT初始化, 工作在 set-and-forget 模式*/void epit_init(EPIT_Type *base, unsigned int frac, unsigned int value) {if(frac > 4095){frac = 4095;}// 配置EPIT设置寄存器,先清0base->CR = 0;// 设置初始值为加载值 | 使能EPIT模块 | 使能中断 | 分频值 | 使能时钟base->CR = (1 LR = value;// 设置比较值base->CMPR = 0;// 使能GIC中断if(base == EPIT1)GIC_EnableIRQ(EPIT1_IRQn);elseGIC_EnableIRQ(EPIT2_IRQn);// 注册中断服务函数sys_irq_handle_register(EPIT1_IRQn, (system_irq_handler_t)epit_irqhandler, NULL);// 定时器使能base->CR |= 1分频值计算:
Tout=((frac+1)∗value)/Tclk
其中 Tclk = 66Mhz
如果分频值是1,则1秒进中断 66M次。 如果要500ms进一次,分频值设置1,计数器值设置为 66M/2。
本文代码开源地址:
来源:编程圈子