新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > s3c2440定時器中斷的應用

        s3c2440定時器中斷的應用

        作者: 時間:2016-11-19 來源:網絡 收藏
        在前面的幾篇文章中,每當程序需要延時時,我們是利用循環語句來實現。這種方法的延時簡單,但不是很精確,就是說不能得到確切的一段時間的延時。因此當需要精確延時時,就不能采用這種方法了。一般是利用定時器來實現。在這里,我們就介紹一下s3c2440定時器的使用方法。

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

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

        下面我們通過一段程序來演示利用定時器得到精確延時。這里我們用到的是定時器4。這段程序的作用是讓蜂鳴器每隔2秒鐘響一次,持續時間為0.5秒,蜂鳴器響的同時伴隨著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秒蜂鳴器響一次,持續時間為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);//打開定時器4中斷

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

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


        pISR_TIMER4 = (U32)Timer4_ISR;

        while(1)
        {
        ;
        }
        }



        關鍵詞: s3c2440定時器中

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 旬邑县| 怀宁县| 南投县| 甘孜| 稻城县| 密山市| 宁强县| 交城县| 万安县| 汉中市| 涞水县| 广宗县| 汝阳县| 钦州市| 蕲春县| 耒阳市| 武穴市| 长沙市| 保康县| 舞阳县| 民县| 南康市| 商丘市| 沈阳市| 依安县| 民丰县| 普兰县| 大英县| 大安市| 都兰县| 阜阳市| 托里县| 宁都县| 白山市| 天全县| 英吉沙县| 通化市| 涪陵区| 民丰县| 额敏县| 安溪县|