七. 定时器

1. EPIT定时器

EPIT ( Enhanced Periodic Interrupt Timer):增强的周期中断定时器

(1) 特征:

  1. 时钟源可选的32位向下计数器
  2. 12位的分频值
  3. 计数器和比较值相等时,产生中断

(2) 结构:

在这里插入图片描述

  1. 选择EPIT定时器的时钟源:ipg_clk,ipg_clk_32k,ipg_clk_highfreq。
  2. 12位的分频器,对应 1~4096分频
  3. 三个寄存器:EPIT_CNR(计数器),EPIT_LR(加载寄存器),EPTI_CMPR(比较寄存器)。
  4. 比较器
  5. 引脚输出:可设置 EPIT1_OUT,EPIT2_OUT输出
  6. 定时中断

(3) 工作模式:

set-and-forget 模式:
只要计数器计数到 0,那么就会从加载寄存器 EPITx_LR 中重新加载数据到计数器中
free-running 模式:
当计数器计数到0以后会重新从0XFFFFFFFF开始计数

(4) 寄存器

配置寄存器 EPITx_CR

CLKSRC(bit25:24): EPIT 时钟源选择位(ipg_clk=66MHz)
PRESCALAR(bit15:4): EPIT 时钟源分频值(12位)
RLD(bit3):工作模式:set-and-forget,free-running
OCIEN(bit2):比较中断使能位,
ENMOD(bit1):为 1 的时候来源于加载寄存器
EN(bit0): EPIT 使能位

EPITx_SR
OCIF(bit0) :中断标志位,此位是写 1 清零的。

(5) 配置步骤

  1. 设置 EPIT1 的时钟源
  2. 设置分频值
  3. 设置工作模式
  4. 设置计数器的初始值来源
  5. 使能比较中断
  6. 设置加载值和比较值
  7. EPIT1 中断设置和中断服务函数编写
  8. 使能 EPIT1 定时器

Tout = ((frac +1 )* value) / Tclk;
Tclk: 输入时钟(66M)
frac: 分频值
value: 加载寄存器
Tout: 输出

(6) 定时器消抖

使用定时器来实现按键消抖,防止按键中断内部出现延时函数。
在这里插入图片描述
上图中 t1 - t3 时间之内是,按键抖动。
t1, t2, t3 会触发按键中断。按键中断处理函数内开 10ms 的定时器中断。
因t1-t2, t2-t3的时间小于10ms,不会触发定时器中断。
t3后10ms,触发定时器中断,内部做原来的按键中断处理。

按键中断函数:

void filtertimer_restart(unsigned int value)
{
	EPIT1->CR &= ~(1<<0); /* 先关闭定时器 */
	EPIT1->LR = value; 	/* 计数值 */
	EPIT1->CR |= (1<<0); /* 打开定时器 */
}

void gpio1_16_31_irqhandler(void)
{
	filtertimer_restart(66000000/100); /* 开启定时器 */
	gpio_clearintflags(GPIO1, 18); /* 清除中断标志位 */
}

2. GPT 定时器

GPT(General Purpose Timer) 通用用途定时器。比EPIT更具有通用性。
可实现的功能:测量时间间隔、生成定时脉冲、执行时间相关的操作。

(1) 特征

  1. 可选时钟源的 32 位向上计数器
  2. 两个输入捕获通道,可以设置触发方式
  3. 三个输出比较通道,可以设置输出模式
  4. 可以生成捕获中断、比较中断和溢出中断
  5. 计数器可以运行在重新启动(restart)或(自由运行)free-run 模式

(2) 结构

时钟选择:ipg_clk_24M、 GPT_CLK(外部时钟)、ipg_clk、ipg_clk_32k 和 ipg_clk_highfreq。
选择 ipg_clk=66MHz
在这里插入图片描述
在这里插入图片描述

  1. GPT 定时器的时钟源
  2. 12 位分频器
  3. GPT 定时器内部 32 位计数器
  4. GPT 的两路输入捕获通道
  5. GPT 的两路输入捕获通道
  6. 输出比较寄存器,三个输出比较寄存器
  7. 输出比较中断

(3) 工作模式

重新启动(restart)模式和自由运行(free-run)模式
重新启动(restart)模式
当计数值和比较寄存器中的值相等的话计数值就会清零,
比较通道 1 才有此模式
自由运行(free-run)模式
当比较事件发生以后并不会复位计数器,而是继续计数,直到计数值为 0XFFFFFFFF,然后重新回滚到 0X00000000。

(4) 寄存器

<1> GPTx_CR 配置

在这里插入图片描述
SWR(bit15):复位 GPT 定时器,写 1 复位 GPT 定时器
FRR(bit9):运行模式,restart / free-run
CLKSRC(bit8:6):钟源选择位 001(ipg_clk)
ENMOD(bit1): 关闭后是否计数清零
EN(bit): GPT 使能位

<2> GPTx_PR 分频

PRESCALER(bit11:0),这就是 12 位分频值,可设置 0~4095,分别对应 1~4096 分频

<3> GPTx_SR 状态

ROV(bit5): 回滚标志位,计数值从 0XFFFFFFFF 回滚到 0 的时候此位置 1
IF2~IF1(bit4:3):输入捕获标志位
OF3~OF1(bit2:0):输出比较中断标志位,比较事件发生以后此位置 1

<4> GPTx_CNT 计数

保存着 GPT 定时器的当前计数值

<5> GPTx_OCR 比较

三个比较寄存器,GPTx_OCR1-3,存放这三路比较值。可用于触发中断。

(5) 实现高精度延时

设置计数频率为1M,ipg_clk=66MHz,设置 66 分频
GPTx_CNT 计数周期为 1us。

<1> 步骤

  1. 设置 GPT1 定时器,GPTx_CR
  2. 设置 GPT1 的分频值
  3. 设置 GPT1 的比较值
  4. 使能 GPT1 定时器
  5. 编写延时函数

<2> 实现

void delayus(unsigned int usdelay)
{
	unsigned long oldcnt,newcnt;
	unsigned long tcntvalue = 0; /* 走过的总时间 */

	oldcnt = GPT1->CNT;
	while(1)
	{
		newcnt = GPT1->CNT;
		if(newcnt != oldcnt)
		{
			if(newcnt > oldcnt) /* GPT 是向上计数器,并且没有溢出 */
				tcntvalue += newcnt - oldcnt;
			else /* 发生溢出 */
				tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;

			oldcnt = newcnt;
			if(tcntvalue >= usdelay) /* 延时时间到了 */
				break; /* 跳出 */
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值