首页天道酬勤,

,

张世龙 05-13 03:06 116次浏览

简要说明ARM Cortex-A7的计时器,周期性中断时机特点:

时钟源可选择的32位递减计数器12位的分频器在其计数值与比较值相等时产生中断。 即使被编程计数器值能够在低功耗和调试模式下被编程为主动状态原理分析结构分析

有三个时钟源可供选择:复用器、ipg_clk和时钟控制模块CCM提供的外设时钟; ipg_clk_32k :低频基准时钟、32kHz基准时钟、外部32kHz晶体振动; ipg_clk_highfreq :时钟控制模块CCM提供的高频参考时钟。 12位预分频器可以对时钟源进行分频,并且与12位相对应的值可以设置为04095,即14096分频。 EPIT内部、三个重要寄存器(32位) Counter Register、计数寄存器、EPIT是倒计时定时器,给定初始值后,从该初始值开始递减,直到变为0 Load Register是加载寄存器,如果EPIT设置为set-and-forget模式,则当计数器递减为0时,EPIT会将Load Register保存的值加载到Counter Register中,并比较寄存器是比较寄存器,用于与Counter Register的值进行比较,相等时生成比较事件。 比较器比较比较比较寄存器和计数器寄存器的值,如果相等,则发生比较事件,设定周边的管脚输出,指定管脚输出信号。 定时中断。 工作模式有set-and-forget和free-running两种,可以通过EPIT_CR[RLD]设定

EPIT_CR寄存器的RLD设定为1时,EPIT将以set-and-forget模式动作。 在此模式下,EPIT计时器的计数值从LoadRegister获取初始值,此时不能直接将数据写入CounterRegister。 当计数器的值递减为0时,从LoadRegister写入数据。当EPIT_CR寄存器的RLD清除0时,EPIT将在自由运行模式下工作,当计数器的值为0时,计数器的值为寄存器(部分)用于构成EPITx_CR、EPIT的寄存器

clk src (bit [ 25336024 ] :用于设置epit的时钟源

- CLKSRC时钟源00关断时钟源01Peripheral时钟10 high-frequency 11 low-frequencyprescalar (bit [ 153:4 ] ) EPIT时钟源的预分频值,12位

RLD(bit3) :用于设定EPIT的动作模式。 该bit为0时以自由运行模式动作,1时以设置和格式模式动作。

ocien(bit2) :比较中断允许位,设置为0时禁止比较中断,设置为1时允许比较中断。

enmod(bit1) :设定计数器的初始值。 如果设置为0,则计数器的初始值等于上次关闭EPIT计时器时计数器的值;如果设置为1,则初始值取决于RLD的配置。 RLD=1时,计数器的值来源于Load Register,RLD=0时,计数器的值为0xFFFF_FFFF

en(bit0) EPIT计时器使能。 0闭,1使能

寄存器EPITx_SR仅最低有效位(ocif(bit0) )与中断标志位进行比较。如果为0,则不发生比较事件,而如果为1,则发生比较时间。 需要手动清除。

溢出时间计算溢出时间=()分频值1 )负载值) /时钟频率

配置工艺设置时钟源,通过EPIT_CR寄存器的CLKSRC位选择设置计时器的预分频值,设置EPITx_CR寄存器的PRESCALAR,配置EPIT计时器时钟分频值设置工作模式,配置EPITx_CR 设置EPITx_CR的enmod(bit1),设置计数器的初始值源使能比较中断,设置EPITx_CR的OCIEN位,设置1以设置加载值(加载值)和比较值,以及EPITx_LR和eeen

代码编写(部分/* * * * * * * * * * * * * * filename : bsp _ epitauthor 3360 ori版本3360 v 1.0 descrip por2/2* * * * * * * * * * * * )

:0 */void epit1_init(unsigned int frac, unsigned int value){ if(frac > 0XFFF) frac = 0XFFF; /* 这里先设置为最大分频 */ EPIT1->CR = 0; /* 清零CR寄存器,为了方便后续配置 */ /* 66MHz,分频值为4,set-and-forget工作模式,值来源load register */ EPIT1->CR = (1<<24 | frac << 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)epit1_irqhandler, NULL); /* 使能EPIT1 */ EPIT1->CR |= 1<<0;}/* * @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; /* 清除中断标志位 */} /*************************** File name: bsp_epit Author: ori Version: v1.0 Description: EPIT驱动头文件 Others: 无 log: 2021/2/2 ***************************/#ifndef _BSP_EPIT_H#define _BSP_EPIT_H#include"imx6ul.h"void epit1_init(unsigned int frac, unsigned int value);void epit1_irqhandler(void);#endif // !1 /*************************** File name: bsp_epit Author: ori Version: v1.0 Description: EPIT练习 Others: 无 log: 2021/2/2 ***************************/#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_exit.h"#include "bsp_epit.h"/* * @description: main函数 * @param : 无 * @return : 无 */int main(void){int_init(); /* 初始化中断(一定要最先调用!) */imx6u_clkinit();/* 初始化系统时钟 */clk_enable();/* 使能所有的时钟 */led_init();/* 初始化led */beep_init();/* 初始化beep */key_init();/* 初始化key */exit_init();/* 初始化按键中断*//* 初始化EPIT定时器,1分频,计数值33000000,500ms */epit1_init(0,33000000);while(1){delay(500);}return 0;} 编译烧录

最后

本文多处参考正点原子的课程和资料(特表感谢),并在此基础上进了扩展和自己的理解,最后自己动手复原例程。

, ,