IMX6ULL之EPIT中断定时器实验说明二

一.    EPIT中断定时器

EPIT定时器:一种中断定时器。详细的介绍可以参考上一篇文章:

IMX6ULL裸机篇之按键中断实验_凌雪舞的博客-CSDN博客

本文学习一下 EPIT定时器的使用。实现如下功能:

实现 500ms 周期的定时器。

我们在 EPIT中断服务函数里,实现 LED灯亮灭。

二.   EPIT中断定时器实验

1.    EPIT中断定时器实验工作

(1)  设置 EPIT1 的时钟源,工作模式,时钟源选择,分频值,使能比较中断等。EPITx_CR 寄存器设置。

分频值与计数器加载值计算公式如下:

Tout = ((frac +1 )* value) / Tclk;
Tclk EPIT1 的输入时钟频率 ( 单位 Hz)
Tout EPIT1 的溢出时间 ( 单位 S)

(2)  EPIT1 中断设置

(3)  使能 GIC 中对应的 EPIT1 中断,注册中断服务函数。

如果需要,还可以设置中断优先级。

(4)  实现中断服务函数。
(5)  使能 EPIT1 定时器。

2.   计算计数加载值

分频值与计数器加载值计算公式如下:

Tout = ((frac +1 )* value) / Tclk;

其中,frac 是分频数,value 为待计算的计数加载值。

Tclk : EPIT1 的输入时钟频率(单位 Hz)。

Tout:EPIT1 的溢出时间(单位 S)。

时钟源的选择由如下四种。配置选择 ipg_clk 为时钟源。根据之前时钟源章节,可以知道 ipg_clk 时钟源提供了 66 MHZ的时钟频率。

 

秒与频率换算关系: 秒 = 1 / 频率。

这里选择 配置为 1 分频,即 frac 值为 0。

这个实验实现 500ms定时,即 Tout 值为 0.5 s(500 ms == 0.5s)

Tclk 是由 ipg_clk时钟源提供,由之前时钟实验可以知道, ipg_clk时钟频率为 66 MHZ,即 Tclk 66MHZ

通过以上公式计算可得:

value = (Tout * Tclk)/(0+1)

value = (0.5* 66000000HZ) = 33000000

3.  代码实现

bsp 文件夹下 创建名为" epittimer " 的文件夹,然后在该目录下创建 bsp_epittimer.c bsp_epittimer.h
bsp_epittimer.h 代码如下:
#ifndef      _BSP_EPIT_H_
#define      _BSP_EPIT_H_

#include "imx6ull.h"

void epit1_init(unsigned int freq_value, unsigned int reload_value);
void epit1_irq_hander(unsigned int gicciar, void* param);

#endif

bsp_epittimer.c文件代码如下:

#include "bsp_epit.h"
#include "bsp_int.h"
#include "bsp_led.h"


/* 初始化EPIT */
//freq_value: 分频数
//reload_value:  计数器加载值
void epit1_init(unsigned int freq_value, unsigned int reload_value)
{
    if(freq_value > 4095)
    {
        freq_value = 4095;
    }

    //配置EPIT1定时器的EPIT_CR寄存器
    EPIT1->CR = 0;
    EPIT1->CR = ((1 << 1)|(1 << 2)|(1 << 3)|(freq_value << 4)|(1 << 24));
    //配置EPITx_LR寄存器加载值(相当于倒计数器)
    EPIT1->LR = (reload_value << 0);  
    
    EPIT1->CMPR = 0; //配置EPITx_CMPR寄存器的比较值

    /*初始化中断 */
    GIC_EnableIRQ(EPIT1_IRQn);  //初始化GIC控制器
    /*注册中断函数 */
    system_register_irqhandler(EPIT1_IRQn, epit1_irq_hander, NULL);
    //使能 EPIT1定时器
    EPIT1->CR |= (1 << 0);
}

/* EPIT中断服务函数 */
void epit1_irq_hander(unsigned int gicciar, void* param)
{
    static unsigned int led_status = 0;

    led_status = !led_status;
    //判断中断标志位
    if(EPIT1->SR & (1 <<0)) //中断已发生
    {
        led_switch(LED0, led_status);
    }

    //清除中断标志位(注意:是写1清零!!!)
    EPIT1->SR |= (1 << 0);
}

主函数 main.c 中,添加定时器 EPIT1 的初始化,去掉 while 循环中涉及 LED 灯的操作。

main.c 代码如下:

#include "imx6ull.h"
#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_exter_int.h"
#include "bsp_epit.h"

int main(void)
{
    int_init();           //中断初始化
    imux6ull_clk_init();  //初始化系统时钟
    clk_enable();        //使能外设时钟
    led_init();          //Led初始化
    beep_init();         //蜂鸣器初始化
    key_init();         //key按键初始化
    exter_inter_init();  //Key0中断初始化
    epit1_init(0, 66000000/2); //EPIT1定时器初始化

    while(1);

    return 0;
}

