EPIT定时器实验

本文详细介绍了I.MX6U芯片中的EPIT定时器,它是一个专用于周期性中断的32位定时器。EPIT具有可选时钟源、12位分频器和比较中断功能。通过设置不同模式,如set-and-forget和free-running,实现不同定时需求。文中还给出了EPIT的配置寄存器和中断处理函数的示例代码,展示了如何初始化定时器并处理中断事件,以控制LED灯的翻转,实现周期性的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EPIT定时器简介

EPIT的全称是:Enhanced Periodic Interrupt Timer,直译过来就是增强的周期中断定时器,它主要是完成周期性中断定时的。学过STM32的话应该知道,STM32里面的定时器还有很多其它的功能,比如输入捕获、PWM输出等等。但是I.MX6U的EPIT定时器只是完成周期性中断定时的,仅此一项功能!至于输入捕获、PWM输出等这些功能,I.MX6U由其它的外设来完成。

EPIT是一个32位定时器,在处理器几乎不用介入的情况下提供精准的定时中断,软件使能以后EPIT就会开始运行,EPIT定时器有如下特点:

①、时钟源可选的32位向下计数器。

②、12位的分频值。

③、当计数值和比较值相等的时候产生中断。

①、这是个多路选择器,用来选择EPIT定时器的时钟源,EPIT共有3个时钟源可选择,ipg_clk、ipg_clk_32k和ipg_clk_highfreq。

②、这是一个12位的分频器,负责对时钟源进行分频,12位对应的值是0~4095,对应着1~4096分频。

③、经过分频的时钟进入到EPIT内部,在EPIT内部有三个重要的寄存器:计数寄存器(EPIT_CNR)、加载寄存器(EPIT_LR)和比较寄存器(EPIT_CMPR),这三个寄存器都是32位的。EPIT是一个向下计数器,也就是说给它一个初值,它就会从这个给定的初值开始递减,直到减为0,计数寄存器里面保存的就是当前的计数值。如果EPIT工作在set-and-forget模式下,当计数寄存器里面的值减少到0,EPIT就会重新从加载寄存器读取数值到计数寄存器里面,重新开始向下计数。比较寄存器里面保存的数值用于和计数寄存器里面的计数值比较,如果相等的话就会产生一个比较事件。

④、比较器。

⑤、EPIT可以设置引脚输出,如果设置了的话就会通过指定的引脚输出信号。

⑥、产生比较中断,也就是定时中断。

EPIT定时器有两种工作模式:set-and-forget和free-running,这两个工作模式的区别如下:

set-and-forget模式:EPITx_CR(x=1,2)寄存器的RLD位置1的时候EPIT工作在此模式下,在此模式下EPIT的计数器从加载寄存器EPITx_LR中获取初始值,不能直接向计数器寄存器写入数据。不管什么时候,只要计数器计数到0,那么就会从加载寄存器EPITx_LR中重新加载数据到计数器中,周而复始。

free-running模式:EPITx_CR寄存器的RLD位清零的时候EPIT工作在此模式下,当计数器计数到0以后会重新从0XFFFFFFFF开始计数,并不是从加载寄存器EPITx_LR中获取数据。

EPIT的配置寄存器:EPITx_CR

CLKSRC(bit25:24):EPIT时钟源选择位,为0的时候关闭时钟源,1的时候选择选择Peripheral时钟(ipg_clk),为2的时候选择High-frequency参考时钟(ipg_clk_highfreq),为3的时候选择Low-frequency参考时钟(ipg_clk_32k)。在本例程中,我们设置为1,也就是选择ipg_clk作为EPIT的时钟源,ipg_clk=66MHz。

PRESCALAR(bit15:4):EPIT时钟源分频值,可设置范围0~4095,分别对应1~4096分频。

RLD(bit3):EPIT工作模式,为0的时候工作在free-running模式,为1的时候工作在set-and-forget模式。本章例程设置为1,也就是工作在set-and-forget模式。

OCIEN(bit2):比较中断使能位,为0的时候关闭比较中断,为1的时候使能比较中断,本章试验要使能比较中断。

ENMOD(bit1):设置计数器初始值,为0时计数器初始值等于上次关闭EPIT定时器以后计数器里面的值,为1的时候来源于加载寄存器。

EN(bit0):EPIT使能位,为0的时候关闭EPIT,为1的时候使能EPIT。

EPITx_SR:

寄存器EPITx_SR只有一个位有效,那就是OCIF(bit0),这个位是比较中断标志位,为0的时候表示没有比较事件发生,为1的时候表示有比较事件发生。当比较中断发生以后需要手动清除此位,此位是写1 清零的。

寄存器EPITx_LR、EPITx_CMPR和EPITx_CNR分别为加载寄存器、比较寄存器和计数寄存器,这三个寄存器都是用来存放数据的,很简单。

相关代码编写

