中级会员
- 积分
- 254
- 金钱
- 254
- 注册时间
- 2020-3-22
- 在线时间
- 35 小时
|
本帖最后由 YOKI 于 2020-6-7 15:55 编辑
好久没有发帖了,今天补充一下定时器的帖子。
/********************************************/
时间 :2020/04/10/
作者 :YOKI
导师 :正点原子 左忠凯
硬件 :正点原子 ALPHA I.MX LINUX 开发板
/*******************************************/
EPIT 周期中断定时器
既然讲定时器,那肯定和时钟有关 本节先回顾一下时钟相关的内容:
在 bsp_clk.c 中有一个总线时钟配置函数
/* AHB_CLK_ROOT 总线时钟频率设置 */
void AHB_CLK_ROOT_init(void)
{
int PERIPH_CLK_SEL_BUSY = ((CCM->CDHIPR >> 5) & 0X01); //外设时钟 判忙标志位
int AHB_PODF_BUSY = ((CCM->CDHIPR >> 1) & 0X01); //总线时钟分频 判忙标志位
int MMDC_CH0_MASK = 1;
CCM->CCDR |= (MMDC_CH0_MASK << 17);/* CCM_CCDR bit17 置1 不允许 PRE_PERIPH_CLK_SEL 握手*/
CCM->CBCMR |= (01<<18 ); /* CCM_CBCMR bit18-bit19 PRE_PERIPH_CLK_SEL=01 时钟源 PLL2 PFD2 不分频*/
while(PERIPH_CLK_SEL_BUSY); /* 等待 PERIPH_CLK_SEL_BUSY 清零 */
CCM->CBCDR &= ~(1<<25 ); /* CCM_CBCDR bit25 PERIPH_CLK_SEL=0 时钟源 PLL2 PFD2 */
while(AHB_PODF_BUSY); /* 等待 AHB_PODF_BUSY 清零 */
CCM->CBCDR |= (3<<10); /* CCM_CBCDR bit10-bit12 AHB_PODF=011 时钟源 4 分频 */
CCM->CCDR &= ~(MMDC_CH0_MASK << 17);/* CCM_CCDR bit17 置0 允许 PRE_PERIPH_CLK_SEL 握手*/
/* 5、设置IPG_CLK_ROOT最小3Mhz,最大66Mhz (boot rom自动设置好了可以不用设置)*/
CCM->CBCDR &= ~(3 << 8); /* CBCDR的IPG_PODF清零 */
CCM->CBCDR |= (1 << 8); /* IPG_PODF 2分频,IPG_CLK_ROOT=66MHz */
/* 6、设置PERCLK_CLK_ROOT时钟 */
CCM->CSCMR1 &= ~(1 << 6); /* PERCLK_CLK_ROOT时钟源为IPG */
CCM->CSCMR1 &= ~(7 << 0); /* PERCLK_PODF位清零,即1分频 */
}
其中 第5部分 是和EPIT有关的时钟设置(ipg_clk):
CCM->CBCDR &= ~(3 << 8); /* CBCDR的IPG_PODF清零 */
CCM->CBCDR |= (01 << 8); /* IPG_PODF 2分频,IPG_CLK_ROOT=66MHz */
IPG_CLK_ROOT 由CCM_CBCDR来控制,
IPG_CLK 来自 总线时钟 AHB_CLK_ROOT 的 2分频(修改CBCDR寄存器 可设置不同值)
AHB_CLK_ROOT 来自 PLL2 的 4分频(修改CBCDR寄存器 可设置不同值)
即 PLL2 =528 MHz IPG_CLK = ((528MHz/2)/4)= 66MHz 也就是说,IPG_CLK会随 PLL2 的修改变动
EPIT 周期中断定时器的时钟源由3个:
1、 IPG_CLK
2、 IPG_CLK_32K
3、 IPG_CLK_highfreq
这里选用IPG_CLK 作为时钟源,EPIT是32位的向下(减1)周期性计时器,
EPIT 周期中断定时器的工作机制如下:
用户给定一个计数值(重装载值) 存到 EPITx—LR 寄存器,再给定一个值(比较值)到 EPITx—CMPR 寄存器,
当计数器每个时钟周期 减1 同时和EPITx—CMPR 寄存器的值比较 ,当减到 比较值 时产生一个中断信号再重新装载计数值。
EPIT 有2种工作模式(通过EPIT_CR 寄存器 的 RLD位(bit3) 设定):
1、set and forget (bit3 = 1) : 计数值由用户给定,自动重装
2、free runing (bit3 = 0) : 计数值 = 0xFFFF FFFF,自动重装;
当EPIT 减到比较值或者0x0000 0000 时会产生中断也可从指定引脚输出信号
中断号:(EPIT1_IRQn = 88;EPIT2_IRQn = 89 )
EPITx_CR 寄存器(EPIT控制寄存器)个位含义
bit0: EN 写 1 EPIT使能
bit1: ENMOD 写 1 EPIT从装载值开始计数;写 0 从上一次计数停止的值开始计数
bit2: OCIEN 写 1 比较中断使能
bit3: RLD 写 1 set and forget模式;写 0 free runing模式
bit15-bit4: PRESCALAR 时钟分频 0x000 -0xFFF 1分频 - 4096分频
bit16: SWR 写 1 EPIT 复位
bit25-bit24: CLKSRC 时钟选择 01 PREPERIPH_CLK 即 IPG_CLK
其它位请看参考手册。
EPITx_LR 重装载值寄存器
EPITx_CMPR 比较值寄存器
EPITx_SR EPITx状态寄存器 发生中断(计时满一个周期)时值为1,写 1 清零。
其它寄存器请看参考手册根据以上原理编写 EPIT 初始化函数 和中断处理函数如下:
/******************** 初始化EPIT1 ****************/
/* 参数1: frac 分频值 分频值 0~4096 */
/* 参数2: reload_value 重装载值 */
/***********************************************/
void EPIT1_init(unsigned int frac,unsigned int reload_value)
{
frac = frac-1;
if(frac > 4095)
{
frac=4095;
}
EPIT1->CR = 0; /* 先清零CR寄存器 */
EPIT1->CR |= (1 << 1) | //写 1 EPIT1从装载值开始计数
(1 << 2) | //写 1 比较中断使能
(1 << 3) | //写 1 set and forget模式
(frac << 4) | //写分频值
(01 << 24); //写 01 时钟选择 IPG_CLK
EPIT1->LR = reload_value; //写重装载值
EPIT1->CMPR = 0x00000000; //比较值为0 即倒计数到 0 发生中断
GIC_EnableIRQ(EPIT1_IRQn); //EPIT1_IRQn 中断ID 使能 中断ID=88
Systerm_register_IRQ_Handler(EPIT1_IRQn,EPIT1_IRQ_Handel,NULL); //注册中断
EPIT1->CR |= (1 << 0); //EPIT1 使能
}
/* EPIT1中断处理函数 */
void EPIT1_IRQ_Handel(unsigned int gicc_IAR, void *param)
{ static unsigned char state = 0;
if(EPIT1->SR & (1<<0)) /* 判断比较事件发生 */
{
/* 添加用户代码段 */ LED(state); state = ~state;
}
EPIT1->SR |= (1<<0); //写EPIT1_SR 写1清零 清除中断标志位
// GIC_DeactivateIRQ(EPIT1_IRQn); //向 GICC_EOIR 写入发送中断的中断号来释放中断
// EPIT1->CR &= ~(1 << 0); //EPIT1 关闭
}
在中断函数中可以通过添加其他代码 或 调用其他函数来实现蜂鸣器及LED 灯的响应;
/**********************************************************************************************/
以上注释和代码都是在学习 《正点原子 linux 第二期 裸机开发视频 P30-P36 第15讲 中断系统 》 过程中
跟着 左萌主 学习并加入了一点点自己的思考写成的,作为一个小菜鸡,我大着胆子发出来跟大家一起记录学习
如果有帮助请大家自行参考、下载,如果 转载 请注明出处,并在论坛和我联系。如果有错误请大神指正!左萌主赛高!
作者 :YOKI
导师 :正点原子 左忠凯 (请允许我叫你一声导师吧)
硬件 :正点原子 ALPHA I.MX LINUX 开发板
/*********************************************************************************************/
|
|