一. 高精度延时实验
我们使用 IMX6ULL芯片上的 GPT 定时器来实现。这里我们使用 GPT1定时器。
高精度延时实验工作如下:
1. GPIT1定时器初始化接口
(1) 设置定时器GPT1的软件复位,时钟源,工作模式,计数器值等。涉及 GPT1-CR 寄存器。
(2) 设置GPT1的分频数为66分频;
gpt_clk提供时钟源为 66MHZ,经过66分频后,最终提供给GPT1定时器的频率为 1Mhz。
(3) 输出比较通道配置比较值为最大,即为 0XFFFFFFFF
(4) 打开GPT1 定时器,涉及 GPT1-CR 寄存器。
2. 微妙延时函数
us 延时函数中,需要处理计数器溢出。实时读取 GPT1->CNT寄存器的值。
处理不同情况下的计数:在同一轮计数中的计数 与 在有溢出情况下的计数。
3. 毫秒延时函数实现
二. 代码实现
GPT1定时器与之前的 EPIT定时器一样都有定时中断功能。除此之外,还有其他的功能,例如,溢出中断等。
将之前 " 定时器消抖实验 "工程拷贝过来,直接在 /bsp/delay/目录下的 bsp_delay.c 文件,添加GPT1定时器代码。
bsp_delay.c文件代码如下:
#include "bsp_delay.h"
#include "imx6ull.h"
#include "bsp_int.h"
#include "bsp_led.h"
/* GPT1定时器初始化 */
void GPT1_delay_init(void)
{
GPT1->CR = 0;
//软件复位使能
GPT1->CR |= (1 << 15);
while((GPT1->CR >> 15) & 0X01); //等待复位结束
/*
*设置时钟源为ipg_clk=66MHZ,工作模式(restart-mode)
*默认计数器值从 0开始
*/
GPT1->CR |= (1 << 1) | (1 << 6);
//设置分频值为66MHZ
//频率为 66MHZ/66 = 1Mhz
GPT1->PR |= 65;
/* 设置计数器值
* 1Mhz的频率:计数器计一个数是 1us。
* 0XFFFFFFFF = 4294967295us = 71.5分钟
*/
GPT1->OCR[0] = 0XFFFFFFFF;
//打开GPT1定时器
GPT1->CR |= (1 << 0);
}
/* us延时函数*/
void us_delay(unsigned long us_time)
{
unsigned long old_cnt = 0, new_cnt = 0;
unsigned long time_cnt = 0;
old_cnt = GPT1->CNT;
while(1)
{
new_cnt = GPT1->CNT;
if(new_cnt != old_cnt) //计数器开始计时
{
if(new_cnt > old_cnt)
{
time_cnt += new_cnt - old_cnt;
}
else //已经发生了一次溢出,开始新一轮计数
{
time_cnt += 0XFFFFFFFF - old_cnt + new_cnt;
}
old_cnt = new_cnt;
if(time_cnt >= us_time)
{
break;
}
}
}
}
/*毫秒延时函数 */
void ms_delay(unsigned long ms_time)
{
while(ms_time)
{
us_delay(1000);
ms_time--;
}
}
至此,GPT1定时器实现了高精度延时实验。
本实验的关键工作有两项,其中包括:
1. GPT1定时器初始化工作。
2. us延时函数中,对计数器溢出的处理。
注意:
1. 一般带有软件复位功能的,我们需要使能软件复位功能。
2. 频率是 1 MHZ表示:计数器计一个数,是 1 微秒。