ARM裸机开发:EPIT定时器

举报
JeckXu666 发表于 2022/01/14 23:16:22 2022/01/14
【摘要】 文章目录 ARM裸机开发:EPIT定时器一、硬件平台:二、原理分析2.1 EPIT 定时器简介2.2 EPIT 主要寄存器2.3 EPIT 使用方式 三、程序编写四、实验现象 AR...

ARM裸机开发:EPIT定时器

一、硬件平台:

正点原子I.MX6U阿尔法开发板

_533488159_IMG_20210803_235508_1628006109000_xg_0

二、原理分析

I.MX6U 提供了多种硬件定时器,有些定时器功能强大;本章 EPIT 定时器是其最基本的定时器!

2.1 EPIT 定时器简介

EPIT 全称:Enhanced Periodic Interrupt Timer(增强的周期中断定时器),用于完成周期性中断定时;

在 STM32 中,单片机的定时器除了周期性中断定时之外,还可以进行输入捕获和 PWM 输出功能,而 EPIT 仅支持周期性中断定时功能;

EPIT 是一个 32 位定时器,有如下特点:

  • 时钟源可选的 32 位向下计数器
  • 12 位的分频值
  • 当计数值和比较值相等的时候产生中断

定时器结构如图:

20211117145534

其原理路线如下:

通过 1 选择时钟源,经过 12 位的分频器 2 进行分频,分频后的时钟提供给 32 位的计数寄存器 3,计数寄存器(EPIT_CNR)向下计数,通过比较器 4 和 32 位的比较寄存器(EPIT_CMPR)进行比较,到达计数周期后从加载寄存器(EPIT_LR)重新加载计数值,同时产生一个比较事件 6,也可以设置引脚输出,如果设置了的话就会通过指定的引脚输出信号,对应图中 5

EPIT 定时器有两种工作模式:

  • set-and-forget 模式:

在此模式下 EPIT 的计数器从加载寄存器 EPITx_LR 中获取初始值,不能直接向计数器寄存 器写入数据,只要计数器计数到 0,那么就会从加载寄存器 EPITx_LR 中重新 加载数据到计数器中

  • free-running 模式:

作在此模式下,当计数器计数到0以后会重新从0XFFFFFFFF开始计数,并不是从加载寄存器EPITx_LR中获取数据

2.2 EPIT 主要寄存器

EPIT 的配置寄存器 EPITx_CR

20211117151208

主要位:

功能
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 的时候工作在 setand-forget 模式
OCIEN(bit2) 比较中断使能位
0 的时候关闭比较中断
1 的时候使能比较中断
ENMOD(bit1) 设置计数器初始值
0 时计数器初始值等于上次关闭 EPIT 定时器以后计数器里面的值
1 的时候来源于加载寄存器
EN(bit0) EPIT 使能位
0 的时候关闭 EPIT
1 的时候使能 EPIT

EPITx_SR 标志寄存器:

20211117151908

只有一个位有效,那就是 OCIF (bit0),这个位是比较中断标志位,为 0 的 时候表示没有比较事件发生,为 1 的时候表示有比较事件发生。

比较中断发生以后需要手动清除此位,此位是写 1 清零的

2.3 EPIT 使用方式

使用步骤流程如下:

  • 设置 EPIT1 的时钟源
    设置寄存器 EPIT1_CR 寄存器的 CLKSRC(bit25:24)位,选择 EPIT1 的时钟源
  • 设置分频值
    设置寄存器 EPIT1_CR 寄存器的 PRESCALAR(bit15:4)位,设置分频值
  • 设置工作模式
    设置寄存器 EPIT1_CR 的 RLD(bit3)位,设置 EPTI1 的工作模式
  • 设置计数器的初始值来源
    设置寄存器 EPIT1_CR 的 ENMOD(bit1)位,设置计数器的初始值来源
  • 使能比较中断
    我们要使用到比较中断,因此需要设置寄存器 EPIT1_CR 的 OCIEN(bit2)位,使能比较中断
  • 设置加载值和比较值
    设置寄存器 EPIT1_LR 中的加载值和寄存器 EPIT1_CMPR 中的比较值,通过这两个寄存器就可以决定定时器的中断周期
  • EPIT1 中断设置和中断服务函数编写
    使能 GIC 中对应的 EPIT1 中断,注册中断服务函数,如果需要的话还可以设置中断优先级。最后编写中断服务函数
  • 使能 EPIT1 定时器
    通过寄存器 EPIT1_CR 的 EN(bit0)位来设置

三、程序编写

本节在上一章按键输入中断的过程下继续扩展,先复制一遍工程,然后添加 bsp_epit 文件夹和模块

20211117153147

模块 .h 头文件:

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

void epit_init(unsigned int frac,unsigned int value);
void epit_irqhandler(void);

#endif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

模块 .c 文件:

#include "bsp_epit.h"
#include "bsp_int.h"
#include "bsp_led.h"
//初始化函数
void epit_init(unsigned int psc,unsigned int value)
{
    if(psc>0xfff)
        psc=0xfff;
    EPIT1->CR = 0;

    EPIT1->CR = (1<<24 | psc<<4 | 1<<3 | 1<<2 | 1<<1);
    EPIT1->LR = value;
    EPIT1->CMPR = 0;

    GIC_EnableIRQ(EPIT1_IRQn);

    system_register_irqhandler(EPIT1_IRQn,
                                (system_irq_handler_t)epit_irqhandler,
                                NULL);
    EPIT1->CR = 1<<0;
}
//定时器中断回调函数
void epit_irqhandler(void)
{
    static unsigned char sta = 0;
    sta = !sta;
    if(EPIT1->SR & (1<<0))
    {
        if(sta)
            LED_ON();
        else
            LED_OFF();
    }
    EPIT1->SR |= 1<<0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

主函数代码:

#include "bsp_led.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_exit.h"
#include "bsp_epit.h"
#include "imx6ul.h"
int main(void)
{
    CLK_INIT();
    int_init();
    BSP_KEY_INIT();
    LED_INIT();
    exit_init();
    //设置定时器的分频为1,加载寄存器值为 66000000/2=33000000
    //即定时器中断周期为 500ms
    epit_init(0,66000000/2);
    while (1)
    {
        /* code */
        delay(100);
    }
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

修改 Makefile 添加编译路径:

20211117155051

make 一下,编译通过,下载程序

20211117155156

四、实验现象

可以看到 LED 灯周期性的闪烁,跳变间隔约 0.5 S

文章来源: blog.csdn.net,作者:JeckXu666,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_45396672/article/details/121380440

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200