新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > s3c2440定時(shí)器中斷的應(yīng)用

s3c2440定時(shí)器中斷的應(yīng)用

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
在前面的幾篇文章中,每當(dāng)程序需要延時(shí)時(shí),我們是利用循環(huán)語(yǔ)句來(lái)實(shí)現(xiàn)。這種方法的延時(shí)簡(jiǎn)單,但不是很精確,就是說(shuō)不能得到確切的一段時(shí)間的延時(shí)。因此當(dāng)需要精確延時(shí)時(shí),就不能采用這種方法了。一般是利用定時(shí)器來(lái)實(shí)現(xiàn)。在這里,我們就介紹一下s3c2440定時(shí)器的使用方法。

在講解之前,先介紹一下s3c2440時(shí)鐘系統(tǒng)。一般來(lái)說(shuō),MCU的主時(shí)鐘源主要是外部晶振或外部時(shí)鐘,而用的最多的是外部晶振。在正確情況下,系統(tǒng)內(nèi)所使用的時(shí)鐘都是外部時(shí)鐘源經(jīng)過(guò)一定的處理得到的。由于外部時(shí)鐘源的頻率一般不能滿足系統(tǒng)所需要的高頻條件,所以往往需要PLL(鎖相環(huán))進(jìn)行倍頻處理。在s3c2440中,有2個(gè)不同的PLL,一個(gè)是MPLL,另一個(gè)是UPLL。UPLL是給USB提供48MHz。在這里,我們主要介紹MPLL。外部時(shí)鐘源經(jīng)過(guò)MPLL處理后能夠得到三個(gè)不同的系統(tǒng)時(shí)鐘:FCLK、HCLK和PCLK。FCLK是主頻時(shí)鐘,用于ARM920T內(nèi)核;HCLK用于AHB總線設(shè)備,如ARM920T,內(nèi)存控制,中斷控制,LCD控制,DMA以及USB主模塊;PCLK用于APB總線設(shè)備,如外圍設(shè)備的看門狗,IIS,I2C,PWM,MMC接口,ADC,UART,GPIO,RTC以及SPI。這三個(gè)系統(tǒng)時(shí)鐘(FCLK、HCLK和PCLK)是有一定的比例關(guān)系,這種關(guān)系是通過(guò)寄存器CLKDIVN中的HDIVN位和PDIVN位來(lái)控制的,因此我們只要知道了FCLK,再通過(guò)這兩位的控制,就能確定HCLK和PCLK。而FCLK是如何得到的呢?它是通過(guò)輸入時(shí)鐘(即外部時(shí)鐘源)的頻率,經(jīng)過(guò)一個(gè)計(jì)算公式(具體公式請(qǐng)查閱數(shù)據(jù)手冊(cè))得到的,這個(gè)計(jì)算公式還需要三個(gè)參數(shù)(MDIV、PDIV、SDIV),而這三個(gè)參數(shù)是經(jīng)過(guò)寄存器MPLLCON配置得到的。最后,我們用最清晰的線路來(lái)繪制一下時(shí)鐘的產(chǎn)生過(guò)程:外部時(shí)鐘源→通過(guò)寄存器MPLLCON得到FCLK→再通過(guò)寄存器CLKDIVN得到HCLK和PCLK。這個(gè)配置過(guò)程在啟動(dòng)文件中就已完成。在本開發(fā)板上,外部晶振為12MHz,進(jìn)過(guò)MPLL倍頻以后得到400MHz的FCLK,而FCLK、HCLK、PCLK之間的比例關(guān)系為1:4:8,因此HCLK為100MHz,PCLK為50MHz。

s3c2440的時(shí)鐘系統(tǒng)就介紹到這里,我們?cè)倩氐蕉〞r(shí)器的配置上來(lái)。如何才能得到精確的定時(shí)呢?那就要靠TCFG0和TCFG1這兩個(gè)寄存器來(lái)配置定時(shí)器的頻率,即要確定TCNTOn每遞減一個(gè)數(shù)所需要的時(shí)間,它們之間是倒數(shù)的關(guān)系。具體的計(jì)算公式為:
定時(shí)器輸出時(shí)鐘頻率=PCLK÷(prescaler+1)÷divider
其中prescaler值由TCFG0決定,divider值由TCFG1決定,而prescaler只能取0~255之間的整數(shù),divider只能取2、4、8和16。比如已知PCLK為50MHz,而我們想得到某一定時(shí)器的輸出時(shí)鐘頻率為25kHz,則依據(jù)公式可以使prescaler等于249,divider等于8。有了這個(gè)輸出時(shí)鐘頻率,理論上我們通過(guò)設(shè)置寄存器TCNTBn就可以得到任意與0.04毫秒(1÷25000×1000)成整數(shù)倍關(guān)系的時(shí)間間隔了。例如我們想要得到1秒鐘的延時(shí),則使TCNTBn為25000(1000÷0.04)即可。

下面我們通過(guò)一段程序來(lái)演示利用定時(shí)器得到精確延時(shí)。這里我們用到的是定時(shí)器4。這段程序的作用是讓蜂鳴器每隔2秒鐘響一次,持續(xù)時(shí)間為0.5秒,蜂鳴器響的同時(shí)伴隨著LED亮。

#define _ISR_STARTADDRESS 0x33ffff00

#define U32 unsigned int

#define pISR_TIMER4(*(unsigned *)(_ISR_STARTADDRESS+0x58))


#define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt request status
#define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
#define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status

#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

#define rTCFG0(*(volatile unsigned *)0x51000000)//Timer 0 configuration
#define rTCFG1(*(volatile unsigned *)0x51000004)//Timer 1 configuration
#define rTCON(*(volatile unsigned *)0x51000008)//Timer control
#define rTCNTB4 (*(volatile unsigned *)0x5100003c)//Timer count buffer 4

void __irq Timer4_ISR(void)
{
static int count;
count ++;
rSRCPND = rSRCPND | (0x1<<14);
rINTPND = rINTPND | (0x1<<14);
//每隔2秒蜂鳴器響一次,持續(xù)時(shí)間為0.5秒,并伴隨著LED亮
if (count % 4 ==0)
rGPBDAT = ~0x1e0;//蜂鳴器響,LED亮
else if (count % 4 ==1)
rGPBDAT = 0x1e0;//蜂鳴器不響,LED滅
}


void Main(void)
{
rGPBCON = 0x155555;//B0輸出,給蜂鳴器;B5~B8輸出,給LED
rGPBUP= 0x7ff;

rGPBDAT = 0x1e0;//蜂鳴器不響,LED滅

rSRCPND = rSRCPND | (0x1<<14);
rINTPND = rINTPND | (0x1<<14);
rINTMSK = ~(0x1<<14);//打開定時(shí)器4中斷

rTCFG0 &= 0xFF00FF;
rTCFG0 |= 0xf900;// prescaler等于249
rTCFG1 &= ~0xF0000;
rTCFG1 |= 0x20000;//divider等于8,則設(shè)置定時(shí)器4的時(shí)鐘頻率為25kHz
rTCNTB4 = 12500;//讓定時(shí)器4每隔0.5秒中斷一次

rTCON &= ~0xF00000;
rTCON |= 0x700000;
rTCON &= ~0x200000 ;//定時(shí)器4開始工作


pISR_TIMER4 = (U32)Timer4_ISR;

while(1)
{
;
}
}



關(guān)鍵詞: s3c2440定時(shí)器中

評(píng)論


技術(shù)專區(qū)

關(guān)閉