i.MX6ULL终结者EPIT定时器例程程序设计

本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\9_epit_timer 目录下。我们在Ubuntu系统下使用命令“mkdir 9_epit_timer”建立“9_epit_timer”文件夹,图 1所示:
在这里插入图片描述

图 1

然后使用“cd 9_epit_timer”命令进入到9_epit_timer文件夹,如图 2所示:
在这里插入图片描述

图 2

然后使用命令“cp -r …/8_int/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“9_epit_timer”里面,如图 3所示:
在这里插入图片描述

图 3

然后在drivers目录下建立epittimer文件夹,用来保存EPIT定时器的驱动文件,然后在“drivers/epittimer”目录中新建epittimer.h和epittimer.c两个文件,然后在epittimer.h文件输入下面的代码:

  1 #ifndef _BSP_EPITTIMER_H
  2 #define _BSP_EPITTIMER_H
  3 
  4 #include "imx6ul.h"
  5 
  6 
  7 /* 函数声明 */
  8 void epit1_init(unsigned int frac, unsigned int value);
  9 void epit1_irqhandler(void);
 10 
 11 #endif

我们在epittimer.h文件中声明了两个函数,一个是EPIT1的初始化,另一个是中断处理函数。接下来我们打开epittimer.c文件,在里面输入下面的代码:

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

epittimer.c文件我们定义了两个函数epit1_init(EPIT1初始化函数)和epit1_irqhandler(EPIT1中断处理函数)。

epit1_init函数有两个参数frac和value,frac是分频值,value是加载值。
第28行设置工作模式为set-and-forget,时钟源为66MHz。
第31行设置比较寄存器值为0(当计数器倒计到0的时候就会触发比较中断),所以分频值frac和加载值value决定了中断产生的频率,计算公式如下:
Tout = ((frac +1 )* value) / Tclk;
其中的Tclk是EPIT1的输入时钟频率,Tout是EPIT1的益出时间。如果我们现在要设置中断周期为500ms,可以设置分频值为0,(1分频),这样进入到EPIT1的时钟就是66MHz,那么500ms是1S的一半,即66000000/2=33000000,所以加载寄存器的值是33000000。

函数epit1_irqhandler是EPIT1的中断处理函数,进入此函数先读取EPIT1的SR寄存器的bit0判断是否是比较事件,如果是比较事件就翻转LED的状态,最后要写EPIT1的SR寄存器的bit0,清除中断标记。

然后我们修改main.c文件,在main.c里面输入下面的代码:

  1 #include "clk.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 #include "beep.h"
  5 #include "key.h"
  6 #include "int.h"
  7 #include "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 }

在main.c里的main函数中第22行调用了epit1_init函数来初始化EPIT1定时器,frac为0(1分频),加载寄存器66000000/2,设置的定时周期为500ms,最后进入whil(1)循环里面
只是做下延时。在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46635880/article/details/108879874