s3c2410提供了5個16位的timer(timer0~timer4),其中timer0~timer3支援pulse width modulation—— pwm(脈寬調變)。timer4是乙個內部定時器(internal 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 / /
= 0~255
= 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()
由於我們的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()
S3C2440 SDRAM暫存器初始化設定
開板子是s3c2440,使用兩片容量為32mb 位寬16bit的em63a165ts 6g晶元拼成容量為64m 32bit的sdram儲存器。根據2410datasheet,要使用sdram需配置13個暫存器,以下逐個來看 1 bwscon bus width wait status control...
迴圈方法初始化2440記憶體
採用迴圈方法記憶體初始化中 memsetup 設定儲存控制器以便使用sdram等外設 mov r1,mem ctl base 儲存控制器的13個暫存器的開始位址 adrl r2,mem cfg val 這13個值的起始儲存位址 add r3,r1,52 13 4 54 1 ldr r4,r2 4 讀...
S3C6410時鐘初始化
s3c6410有三個pll,分別為apll mpll和epll。其中apll產生aclk,給arm core使用,mpll產生hclkx2 hclk和pclk,epll產生特殊的時鐘,比如為usb提供48mhz時鐘 可以看到,外部時鐘 一般為12m 經過apll後再經過設定分頻係數divarm後產生...