1 #include "bsp_epittimer.h"
2 #include "bsp_int.h"
3 #include "bsp_led.h"
4 1 #include "bsp_epittimer.h"
2 #include "bsp_int.h"
3 #include "bsp_led.h"
4 
5 /*
6 * @description  : 初始化EPIT定时器.
7 * EPIT定时器是32位向下计数器,时钟源使用ipg=66Mhz 
8 * @param – frac : 分频值,范围为0~4095,分别对应1~4096分频。
9 * @param - value  : 倒计数值。
10 * @return  : 无
11 */
12 void epit1_init(unsigned int frac, unsigned int value)
13 {
14  if(frac > 0XFFF)
15  frac = 0XFFF;
16  EPIT1->CR = 0; /* 先清零CR寄存器 */
17 
18  /*
19     * CR寄存器:
20 * bit25:24 01 时钟源选择Peripheral clock=66MHz
21 * bit15:4 frac 分频值
22 * bit3: 1 当计数器到0的话从LR重新加载数值
23 * bit2: 1 比较中断使能
24 * bit1: 1 初始计数值来源于LR寄存器值
25 * bit0: 0 先关闭EPIT1
26 */
27  EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1);
28  EPIT1->LR = value;  /* 加载寄存器值  */
29  EPIT1->CMPR = 0;  /* 比较寄存器值 */
30 
31  /* 使能GIC中对应的中断 */
32  GIC_EnableIRQ(EPIT1_IRQn);
33 
34  /* 注册中断服务函数   */
35  system_register_irqhandler(EPIT1_IRQn, 
(system_irq_handler_t)epit1_irqhandler, 
NULL); 
36  EPIT1->CR |= 1<<0; /* 使能EPIT1 */ 
37 }
38 
39 /*
40 * @description  : EPIT中断处理函数
41  * @param  : 无
42 * @return  : 无
43 */
44 void epit1_irqhandler(void)
45 { 
46  static unsigned char state = 0;
47  state = !state;
48  if(EPIT1->SR & (1<<0))  /* 判断比较事件发生    */
49  {
50  led_switch(LED0, state);  /* 定时器周期到,反转LED  */
51  }
52  EPIT1->SR |= 1<<0;  /* 清除中断标志位    */
53 }
12 void epit1_init(unsigned int frac, unsigned int value)
13 {
14  if(frac > 0XFFF)
15  frac = 0XFFF;
16  EPIT1->CR = 0; /* 先清零CR寄存器 */
17 
18  /*
19     * CR寄存器:
20 * bit25:24 01 时钟源选择Peripheral clock=66MHz
21 * bit15:4 frac 分频值
22 * bit3: 1 当计数器到0的话从LR重新加载数值
23 * bit2: 1 比较中断使能
24 * bit1: 1 初始计数值来源于LR寄存器值
25 * bit0: 0 先关闭EPIT1
26 */
27  EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1);
28  EPIT1->LR = value;  /* 加载寄存器值  */
29  EPIT1->CMPR = 0;  /* 比较寄存器值 */
30 
31  /* 使能GIC中对应的中断 */
32  GIC_EnableIRQ(EPIT1_IRQn);
33 
34  /* 注册中断服务函数   */
35  system_register_irqhandler(EPIT1_IRQn, 
(system_irq_handler_t)epit1_irqhandler, 
NULL); 
36  EPIT1->CR |= 1<<0; /* 使能EPIT1 */ 
37 }
38 
39 /*
40 * @description  : EPIT中断处理函数
41  * @param  : 无
42 * @return  : 无
43 */
44 void epit1_irqhandler(void)
45 { 
46  static unsigned char state = 0;
47  state = !state;
48  if(EPIT1->SR & (1<<0))  /* 判断比较事件发生    */
49  {
50  led_switch(LED0, state);  /* 定时器周期到,反转LED  */
51  }
52  EPIT1->SR |= 1<<0;  /* 清除中断标志位    */
53 }

 

1 #include "bsp_clk.h"
2 #include "bsp_delay.h"
3 #include "bsp_led.h"
4 #include "bsp_beep.h"
5 #include "bsp_key.h"
6 #include "bsp_int.h"
7 #include "bsp_epittimer.h"
8 
9 /*
10 * @description : main函数
11 * @param : 无
12 * @return : 无
13  */
14 int main(void)
15 {
16  int_init();  /* 初始化中断(一定要最先调用!)  */
17  imx6u_clkinit();  /* 初始化系统时钟  */
18  clk_enable();  /* 使能所有的时钟  */
19  led_init();  /* 初始化led   */
20  beep_init();  /* 初始化beep   */
21  key_init();  /* 初始化key   */
22  epit1_init(0, 66000000/2);  /* 初始化EPIT1定时器,1分频
23     * 计数值为:66000000/2,也就是
24     * 定时周期为500ms。 
25     */
26  while(1) 
27  { 
28  delay(500);
29  }
30 
31    return 0;
32 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值