Linux学习笔记14---EPIT 定时器实验

时间:2024-10-24 06:59:37
#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; 				/* 清除中断标志位 */
}

        bsp_epittimer.c 里面有两个函数 epit1_init epit1_irqhandler ,分别是 EPIT1 初始化函数和 EPIT1 中断处理函数。 epit1_init 有两个参数 frac value ,其中 frac 是分频值, value 是加载值。 在第 29 行设置比较寄存器为 0 ,也就是当计数器倒计数到 0 以后就会触发比较中断,因此分频值 frac value 就可以决定中断频率,计算公式如下:
Tout = ((frac +1 )* value) / Tclk;
其中:
        Tclk: EPIT1 的输入时钟频率 ( 单位 Hz)
        Tout: EPIT1 的溢出时间 ( 单位 S)
        第 38 行设置了 EPIT1 工作模式为 set-and-forget ,并且时钟源为 ipg_clk=66MHz 。假如我们 现在要设置 EPIT1 中断周期为 500ms ,可以设置分频值为 0 ,也就是 1 分频,这样进入 EPIT1的时钟就是 66MHz 。如果要实现 500ms 的中断周期, EPIT1 的加载寄存器就应该为 66000000/2=33000000。
        函数 epit1_irqhandler EPIT1 的中断处理函数,此函数先读取 EPIT1_SR 寄存器,判断当 前的中断是否为比较事件,如果是的话就翻转 LED 灯。最后在退出中断处理函数的时候需要清除中断标志位。
        最后就是 main.c 文件了,在 main.c 里面输入如下内容:
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_epittimer.h"

/*
 * @description	: main函数
 * @param 		: 无
 * @return 		: 无
 */
int main(void)
{
	int_init(); 				/* 初始化中断(一定要最先调用!) */
	imx6u_clkinit();			/* 初始化系统时钟 			*/
	clk_enable();				/* 使能所有的时钟 			*/
	led_init();					/* 初始化led 			*/
	beep_init();				/* 初始化beep	 		*/
	key_init();					/* 初始化key 			*/
	epit1_init(0, 66000000/2);	/* 初始化EPIT1定时器,1分频
								 * 计数值为:66000000/2,也就是
								 * 定时周期为500ms。
								 */
	while(1)			
	{	
		delay(500);
	}

	return 0;
}
        main.c 里面就一个 main 函数,第 22 行调用函数 epit1_init 来初始化 EPIT1 ,分频值为 0 ,也就是 1 分频,加载寄存器值为 66000000/2=33000000 EPIT1 定时器中断周期为 500ms 。第26~29 行的 while 循环里面就只有一个延时函数,没有做其他处理,延时函数都可以去掉。