一 簡介
GPT的全稱是General Purpose Timer,它是一個(gè)32位的向上的定時(shí)器, GPT 定時(shí)器也可以跟一個(gè)值進(jìn)行比較,當(dāng)計(jì)數(shù)器值和這個(gè)值相等的話就發(fā)生比較事件,產(chǎn)生比較中斷。GPT 定時(shí)器有一個(gè) 12 位的分頻器,可以對(duì) GPT 定時(shí)器的時(shí)鐘源進(jìn)行分頻。 分析方式同EPTI?
它具有以下特點(diǎn):
1.一個(gè)可選時(shí)鐘源的32位向上計(jì)數(shù)器。
2.兩個(gè)輸入捕獲通道,可以設(shè)置觸發(fā)方式。
3.三個(gè)輸出比較通道,可以設(shè)置輸出模式。
4.可以生成捕獲中斷、比較中斷和溢出中斷。
5.計(jì)數(shù)器可以運(yùn)行在重新啟動(dòng)(restart)或(自由運(yùn)行)free-run模式。
二 結(jié)構(gòu)原理圖
2.1 ?時(shí)鐘源
五個(gè)時(shí)鐘源,分別為:ipg_clk_24M、GPT_CLK(外部時(shí)鐘)、ipg_clk=66MHz、ipg_clk_32k和ipg_clk_highfreq? ?
?2.2 ?內(nèi)部結(jié)構(gòu)
?2.3 工作原理
????????通過設(shè)置定時(shí)器工作頻率確定計(jì)數(shù)器加1耗時(shí)t,延時(shí)時(shí)間 D/t = N 確定計(jì)數(shù)器計(jì)數(shù)值,輪詢讀取計(jì)數(shù)器( GPTx_CNT )值為N即為延時(shí) D.
?????????比如選擇ipg_clk =66MHz,然后時(shí)鐘源通過一個(gè)12位的分頻器,分頻以后進(jìn)入32位的GPT定時(shí)器內(nèi)部。我們選擇分頻參數(shù)為66,那么進(jìn)入GPT定時(shí)器的頻率就是1MHz了。1MHz的周期是1us,也就是說GPT的計(jì)數(shù)器每加一,就是經(jīng)過了1us,如果累計(jì)加了20個(gè)數(shù),就是20us。所以我們可以通過讀取GPT計(jì)數(shù)器中的數(shù)值累加的個(gè)數(shù),就知道經(jīng)過的時(shí)間了。比如我們現(xiàn)在要延時(shí)50us,那么我們進(jìn)入到延時(shí)函數(shù),讀取到GPT計(jì)數(shù)器的當(dāng)前計(jì)數(shù)為100,那么當(dāng)GPT計(jì)數(shù)器中的值變成200的時(shí)候(200-100=100個(gè)數(shù)),我們就知道延時(shí)經(jīng)過了100us。?????
2.3.1 GPT 定時(shí)器結(jié)構(gòu)中各部分意義如下:
①、此部分為 GPT 定時(shí)器的時(shí)鐘源,前面已經(jīng)說過了,本章例程選擇 ipg_clk 作為 GPT 定時(shí)器時(shí)鐘源。
②、此部分為 12 位分頻器,對(duì)時(shí)鐘源進(jìn)行分頻處理,可設(shè)置 0~ 4095,分別對(duì)應(yīng) 1~ 4096 分頻。
③、經(jīng)過分頻的時(shí)鐘源進(jìn)入到 GPT 定時(shí)器內(nèi)部 32 位計(jì)數(shù)器。
④和⑤、這兩部分是 GPT 的兩路輸入捕獲通道,本章不講解 GPT 定時(shí)器的輸入捕獲。
⑥、此部分為輸出比較寄存器,一共有三路輸出比較,因此有三個(gè)輸出比較寄存器,輸出比較寄存器是 32 位的。
⑦、此部分位輸出比較中斷,三路輸出比較中斷,當(dāng)計(jì)數(shù)器里面的值和輸出比較寄存器里面的比較值相等就會(huì)觸發(fā)輸出比較中斷。
???????????
2.3.2 工作模式
1 重新啟動(dòng)(restart)模式:
????????當(dāng) GPTx_CR(x=1,2)寄存器的 FRR 位清零的時(shí)候 GPT 工作在此 模式。在此模式下,當(dāng)計(jì)數(shù)值和比較寄存器中的值相等的話計(jì)數(shù)值就會(huì)清零,然后重新從0X00000000 開始向上計(jì)數(shù),只有比較通道 1 才有此模式!向比較通道 1 的比較寄存器寫入任何 數(shù)據(jù)都會(huì)復(fù)位 GPT 計(jì)數(shù)器。對(duì)于其他兩路比較通道(通道 2 和 3),當(dāng)發(fā)生比較事件以后不會(huì) 復(fù)位計(jì)數(shù)器。
2 自由運(yùn)行(free-run)模式:
????????當(dāng) GPTx_CR(x=1,2)寄存器的 FRR 位置 1 時(shí)候 GPT 工作在此模 式下,此模式適用于所有三個(gè)比較通道,當(dāng)比較事件發(fā)生以后并不會(huì)復(fù)位計(jì)數(shù)器,而是繼續(xù)計(jì) 數(shù),直到計(jì)數(shù)值為 0XFFFFFFFF,然后重新回滾到 0X00000000。 接下來看一下 GPT 定時(shí)器幾個(gè)重要的寄存器,第一個(gè)就是 GPT 的配置寄存器 GPTx_CR, 此寄存器的結(jié)構(gòu)如圖 20.1.1.3 所示:
2.4 重要寄存器
GPTX_CR??? GPTX_PR? ? GPTx_SR??GPTx_CNT
2.4.1?GPT 的配置寄存器 GPTx_CR
位 | 描述 |
---|---|
SWR(bit15) | 復(fù)位 GPT 定時(shí)器,向此位寫 1 就可以復(fù)位 GPT 定時(shí)器,當(dāng) GPT 復(fù)位完成以后此為會(huì)自動(dòng)清零。 |
FRR(bit9) | 運(yùn)行模式選擇,當(dāng)此位為 0 的時(shí)候比較通道 1 工作在重新啟動(dòng)(restart)模式。當(dāng)此位為 1 的時(shí)候所有的三個(gè)比較通道均工作在自由運(yùn)行模式(free-run)。 |
CLKSRC(bit8:6) | GPT 定時(shí)器時(shí)鐘源選擇位,為 0 的時(shí)候關(guān)閉時(shí)鐘源;為 1 的時(shí)候選擇ipg_clk 作為時(shí)鐘源;為 2 的時(shí)候選擇 ipg_clk_highfreq 為時(shí)鐘源;為 3 的時(shí)候選擇外部時(shí)鐘為時(shí)鐘源;為 4 的時(shí)候選擇 ipg_clk_32k 為時(shí)鐘源;為 5 的時(shí)候選擇 ip_clk_24M 為時(shí)鐘源。本章例程選擇 ipg_clk 作為 GPT 定時(shí)器的時(shí)鐘源,因此此位設(shè)置位 1(0b001)。 |
ENMOD(bit1) | GPT 使能模式,此位為 0 的時(shí)候如果關(guān)閉 GPT 定時(shí)器,計(jì)數(shù)器寄存器保存定時(shí)器關(guān)閉時(shí)候的計(jì)數(shù)值。此位為 1 的時(shí)候如果關(guān)閉 GPT 定時(shí)器,計(jì)數(shù)器寄存器就會(huì)清零。EN(bit): GPT 使能位,為 1 的時(shí)候使能 GPT 定時(shí)器,為 0 的時(shí)候關(guān)閉 GPT 定時(shí)器。 |
2.4.2、GPT 定時(shí)器的分頻寄存器 GPTx_PR?
PRESCALER(bit11:0),這就是 12 位分頻值, 可設(shè)置 0~4095,分別對(duì)應(yīng) 1~4096 分頻
2.4.3?狀態(tài)寄存器 GPTx_SR
ROV(bit5):回滾標(biāo)志位,當(dāng)計(jì)數(shù)值從 0XFFFFFFFF 回滾到 0X00000000 的時(shí)候此位置 1。
IF2~IF1(bit4:3):輸入捕獲標(biāo)志位,當(dāng)輸入捕獲事件發(fā)生以后此位置 1,一共有兩路輸入捕 獲通道。如果使用輸入捕獲中斷的話需要在中斷處理函數(shù)中清除此位。
OF3~OF1(bit2:0):輸出比較中斷標(biāo)志位,當(dāng)輸出比較事件發(fā)生以后此位置 1,一共有三路 輸出比較通道。如果使用輸出比較中斷的話需要在中斷處理函數(shù)中清除此位。
2.4.4 計(jì)數(shù)寄存器 GPTx_CNT
文章來源:http://www.zghlxwxcb.cn/news/detail-479161.html
三 使用實(shí)驗(yàn)
通過?GPT 延時(shí)500ms?控制LED0 的亮滅?文章來源地址http://www.zghlxwxcb.cn/news/detail-479161.html
3.1 配置步驟
- 1、設(shè)置 GPT1 定時(shí)器
- 首先設(shè)置 GPT1_CR 寄存器的 SWR(bit15)位來復(fù)位寄存器 GPT1。復(fù)位完成以后設(shè)置寄存 器 GPT1_CR 寄存器的 CLKSRC(bit8:6)位,選擇 GPT1 的時(shí)鐘源為 ipg_clk。設(shè)置定時(shí)器 GPT1的工作模式,?Restart模式,當(dāng)CNT等于OCR1的時(shí)候就產(chǎn)生中斷,為了實(shí)現(xiàn)較大的計(jì)數(shù),我們將比較值設(shè)置為最大的0XFFFFFFFF
- 2、設(shè)置 GPT1 的分頻值
- 設(shè)置寄存器 GPT1_PR 寄存器的 PRESCALAR(bit111:0)位,設(shè)置分頻值。
- 3、設(shè)置 GPT1 的比較值?
- 如果要使用 GPT1 的輸出比較中斷,那么 GPT1 的輸出比較寄存器 GPT1_OCR1 的值可以 根據(jù)所需的中斷時(shí)間來設(shè)置。本章例程不使用比較輸出中斷,所以將 GPT1_OCR1 設(shè)置為最大 值,即:0XFFFFFFFF。
- 4、使能 GPT1 定時(shí)器
- 設(shè)置好 GPT1 定時(shí)器以后就可以使能了,設(shè)置 GPT1_CR 的 EN(bit0)位為 1 來使能 GPT1 定 時(shí)器。
- 5、編寫延時(shí)函數(shù)
- GPT1定時(shí)器已經(jīng)開始運(yùn)行了,可以根據(jù)前面介紹的高精度延時(shí)函數(shù)原理來編寫延時(shí)函數(shù), 針對(duì) us 和 ms 延時(shí)分別編寫兩個(gè)延時(shí)函數(shù)。?
3.2 代碼?
/***************************************************************
Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名 : bsp_delay.c
作者 : 左忠凱
版本 : V1.0
描述 : 延時(shí)文件。
其他 : 無
論壇 : www.wtmembed.com
日志 : 初版V1.0 2019/1/4 左忠凱創(chuàng)建
V2.0 2019/1/15 左忠凱修改
使用定時(shí)器GPT實(shí)現(xiàn)高精度延時(shí),添加了:
delay_init 延時(shí)初始化函數(shù)
gpt1_irqhandler gpt1定時(shí)器中斷處理函數(shù)
delayus us延時(shí)函數(shù)
delayms ms延時(shí)函數(shù)
***************************************************************/
#include "bsp_delay.h"
/*
* @description : 延時(shí)有關(guān)硬件初始化,主要是GPT定時(shí)器
GPT定時(shí)器時(shí)鐘源選擇ipg_clk=66Mhz
* @param : 無
* @return : 無
*/
void delay_init(void)
{
GPT1->CR = 0; /* 清零,bit0也為0,即停止GPT */
GPT1->CR = 1 << 15; /* bit15置1進(jìn)入軟復(fù)位 */
while((GPT1->CR >> 15) & 0x01); /*等待復(fù)位完成 */
/*
* GPT的CR寄存器,GPT通用設(shè)置
* bit22:20 000 輸出比較1的輸出功能關(guān)閉,也就是對(duì)應(yīng)的引腳沒反應(yīng)
* bit9: 0 Restart模式,當(dāng)CNT等于OCR1的時(shí)候就產(chǎn)生中斷
* bit8:6 001 GPT時(shí)鐘源選擇ipg_clk=66Mhz
* bit
*/
GPT1->CR = (1<<6);
/*
* GPT的PR寄存器,GPT的分頻設(shè)置
* bit11:0 設(shè)置分頻值,設(shè)置為0表示1分頻,
* 以此類推,最大可以設(shè)置為0XFFF,也就是最大4096分頻
*/
GPT1->PR = 65; /* 設(shè)置為65,即66分頻,因此GPT1時(shí)鐘為66M/(65+1)=1MHz */
/*
* GPT的OCR1寄存器,GPT的輸出比較1比較計(jì)數(shù)值,
* GPT的時(shí)鐘為1Mz,那么計(jì)數(shù)器每計(jì)一個(gè)值就是就是1us。
* 為了實(shí)現(xiàn)較大的計(jì)數(shù),我們將比較值設(shè)置為最大的0XFFFFFFFF,
* 這樣一次計(jì)滿就是:0XFFFFFFFFus = 4294967296us = 4295s = 71.5min
* 也就是說一次計(jì)滿最多71.5分鐘,存在溢出
*/
GPT1->OCR[0] = 0XFFFFFFFF;
GPT1->CR |= 1<<0; //使能GPT1
/* 一下屏蔽的代碼是GPT定時(shí)器中斷代碼,
* 如果想學(xué)習(xí)GPT定時(shí)器的話可以參考一下代碼。
*/
#if 0
/*
* GPT的PR寄存器,GPT的分頻設(shè)置
* bit11:0 設(shè)置分頻值,設(shè)置為0表示1分頻,
* 以此類推,最大可以設(shè)置為0XFFF,也就是最大4096分頻
*/
GPT1->PR = 65; //設(shè)置為1,即65+1=66分頻,因此GPT1時(shí)鐘為66M/66=1MHz
/*
* GPT的OCR1寄存器,GPT的輸出比較1比較計(jì)數(shù)值,
* 當(dāng)GPT的計(jì)數(shù)值等于OCR1里面值時(shí)候,輸出比較1就會(huì)發(fā)生中斷
* 這里定時(shí)500ms產(chǎn)生中斷,因此就應(yīng)該為1000000/2=500000;
*/
GPT1->OCR[0] = 500000;
/*
* GPT的IR寄存器,使能通道1的比較中斷
* bit0: 0 使能輸出比較中斷
*/
GPT1->IR |= 1 << 0;
/*
* 使能GIC里面相應(yīng)的中斷,并且注冊(cè)中斷處理函數(shù)
*/
GIC_EnableIRQ(GPT1_IRQn); //使能GIC中對(duì)應(yīng)的中斷
system_register_irqhandler(GPT1_IRQn, (system_irq_handler_t)gpt1_irqhandler, NULL); //注冊(cè)中斷服務(wù)函數(shù)
#endif
}
#if 0
/* 中斷處理函數(shù) */
void gpt1_irqhandler(void)
{
static unsigned char state = 0;
state = !state;
/*
* GPT的SR寄存器,狀態(tài)寄存器
* bit2: 1 輸出比較1發(fā)生中斷
*/
if(GPT1->SR & (1<<0))
{
led_switch(LED2, state);
}
GPT1->SR |= 1<<0; /* 清除中斷標(biāo)志位 */
}
#endif
/*
* @description : 微秒(us)級(jí)延時(shí)
* @param - value : 需要延時(shí)的us數(shù),最大延時(shí)0XFFFFFFFFus
* @return : 無
*/
void delayus(unsigned int usdelay)
{
unsigned long oldcnt,newcnt;
unsigned long tcntvalue = 0; /* 走過的總時(shí)間 */
oldcnt = GPT1->CNT;
while(1)
{
newcnt = GPT1->CNT;
if(newcnt != oldcnt)
{
if(newcnt > oldcnt) /* GPT是向上計(jì)數(shù)器,并且沒有溢出 */
tcntvalue += newcnt - oldcnt;
else /* 發(fā)生溢出 */
tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;
oldcnt = newcnt;
if(tcntvalue >= usdelay)/* 延時(shí)時(shí)間到了 */
break; /* 跳出 */
}
}
}
/*
* @description : 毫秒(ms)級(jí)延時(shí)
* @param - msdelay : 需要延時(shí)的ms數(shù)
* @return : 無
*/
void delayms(unsigned int msdelay)
{
int i = 0;
for(i=0; i<msdelay; i++)
{
delayus(1000);
}
}
/*
* @description : 短時(shí)間延時(shí)函數(shù)
* @param - n : 要延時(shí)循環(huán)次數(shù)(空操作循環(huán)次數(shù),模式延時(shí))
* @return : 無
*/
void delay_short(volatile unsigned int n)
{
while(n--){}
}
/*
* @description : 延時(shí)函數(shù),在396Mhz的主頻下
* 延時(shí)時(shí)間大約為1ms
* @param - n : 要延時(shí)的ms數(shù)
* @return : 無
*/
void delay(volatile unsigned int n)
{
while(n--)
{
delay_short(0x7ff);
}
}
到了這里,關(guān)于I.MX6ull GPT高精度定時(shí)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!