S3C2410的TIMER、PWM及WIN CE的驅動

來源:互聯網
上載者:User

鬱悶,剛才寫了N百字的東西,就在我系統崩潰的一瞬間,沒有。。。。傷心欲死。。。。,但從哪兒完蛋的就從哪不讓它完蛋的信念告訴我,一定接著寫。。。

在學校的時候裸跑了2410的PWM來控制直流電動機,之後來到公司先後寫了蜂鳴器(有點兒簡單,都不好意思提)、CC1100定時器部分的WIN CE驅動,算是對2410的TIMER有所瞭解了,現記錄如下:

在寫之前請各位先看一下我轉蔡於清老師的一篇文章,因為我也是在看了這篇文章之後才著手弄s3c2410 Timer的,但一定要抱著試試看的態度閱讀喲,不然小心中招。嘻嘻^_^先賣個關子。
 

s3c2410 Timer作者:蔡於清
www.another-prj.com

s3c2410提供了5個16位的Timer(Timer0~Timer4),其中Timer0~Timer3支援Pulse Width Modulation—— PWM(脈寬調製 )。Timer4是一個內部定時器(internal timer),他沒有輸出引腳(output pins)。
下面是Timer的工作原理圖。

clip_image002.gif (34.3 KB)2007-3-23 21:32

[attach]60[/attach]
如所示,PCLK是Timer的訊號源,我們通過設定每個Timer相應的PrescalerClock 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的中斷的屏蔽.這些操作可以參考<<s3c2410 中斷異常處理>>一文.
另外OS實驗區提供的原始碼中有更為詳細的代碼,需要的朋友可以參考,關於Timer的代碼存在於timer.c timer.h檔案中看完了這篇文章有何感想?是不是對這個小東西差不多懂了,但是不要著急,這裡面是有問題地,呵呵(給別人挑毛病好像是我最大的愛好)。
        請君細看這段“若Counter已經被遞減到等於Comparer,發生計數超出,則Timer產生中斷訊號(或是執行DMA操作)並自動把Counter重新裝入TCNTB(重新整理TCNTB以重新進行遞減)。”看過晶片文檔的哥們應該看出來了,問題就在這裡不是減到相等時發生的中斷,而是減到零的時候才發生中斷的。當然了PWM的極性翻轉是在這時發生的。
        看這篇文章的各位看官應該都是想用TIEMR或PWM的人,這裡有必要說一下2410TIMER的運行流程,當然了那些什麼死區控制,輸出極性反轉器什麼的就不提了,首先分兩部分,PWM和TIMER(我是這樣分的,請君勿見怪)呵呵。前者要先要往CFG0、1裡寫入你想要的分頻值和除數,然後再向Counter裡寫入你想要的減法(它會把值複製到一個內部的寄存器中,這個寄存器對於使用者來說是不可見的,然後它再把值給減法器,進行相減),之後設定自動更新位和開始位,這樣那些你想要的脈衝就會源源不繼的湧來了,用示波器觀看後,很是有成就感啊(雖然技術含量不是太高,不過知足者長樂嘛,哈哈)。對於後者來說,一般都是需要作為定時器來使用,只執行一次這樣的話和前面差不多,就是在置開始位的時候不要把自動更新加上,那樣就行了。
     另外要注意的是:     If the timer is stopped by force, the TCNTn retains the counter value and is not reloaded from TCNTBn. If a newvalue has to be set, perform manual update.
      其實轉載的文章已經說明的夠清楚了,此處沒必要浪費各位看官的時間。下面說一下關於WIN CE的問題
      在WIN CE 下我想添加自訂的使用者中斷,於是要實現的就是ISR代碼(在ARMINIT。C中),中斷的使能,禁能和DONE代碼(在CFW。C中),我以為清中繼的代碼可以在ISR中也可以在中斷的DONE中,但是實踐證明如果注釋掉ISR中的清中斷代碼的話中斷會一直執行,不知這是何故,按理來說就是出問題也不應該是這樣的問題啊,可能是哪兒裡又沒有注意到,我經常犯各種各樣希奇古怪的錯誤,有時候想一想自己都樂,比如把“&”寫成了“|”、在一句之後沒有加分號等等等,數之不盛數啊,真叫人發愁,成不了大氣,哎!!!剛才寫的要比這篇清楚,哎,沒有時間了,晚上八點了,該回家了。還得一個人撓牆根玩兒,無奈。。。…_…

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.