I.MX6ull EPIT定时器

一 简介

EPIT定时器是一种增强的周期中断定时器,完成周期性中断定时的功能。

具有以下特点

  1.  EPIT定时器是一个32位的定时器 
  2. 时钟源可选的向下计数器  EPIT 共有 3 个时钟源可选择,ipg_clk、ipg_clk_32k 和 ipg_clk_highfreq
  3.  当计数值和比较值相等的时候产生中断
  4.  12 位分频器 对应的值是 0~4095,对应1~4096 分频
  5.  EPIT定时器在处理器几乎不用介入的情况下提供精准的定时中断,时序分辨率高达125fs。它可以应用于高速数据采集、超声波测距、雷达等领域。
  6. 可以设置引脚输出,如果设置了的话就会通过指定的引脚输出信号。

二 结构原理图

I.MX6ull EPIT定时器_第1张图片

2.1 工作原理

图中  EPIT 内部有三个重要的寄存器:

计数寄存器(EPIT_CNR)、加载寄存器(EPIT_LR)和比较寄存器(EPIT_CMPR),

        EPIT 是一个向下计数器,也就是说给它一个初值,开始递减,直到减 为 0,EPIT_CNR 里面保存的就是当前的计数值。如果 EPIT 工作在 set-and-forget 模式下,当计数寄存器里面的值减少到 0,EPIT 就会重新从EPIT_LR读取数值到计数寄存器里面,重新开 始向下计数。比较寄存器 EPIT_CMPR 里面保存的数值用于和计数寄存器里面的计数值比较,如果相等的话 就会产生一个比较事件。

2.2 工作模式

       两种工作模式: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中获取数据

2.3 23.6.1 Control register (EPITx_CR)

I.MX6ull EPIT定时器_第2张图片

2.3.1 EPITx_CR field descriptions  位字段描述

I.MX6ull EPIT定时器_第3张图片

 I.MX6ull EPIT定时器_第4张图片

寄存器 EPITx_CR 重要位如下:
CLKSRC(bit25:24): EPIT 时钟源选择位,
为 0 的时候关闭时钟源,
为1 的时候选择选择Peripheral 时钟(ipg_clk),
为 2 的时候选择 High-frequency 参考时钟(ipg_clk_highfreq),
为 3 的时候选择 Low-frequency 参考时钟(ipg_clk_32k)。
一般选择 ipg_clk=66MHz。
PRESCALAR(bit15:4): EPIT 时钟源分频值,可设置范围 0~ 4095,分别对应 1~ 4096 分频。
RLD(bit3): EPIT 工作模式,
为 0 的时候工作在 free-running 模式,
为 1 的时候工作在 set-and-forget 模式。
一般工作在 set-and-forget 模式。
OCIEN(bit2):比较中断使能位,
为 0 的时候关闭比较中断,
为 1 的时候使能比较中断,
本章试验要使能比较中断。
ENMOD(bit1):设置计数器初始值,
为 0 时计数器初始值等于上次关闭 EPIT 定时器以后计数器里面的值,
为 1 的时候来源于加载寄存器。
EN(bit0): EPIT 使能位,
为 0 的时候关闭 EPIT,
为 1 的时候使能 EPIT。0

2.4  EPIT_SR寄存器

EPIT_SR寄存器,只有bit0有效,表示中断状态,写1清零。当OCIF位为1的时候表示中断发生,为0的时候表示中断未发生。我们处理完定时器中断以后一定要清除中断标志位

I.MX6ull EPIT定时器_第5张图片

2.5  EPIT_LR 寄存器

EPIT_LR寄存器设置计数器的加载值。计数器每次计时到0以后就会读取LR寄存器的值重新开始计时。

I.MX6ull EPIT定时器_第6张图片

2.6  EPIT_CMPR 寄存器

CMPR比较计数器,当计数器的值和CMPR相等以后就会产生比较中断。无需设置

I.MX6ull EPIT定时器_第7张图片

3  使用实验   

通过 EPTI1 的中断来控制 LED0 的亮灭 500ms一次中断,

3.1 EPIT 的配置步骤

