#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
循环里面就只有一个延时函数,没有做其他处理,延时函数都可以去掉。