10_I.MX6ULL_EPIT定时器

目录

EPIT定时器简介

EPIT的配置

源码实现


EPIT定时器简介

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

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

1.时钟源可选的32位向下计数器。

2.12 位的分频值。

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

EPIT定时器结构如所示:

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

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

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

4.比较器。

5.EPIT可以设置引脚输出,如果设置了的话就会通过指定的引脚输出信号.⑥、产生比较中断,也就是定时中断。

6.产生比较中断,也就是定时中断。

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)。

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

RLD(bit3):EPIT工作模式,为0的时候工作在free-running模式,为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(bito),这个位是比较中断标志位,为0的时候表示没有比较事件发生,为1的时候表示有比较事件发生。当比较中断发生以后需要手动清除此位,此位是写1清零的

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

EPIT的配置

1.设置 EPITI的时钟源

设置寄存器EPIT_CR寄存器的CLKSRC(bit25:24)位,选择EPIT1的时钟源。

2.设置分频值

设置寄存器EPIT_CR寄存器的PRESCALAR(bit15:4)位,设置分频值。

3.设置工作模式

设置寄存器EPITI_CR的RLD(bit3)位,设置 EPIT的工作模式。

4.设置计数器的初始值来源

设置寄存器EPIT_CR的ENMOD(bit1)位,设置计数器的初始值来源。

5.使能比较中断

我们要使用到比较中断,因此需要设置寄存器EPIT_CR的OCIEN(bit2)位,使能比较中断。

6.设置加载值和比较值

设置寄存器EPIT_LR中的加载值和寄存器EPIT_CMPR中的比较值,通过这两个寄存器就可以决定定时器的中断周期。

7.EPIT中断设置和中断服务函数编写

使能GIC中对应的EPIT1中断,注册中断服务函数,如果需要的话还可以设置中断优先级。最后编写中断服务函数。

8.使能EPIT定时器配置好EPIT以后就可以使能EPIT了,通过寄存器EPITI_CR的EN(bito)位来设置。

源码实现

500ms定时器翻转led灯

#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "imx6ul.h"


#define LED0	0

/* 函数声明 */
void led_init(void);
void led_switch(int led, int status);
#endif

#include "bsp_led.h"
/*
 * @description	: 初始化LED对应的GPIO
 * @param 		: 无
 * @return 		: 无
 */
void led_init(void)
{
	/* 1、初始化IO复用 */
	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);		/* 复用为GPIO1_IO03 */
	
	
	/* 2、、配置GPIO1_IO03的IO属性	
	 *bit 16:0 HYS关闭
	 *bit [15:14]: 00 默认下拉
	 *bit [13]: 0 kepper功能
	 *bit [12]: 1 pull/keeper使能
	 *bit [11]: 0 关闭开路输出
	 *bit [7:6]: 10 速度100Mhz
	 *bit [5:3]: 110 R0/6驱动能力
	 *bit [0]: 0 低转换率
	 */
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
	
	/* 3、初始化GPIO,GPIO1_IO03设置为输出*/
	GPIO1->GDIR |= (1 << 3);	 

	/* 4、设置GPIO1_IO03输出低电平,打开LED0*/
	GPIO1->DR |= (1 << 3);		
}


/*
 * @description		: LED控制函数,控制LED打开还是关闭
 * @param - led		: 要控制的LED灯编号
 * @param - status	: 0,关闭LED0,1 打开LED0
 * @return 			: 无
 */
void led_switch(int led, int status)
{	
	switch(led)
	{
		case LED0:
			if(status == ON)
				GPIO1->DR &= ~(1<<3);	/* 打开LED0 */
			else if(status == OFF)
				GPIO1->DR |= (1<<3);	/* 关闭LED0 */
			break;
	}
}
#ifndef __BSP__EPIT_H_
#define __BSP__EPIT_H_

#include "imx6ul.h"

/*函数声明*/
void epit_init(unsigned int frac, unsigned int value);
void epit1_irqhandler(void);

#endif
#include "bsp_epit.h"
#include "bsp_interrupt.h"
#include "bsp_led.h"
/*
 * @description	: EPIT中断服务函数
 * @param 		: 无
 * @return 		: 无
 */
void epit1_irqhandler()
{
    static unsigned char state = 0;

    state = !state;

    if(EPIT1->SR & (1 << 0)) /*中断发生*/
    {
        led_switch(LED0, state); /*反转led*/
    }

    /*清楚标志位*/
    EPIT1->SR |= (1 << 0);
}




/*
 * @description	: 初始EPIT
 * @param 		: 分频值
 * @param 		: 加载值
 * @return 		: 无
 */
void epit_init(unsigned int frac, unsigned int value)
{

    /*最大分频值4095*/
    if(frac > 4095)
    {
        frac = 4095;
    }

    /*配置EPIT1_CR寄存器*/
    EPIT1->CR = 0;
    /*
     * 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 << 1) | (1 << 2) | (1 << 3) | (frac << 4) | (1 << 24);

    EPIT1->LR = value; /*加载寄存器*/
    EPIT1->CMPR = 0;    /*比较计数器*/

    /*使能中断*/
    GIC_EnableIRQ(EPIT1_IRQn);

    /*注册中断*/
    system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)epit1_irqhandler , NULL );

    /*打开EPTI1*/
    EPIT1->CR |= 1 << 0;
}


#include "bsp_clk.h"

#include "bsp_delay.h"

#include "bsp_led.h"

#include "bsp_beep.h"

#include "bsp_key.h"

#include "bsp_interrupt.h"

#include "bsp_exti.h"

#include "bsp_epit.h"

/*

 * @description	: main函数

 * @param 		: 无

 * @return 		: 无

 */

int main(void)

{

	unsigned char state = OFF;



	int_init(); 		/* 初始化中断(一定要最先调用!) */

	imx6u_clkinit();	/* 初始化系统时钟 			*/

	clk_enable();		/* 使能所有的时钟 			*/

	led_init();			/* 初始化led 			*/

	epit_init(0, 66000000/2);	/*EPIT定时器初始 500ms*/



	while(1)			

	{	

	}



	return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值