久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: s3c2410 Timer工作原理 [打印本頁]

作者: 葛靖青    時間: 2010-11-3 10:49
標題: s3c2410 Timer工作原理

【轉自互聯網,如需引用請聯系原作者】

s3c2410提供了5個16位的Timer(Timer0~Timer4),其中Timer0~Timer3支持Pulse Width Modulation—— PWM(脈寬調制 )。Timer4是一個內部定時器(internal timer),他沒有輸出引腳(output pins)。
    下面是Timer的工作原理圖。
 
    如上圖所示,PCLK是Timer的信號源,我們通過設置每個Timer相應的Prescaler和Clock Divider把PCLK轉換成輸入時鐘信號傳送給各個Timer的邏輯控制單元(Control Logic),事實上每個Timer都有一個稱為輸入時鐘頻率(Timer input clock Frequency)的參數,這個頻率就是通過PCLK,Prescaler和Clock Divider確定下來的,每個Timer 的邏輯控制單元就是以這個頻率在工作。下面給出輸入時鐘頻率的公式:

Timer input clock Frequency = PCLK / {prescaler value+1} / {clock divider }
{prescaler value} = 0~255
{ clock divider } = 2, 4, 8, 16

    然而并不是每一個Timer都有對應的Prescaler和Clock Divider,從上面的原理圖我們可以看到Timer0,Timer1共用一對Prescaler和Clock Divider,Timer2,Timer3,Timer4共用另一對Prescaler和Clock Divider,s3c2410的整個時鐘系統模塊只存在兩對Prescaler和Clock Divider。
    我曾經在討論watchdog的文章中提到,watchdog也是一種定時器,他的工作就是在一個單位時間內對一個給定的數值進行遞減和比較的操作,而我們這篇文章討論的定時器他的工作內容和watchdog在本質上是一樣的。定時器在一個工作周期(Timer input clock cycle)內的具體工作內容主要有3個。分別是:

  1. 對一個數值進行遞減操作
  2. 把遞減后的數值和另一個數值進行比較操作
  3. 產生中斷或執行DMA操作

     在啟用Timer之前我們會對Timer進行一系列初始化操作,這些操作包括上面提到的設置Prescaler和Clock Divider,其中還有一個非常重要的就是要給Timer兩個數值,我們分別稱之為Counter(變量,用于遞減)和Comparer(定值,用于比較),Counter會被Timer 加載到COUNT BUFFER REGISTER(TCNTB),而Comparer會被Timer 加載到和COMPARE BUFFER REGISTER(TCMPB),每個Timer都有這樣兩個寄存器。當我們設置完畢啟動Timer之后,Timer在一個工作周期內所做的就是先把TCNTB中的數值(Counter)減1,之后把TCNTB中的數值和TCMPB中的數值(Comparer)進行對比,若Counter已經被遞減到等于Comparer,發生計數超出,則Timer產生中斷信號(或是執行DMA操作)并自動把Counter重新裝入TCNTB(刷新TCNTB以重新進行遞減)。以上就是Timer的工作原理。

下面我們結合代碼具體說明如何對Timer0進行初始化并開啟它。
首先我假設我的PCLK是50700000Hz

// define Timer register
#define rTCFG0 (*(volatile unsigned int *)0x51000000)
#define rTCFG1 (*(volatile unsigned int *)0x51000004)
#define rTCON (*(volatile unsigned int *)0x51000008)
#define rTCNTB0 (*(volatile unsigned int *)0x5100000C)
#define rTCMPB0 (*(volatile unsigned int *)0x51000010)
#define rTCNTO0 (*(volatile unsigned int *)0x51000014)
#define rTCNTB1 (*(volatile unsigned int *)0x51000018)
#define rTCMPB1 (*(volatile unsigned int *)0x5100001C)
#define rTCNTO1 (*(volatile unsigned int *)0x51000020)
#define rTCNTB2 (*(volatile unsigned int *)0x51000024)
#define rTCMPB2 (*(volatile unsigned int *)0x51000028)
#define rTCNTO2 (*(volatile unsigned int *)0x5100002C)
#define rTCNTB3 (*(volatile unsigned int *)0x51000030)
#define rTCMPB3 (*(volatile unsigned int *)0x51000034)
#define rTCNTO3 (*(volatile unsigned int *)0x51000038)
#define rTCNTB4 (*(volatile unsigned int *)0x5100003C)
#define rTCNTO4 (*(volatile unsigned int *)0x51000040)