经过测试,LED灯第一次亮的时间比后面的长。代码存在问题,经过检查发现,问题出现在 Led 初始化接口中。将 led_init()函数 LED 灯关闭即可。

bsp_led.c 中LED 初始化接口代码如下:

//Led初始化
void led_init(void)
{
    //复用为GPIO功能
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);
    //配置电气特性
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0X1070); 
    //配置为输出
    GPIO1->GDIR = 0X08;
    //关闭Led
    GPIO1->DR |= (1 << 3);		
}

以上就是裸机篇之的中断定时器 EPIT1 的实验。至此实验顺利完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: i.MX6 EPIT(Enhanced Periodic Interrupt Timer)是一种双向计时器,可用于实现嵌入式Linux中的计时器功能,如周期性中断、定期任务等。 i.MX6 EPIT定时器驱动是在Linux内核中实现EPIT的驱动程序,可通过/sys/class/timer/epit目录下的文件进行控制。该驱动程序使用了内核中的定时器子系统,支持定时器的配置、开启、关闭和重启功能。 EPIT定时器具有多种模式,可实现周期性中断、单次计时、连续计时等。驱动程序提供了获取当前定时器计数器和比较器值、设置比较器值、配置定时器模式和时钟源等接口。 在应用程序中,可以利用EPIT定时器驱动实现心跳包发送、数据采集、定时任务等功能。例如,定期采集传感器数据可以使用连续计时模式,每隔一段时间触发一次中断,读取传感器数据并进行处理,以便实现对数据的实时监测和分析。 总之,i.MX6 EPIT定时器驱动在嵌入式Linux系统中具有广泛的应用场景,是实现计时器功能的重要组成部分。 ### 回答2: i.mx6 epit定时器驱动是一种用于控制时间计数和时序操作的驱动程序。i.mx6 epit定时器驱动是针对ARM架构的一种硬件计时器,其可在一定时间范围内对计时周期进行划分,并且在计时到达特定时间节点时可以触发相应的中断信号。这种特性有助于对系统中各个模块的时间操控和协同进行更加精确和高效的管理。 在实现i.mx6 epit定时器驱动时,需要首先对硬件的时钟和计数器进行初始化,同时规划好所需要的计时周期及其对应的中断服务程序。其次,需要根据实际应用场景,选择合适的工作模式,比如定时器的循环工作模式和单次工作模式等。此外,i.mx6 epit定时器驱动还可通过设置各种定时器的触发条件、分频系数、计数器值、预定中断周期等参数来指导其工作。 i.mx6 epit定时器驱动在实际应用中,可以用于很多领域比如:测量仪、定时器中断控制、数据采集、总线同步、状态监测等。同时,在多任务操作系统中,也可以将i.mx6 epit定时器驱动与系统时钟的管理器进行集成,以实现更加高效和稳定的系统时间管理。 综上所述,i.mx6 epit定时器驱动是一种用于时间计数和时序操作的驱动程序,具有精确高效的特点,并且在多领域应用中有着广泛的应用价值。 ### 回答3: i.MX6 EPIT (Enhanced Periodic Interval Timer)是一种高级计时器,用于基于ARM Cortex-A9的i.MX6处理器。它具有精确的定时器功能和多种配置选项,可用于实现高精度周期性操作,如定时中断、PWM (脉宽调制)等。在嵌入式系统中,i.MX6 EPIT常用于实现精确定时、控制外设、任务切换等功能。 驱动i.MX6 EPIT定时器需要在内核中实现一个设备驱动程序。该驱动程序需要完成以下几个主要任务: 1. 初始化EPIT定时器,包括设置时钟源、预分频、计数模式、计时周期等。 2. 响应定时器中断,即在定时器达到预定的时间时触发中断。在中断处理程序中,可以执行相应的操作,如更新任务状态、控制外设、发送信号等。 3. 提供用户接口,允许应用程序通过ioctl系统调用配置和控制定时器。例如,可以通过ioctl命令来设置定时周期、使能定时器、暂停定时器等。 在实现EPIT定时器驱动时,需要注意以下几个关键点: 1. 时钟源选择。i.MX6处理器内部有多个时钟源可供选择,如ARM内核时钟、PLL时钟、外部时钟输入等。需要根据应用场景选择适合的时钟源,并进行相应的配置。 2. 计时精度。EPIT定时器的计时精度可以通过预分频系数和计数位宽来控制。需要根据具体需求进行合理的配置,以实现满足精度要求的定时功能。 3. 中断处理。在中断处理程序中,需要注意避免阻塞和死锁问题,防止同时发生多个中断导致系统崩溃。 4. 设备节点的创建和管理。通过设备节点,驱动程序可以与用户空间的应用程序进行交互。需要正确创建和管理设备节点,保证应用程序与驱动之间的通信正常进行。 总之,实现i.MX6 EPIT定时器驱动需要对硬件及其编程接口有一定的了解,同时结合系统需求进行合理的配置和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值