一、定时器介绍
原理图:
时间计算:T = 1 / F = 1/100HZ = 0.01S
二、I.MX6ull GPT定时器介绍
简介:
GPT内部寄存器
1.GPT定时器工作原理
(1)选择时钟信号
The clock that is input to the prescaler can be selected from 4 clock sources. The following table describes theclock sources for GPT. Please see Clock Controller Module (CCM) for clock setting, configuration and gatinginformation.
输入到预定标器的时钟可以从4个时钟源中选择。下表描述了GPT的时钟源。有关时钟设置、配置和门控信息,请参阅时钟控制器模块(CCM)
可以从 4 个时钟源中选择输入到预分频器的时钟,分别为:
高频参考时钟(ipg_clk_highfreq)
低频参考时钟(ipg_clk_32k)
外围时钟(ipg_clk)
外部时钟(GPT_CLK)或者晶体振荡器时钟(ipg_clk_24M)
外部时钟(GPT_CLK)或者晶体振荡器时钟(ipg_clk_24M)只能选择一个。
这里我们选择ipg_cIk=66MHZ作为GPT定时器的输入时钟源,芯片在启动的时候,芯片内部的程序已经做了系统时钟初始化,初始化的时钟频率如下:
时钟源选择寄存器:
预分频设置寄存器:
A.ipg_clk :66000kHZ
B.Prescaler:65
最终GPT定时器的输入时钟源:66000kHZ/(65+1)=1000KHZ,周期为 1us。3也就是说每隔1us,GPT内部的计数器值+1,GPTx_CNT 是个32位寄存器,
GPTx_CNT最大的值是0XFFFFFFFF,也就是OXFFFFFFFFuS=4294967295us=4294s*72min。也就是说72分钟以后GPTx_CNT寄存器就会回滚到0X00000000
(2)GPT计数器工作模式
The GPT counter can be programmed to work in either of two modes: Restart mode or Free-Run mode.
GPT计数器可以编程为以两种模式之一工作:重新启动模式或自由运行模式
Restart Mode
In Restart mode (selectable through the GPT Control Register GPT CR), when the counterreaches the compared value, the counter resets and starts again from 0x00000000.
在重新启动模式下(可通过GPT控制寄存器GPT_CR选择),当计数器达到比较值时,计数器复位并从
0x00000000再次启动。The Restart feature is associated only with Compare channel 1. Any write access to the Compareregister of Channel 1 will reset the GPT counter, This is done to avoid possibly missing a compare event whencompare value is changed from a higher value to lower value while counting is proceeding. For the other twocompare channels, when the compare event occurs the counter is not reset.
重新启动功能仅与比较通道1相关联。对通道1的比较寄存器的任何写访问都将重置GPT计数器。这样做是为了避免在计数进行时比较值从较高值更改为较低值时可能丢失比较事件。对于其他两个比较通道,当比较事件发生时,计数器不会重置。
Free-Run Mode
In Free-Run mode, when compare events occur for all 3 channels, the counter is not reset, instead thecounter continues to count until 0xfffffff, ahd then rolls over (to 0x00000000)
在自由运行模式下,当所有3个通道发生比较事件时,计数器不会重置;相反,计数器继续计数,直到0xfffFFF然后滚动(到0x00000000)
计数器工作模式选择寄存器:
(3)GPT操作
The General Purpose Timer (GPT) has a single counter (GPT CNT) that is a 32-bit free-running up-counter, which starts counting after it is enabled by software (EN=1).
通用计时器(GPT)有一个计数器(GPTCNT),它是一个32位自由运行的向上计数器,它在软件启用后开始计数(EN=1)。
计数器使能寄存器
读计数器寄存器
使能位模式位和使能位寄存器
If the GPT timer is disabled (EN=0), then the Main Counter and Prescaler Counter freeze their current countvalues. The ENMOD bit determines the value of the GPT counter when the EN bit is set and the Counter isenabled again.
如果禁用GPT计时器(EN=0),则主计数器和预分频计数器将冻结其当前计数值。ENMOD位确定设置EN位并再次启用计数器时GPT计数器的值。
.If the ENMOD bit is set (=1), then the Main Counter and Prescaler Counter values are reset to 0, when GPTis enabled (EN=1).
如果设置了ENMOD位(=1),则启用GPT时,主计数器和预分频器计数器值将重置为0(EN=1)
.If ENMOD bit is programmed to 0, then the Main Counter and Prescaler Counter restart counting from theirfrozen values, when GPT is enabled again(EN=1).
如果ENMOD位被编程为0,则当GPT再次启用时(EN=1),主计数器和预分频器计数器从其冻结值重新开始计数。
硬件复位
A hardware reset resets all the GPT registers to their respective reset values. All registers except theOutput Compare Registers (0CR1, OcR2, 0cR3) obtain a value of 0x0. The Compare registers are reset toOXFFFF FFFF.
硬件重置将所有GPT寄存器重置为各自的重置值,除了输出比较寄存器(OCR1、OCR2、OCR3)之外的所有寄存器都获得0x0的值。比较寄存器重置为0xFFFF FFFF。
软件复位
The software reset (SWR bit in the GpT CR control register) resets all of the register bits exceptthe EN, ENMOD, STOPEN, WAITEN, and DBGEN bits. The state of these bits is not affected by a softwarereset, Note that a software reset can be given while the GPT is disabled.软件复位(GPT_CR控制寄存器中的SWR位)复位EN、ENMOD、STOPEN、WAITEN和DBGEN位之外的所有寄存器位。这些位的状态不受软件复位的影响。请注意,在用GPT时,可以进行软件复位。
2.GPT的输入捕获
(1)输入捕获使用场景
在嵌入式开发中,我们常需要捕获传感器的高电平(或低电平)信号的持续时间,如红外解码信号、编码器输入信号等。
从直观上理解,就是要不断的检测这个信号,当信号从0变到1时,记录一个时间,再从1变到0时,记录另一个时间,两个时间差就是高电平的持续时间了。
(2)输入捕获工作原理
启动定时器,让CNT计数器在不停的计数
首先配置定时器的输入通道为上升沿捕获,这样当检测到从0到1的跳变时,ICR就会先保存当前的CNT值
然后将定时器的输入通道为下降沿捕获,当检测从1到0的跳变时,ICR就会先保存当前的CNT值
最终我们根据两次捕获的值,就可以计算出高电平持续的时间
捕获寄存器
(3)GPT的输入捕获操作
There are two Input Capture Channels, and each Input Capture Channel has a dedicated capture pin, captureregister and input edge detection/selection logic. Each input capture function has an associated status flag,and can cause the processor to make an interrupt service reguest.
有两个输入捕获通道,每个输入捕获通道都有一个专用的捕获引脚、捕获寄存器和输入边缘检测/选择逻辑。每个输入捕获功能都有一个关联的状态标志,可以导致处理器发出中断服务请求。
When a selected edge transition occurs on an Input Capture pin, the contents of the GPT CNT iscaptured on the corresponding capture register and the appropriate interrupt status flag is set, Aninterrupt request can be generated when the transition is detected ifits corresponding enable bit is set (in theInterrupt Register), The capture can be programmed to occur on the input pin's rising edge, fallingedge, on both rising and falling edges, or the capture can be disabled. The events are synchronizedwith the clock that was selected to run the counter, Only those transitions that occur at least one clock cycle(clock selected to run the counter) after the previous recorded transition will be guaranteed to trigger acapture event. There can be up to one clock cycle of uncertainty in the latching of the input transition. TheInput Capture registers can be read at any time without affecting their values.
当输入捕获引脚上发生选定的边缘转换时,GPT_CNT的内容将在相应的捕获寄存器上捕获,并设置适当的中断状态标志。如果设置了相应的使能位(在中断寄存器中),则可以在检测到转换时生成中断请求。捕获可以编程为发生在输入引脚的上升沿、下降沿、上升沿和下降沿上,或者可以禁用捕获。事件与选择运行计数器的时钟同步。只有在先前记录的转换之后至少一个时钟周期(选择运行计数器的时钟)发生的转换才能保证触发捕获事件。输入转换的锁定中最多可以有一个时钟周期的不确定性。输入捕获寄存器可以在任何时候读取,而不会影响它们的值。
控制寄存器设置捕获时机
状态标志寄存器判断捕获是否产生
读捕获值寄存器
3.GPT的输出比较
The three Output Compare Channels use the same counter (GPT CNT) as the Input Capture Channels. Whenthe programmed content of an Output Compare register matches the value in GpT cNT, anoutput compare status flag is set and an interrupt is generated (if the corresponding bit is set inthe interrupt register). Consequently, the Output Compare timer pin will be set, cleared, togglednot affected at all or provide an active-low pulse for one input clock period
三个输出比较通道使用相同的计数器(GPT_CNT)作为输入捕获通道。当输出比较寄存器的编程内容与GPT_CNT中的值匹配时,设置输出比较状态标志并生成中断(如果在中断寄存器中设置了相应的位)。因此,输出比较定时器引脚将被设置、清除、切换、完全不受影响或输出一个低脉冲(脉冲持续时间为定时器的时钟源的周期)
输出通道
输出动作寄存器
可设置输出动作
状态标志寄存器
here is also a-'forced-compare" feature that allows the software to generate a compare eventwhen reguired, without the condition of the counter value that is equal to the compare value. Theaction taken as a result of a forced compare is the same as when an output compare matchoccurs, except that the status flags are not set and no interrupt can be generated. Forced channelstake programmed action immediately after the write to the force-compare bits. These bits are self-negatingand always read as zeros.
还有一个“强制比较(forced-compare)"功能,一旦设置,就会马上产生比较事件;不管当前计数器值是 否等于比较值。强制比较的产生的事件,跟正常的输出事件相同,只是它不会设置状态标记位并且不会产生中断。一旦设置 force-compare 位,该事件会即刻产生,这个位是自动清除的,读的话一直零。
比较寄存器值设置寄存器
三、高精度延时实现
1、实现思路
软件复位GPT定时器
确定GPT定时器的时钟源确定比较寄存器的值(根据延时时间来确定)
开启GPT定时器
等待输出比较事件产生
关闭GPT定时器
2、编程实现
gpt.c
#include "imx6ull.h"
/*GPT 初始化*/
void gpt_init()
{
/*Reset GPT*/
GPT1->CR |= (1 << 15);//复位
while (GPT1 ->CR &(1 << 15))
{
/* 等待复位结束 */
}
/*Select Clock:IPG时钟源选择*/
GPT1->CR &= ~(0x7 << 6);
GPT1->CR |= (0x1 << 6);
/*
The GPT Prescaler:65预分配器设置
GPT Clock = 66MHZ/(65+1) = 66MHZ =>1us
*/
GPT1->PR = 65;
return;
}
/*等待比较时间产生*/
void wait_cmp_event(void)
{
int flag;
do
{
flag = GPT1->SR & (1 << 0);//等待比较时间产生
} while (!flag);
return;
}
/*开启定时器*/
void gpt_start(void)
{
GPT1->CR |= (1 << 9) | (1 << 1) | (1 << 0);
return;
}
/*关闭定时器*/
void gpt_stop(void)
{
GPT1->CR &= ~(1 << 0);
}
/*微秒延时函数*/
void gpt_delay_us(uint32_t us)
{
gpt_init();//初始化
GPT1->OCR1 = us;//选择通道1
gpt_start();//开启定时器
wait_cmp_event();//比较时间产生
gpt_stop();//关闭定时器
return;
}
/*毫秒延时函数*/
void gpt_delay_ms(uint32_t ms)
{
gpt_init();//初始化
GPT1->OCR1 = ms*1000;//选择通道1
gpt_start();//开启定时器
wait_cmp_event();//比较时间产生
gpt_stop();//关闭定时器
return;
}
/*秒延时函数*/
void gpt_delay_sec(uint32_t sec)
{
gpt_delay_ms(sec * 1000);//毫秒延时
return;
}
/*延时函数测试*/
void gpt_test(void)
{
led_init();//LED初始化
while (1)
{
led_on();//开灯
gpt_delay_sec(3);//大约延时1s
led_off();//关灯
gpt_delay_sec(3);//大约延时1s
}
return;
}
main.c
extern void gpt_test(void);
int main(void)
{
gpt_test();
return 0;
}
led.c
#include "imx6ull.h"
/* LED初始化 */
void led_init(void)
{
/*GPIO MODE*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO27 &= ~(0xf << 0);//位清零
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO27 |= (0x5 << 0);//设置IOMUXC控制器将管脚复用为GOIO功能模式
/*Direction:Output*/
GPIO1->GDIR |= (1 << 27);//设置GPIO管脚为输出方向
/*Enable GPIO1 Clock*/
CCM_CCGR1 |= (0x30 << 26);//打开GPIO管脚的时钟信号
}
/* 开灯 */
void led_on(void)
{
GPIO1->DR |= (1 << 27);//设置GPIO 管脚输出高电平
}
/* 关灯 */
void led_off(void)
{
GPIO1->DR &= ~(1 << 27);//设置GPIO 管脚输出低电平
}
/* 延时 */
void delay_time(uint32_t time)
{
int i;
int j;
for(i = 0; i < time * 1000; i++)
{
for(j = 0; j < 50000; j++)
{
}
}
}
void led_test(void)
{
led_init();//LED初始化
while (1)
{
led_on();//开灯
delay_time(1);//大约延时1s
led_off();//关灯
delay_time(1);//大约延时1s
}
return;
}