void timer0_config()
{
/*
                Timer0的prescaler由rTCFG0 的 0~7 bit決定
                Prescaler=119

*/
                rTCFG0=119       
/*
                Timer0的divider value由TCFG1的 0~3 bit決定,設置為3表示divider value = 1/16
                rTCFG1的第20~23bit用于決定Timer計數超出后所采取的響應,我們使用了中斷模式(20~23bit全部為0),
                即計數超出后產生中斷

*/
                rTCFG1=3;
       
                rTCNTB0=26406;
                rTCMPB0=0;
}
由于我們的PCLK是50700000Hz, 根據Timer input clock Frequency的計算公式我們如下計算Timer0的時鐘輸入頻率:

prescaler value = 119
divider value = 1/16
PCLK= 50700000
Timer input clock Frequency =50700000/ (119+1)/(1/16)=26406

   
也就是說通過設置prescaler和divider value之后,Timer0的工作頻率為26406,也就是說一秒內Timer0會進行26406次遞減和比較操作,假設我們現在是要讓Timer0每1秒產生一次中斷的話,我們應該設置Counter=26406和Camparer=0,既:

rTCNTB0=26406;
rTCMPB0=0;

如果我們要讓Timer0每0.5秒產生一次中斷,則我們應該設置Counter=26406/2和Camparer=0,既:

rTCNTB0=13203;
rTCMPB0=0;

如果我們要讓Timer0每0.25秒產生一次中斷,則我們應該設置Counter=26406/4和Camparer=0,既:

rTCNTB0=6601;
rTCMPB0=0;

初始化完Timer后我們要開啟它。

void timer0_start()
{
/*
               Update TCNTB0 & TCMPB0
               rTCON寄存器的第1位是刷新Timer0的COUNT BUFFER REGISTER(TCNTB)和
                COMPARE BUFFER REGISTER(TCMPB),由于是第一次加載Counter和Comparer,
                所以我們需要手動刷新它們

*/
               rTCON|=1<<1;
/*
               置rTCON第0位為1,開啟Timer0
               把rTCON第1位置為0,停止刷新TCNTB0 和 TCMPB0
               置rTCON第3位為1,設置Counter的加載模式為自動加載(auto reload),這樣每當
               Timer計數超出之后(此時TCNTB的值等于TCMPB的值),Timer會自動把原來我們給
               定的Counter重新加載到TCNTB中

*/
        rTCON=0x09;       
}

    要使你的Timer能夠正常的工作,除了調用timer0_config()和timer0_start()之外,我們還必須設置Timer的中斷服務例程并取消對Timer的中斷的屏蔽.






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 精品国产乱码久久久久久果冻传媒 | 日韩在线观看中文字幕 | 日日摸日日添日日躁av | 黄色网址大全在线观看 | 精品久久久久一区二区国产 | 日韩精品1区2区3区 成人黄页在线观看 | 久产久精国产品 | 欧美性另类| 自拍 亚洲 欧美 老师 丝袜 | 99久久精品免费视频 | 亚洲人成人网 | 日韩久久精品 | 成人亚洲| 毛片一区二区三区 | 91色网站| 蜜桃臀av一区二区三区 | 亚洲情综合五月天 | 国产精品久久久久久影院8一贰佰 | 亚洲三级国产 | 在线日韩欧美 | 久久久久国产一区二区三区不卡 | 国产精品视频在线播放 | 国产精品揄拍一区二区 | 男女羞羞的网站 | 久久久久久亚洲精品 | 国产欧美视频一区 | 亚洲精品中文字幕在线观看 | 玖玖在线免费视频 | 日本字幕在线观看 | 国产成人免费视频网站高清观看视频 | 国产精品久久a | 成人二区 | 高清av在线| 日韩插插| 亚洲一区二区三区四区五区中文 | 国产成人精品一区二 | 亚洲欧美一区二区三区在线 | 国产乱码高清区二区三区在线 | 99久久婷婷国产亚洲终合精品 | 亚洲国产一区二区在线 | 日韩精品免费 |