如下:

  • 1、设置 EPIT1 的时钟源
  • 设置寄存器 EPIT1_CR 寄存器的 CLKSRC(bit25:24)位,选择 EPIT1 的时钟源。
  • 2、设置分频值
  • 设置寄存器 EPIT1_CR 寄存器的 PRESCALAR(bit15:4)位,设置分频值。
  • 3、设置工作模式
  • 设置寄存器 EPIT1_CR 的 RLD(bit3)位,设置 EPTI1 的工作模式。
  • 4、设置计数器的初始值来源
  • 设置寄存器 EPIT1_CR 的 ENMOD(bit1)位, 设置计数器的初始值来源。
  • 5、 使能比较中断
  • 我们要使用到比较中断,因此需要设置寄存器 EPIT1_CR 的 OCIEN(bit2)位,使能比较中断。
  • 6、设置加载值和比较值
  • 设置寄存器 EPIT1_LR 中的加载值和寄存器 EPIT1_CMPR 中的比较值,通过这两个寄存器
  • 就可以决定定时器的中断周期。
  • 7、 EPIT1 中断设置和中断服务函数编写
  • 使能 GIC 中对应的 EPIT1 中断,注册中断服务函数,如果需要的话还可以设置中断优先级。最后编写中断服务函数。
  • 8、使能 EPIT1 定时器
  • 配置好 EPIT1 以后就可以使能 EPIT1 了,通过寄存器 EPIT1_CR 的 EN(bit0)位来设置。


驱动编写

  1.  配置EPIT1
  2.  使能对应中断
  3. 注册中断 服务函数
  4. 使能EPIT1

EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1); 一次配置完EPIT1_CR寄存器

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_epittimer.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : EPIT定时器驱动文件。
其他	   : 配置EPIT定时器,实现EPIT定时器中断处理函数
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/5 左忠凯创建
***************************************************************/
#include "bsp_epittimer.h"
#include "bsp_int.h"
#include "bsp_led.h"

/*
 * @description		: 初始化EPIT定时器.
 *					  EPIT定时器是32位向下计数器,时钟源使用ipg=66Mhz		 
 * @param - frac	: 分频值,范围为0~4095,分别对应1~4096分频。
 * @param - value	: 倒计数值。
 * @return 			: 无
 */
void epit1_init(unsigned int frac, unsigned int value)
{
	if(frac > 0XFFF)
		frac = 0XFFF;
		
	EPIT1->CR = 0;	/* 先清零CR寄存器 */
	
	/*
     * CR寄存器:
     * bit25:24 01 时钟源选择Peripheral clock=66MHz
     * bit15:4  frac 分频值
     * bit3:	1  当计数器到0的话从LR重新加载数值
     * bit2:	1  比较中断使能
     * bit1:    1  初始计数值来源于LR寄存器值
     * bit0:    0  先关闭EPIT1
     */
	EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1);
	
	EPIT1->LR = value;	/* 倒计数值 */
	EPIT1->CMPR	= 0;	/* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 */

	/* 使能GIC中对应的中断 			*/
	GIC_EnableIRQ(EPIT1_IRQn);

	/* 注册中断服务函数 			*/
	system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)epit1_irqhandler, NULL);	

	EPIT1->CR |= 1<<0;	/* 使能EPIT1 */ 
}

/*
 * @description			: EPIT中断处理函数
 * @param				: 无
 * @return 				: 无
 */
void epit1_irqhandler(void)
{ 
	static unsigned char state = 0;

	state = !state;
	if(EPIT1->SR & (1<<0)) 			/* 判断比较事件发生 */
	{
		led_switch(LED0, state); 	/* 定时器周期到,反转LED */
	}
	
	EPIT1->SR |= 1<<0; 				/* 清除中断标志位 */
}

3.2 分频计算方法

 bit25:24 01 时钟源选择Peripheral clock=66MHz 设置分频值1 则计时计数器为  66*1000*1000/1*0.5 = 33000 000

	epit1_init(0, 66000000/2);	/* 初始化EPIT1定时器,1分频
								 * 计数值为:66000000/2,也就是
								 * 定时周期为500ms。
								 */

   

你可能感兴趣的:(单片机,嵌入式硬件)