- 嵌入式系統設計與實踐:Linux篇
- 季江民
- 2807字
- 2020-04-03 09:21:47
4.3 系統定時器
S3C2410有5個16 bit定時器。定時器0—3有脈寬調制功能(Pulse Width Modulation, PWM),定時器4是內部定時器,沒有輸出引腳。定時器0有Dead-zone發生器,可以保證一對反向信號不會同時改變狀態,常用于大電流設備中。
定時器0—1共用一個8位的時鐘分頻器(8 bit prescaler),定時器2—4共用另外一個。每個定時器有一個時鐘分頻器,可以選擇5種分頻方法。每個定時器從各自的時鐘分頻器獲取時鐘信號。prescaler是可編程的,并依據TCFG0-1寄存器數值對PCLK進行分頻。
當定時器被使能之后,定時器計數緩沖寄存器(TCNTBn)中初始的數值就被加載到遞減計數器中。定時器比較緩沖寄存器(TCMPBn)中的初始數值被加載到比較寄存器中,以備與遞減計數器數值進行比較,這種雙緩沖特點可以讓定時器在頻率和占空比變化時輸出的信號更加穩定。
每個定時器都有一個各自時鐘驅動的16 bit遞減計數器,當計數器數值為0時,產生一個定時中斷,同時TCNTBn中的數值被再次載入遞減計數器中再次開始計數。只有關閉定時器才不會重載。TCMPBn中的數值用于PWM,當遞減計數器的數值和比較寄存器數值一樣時,定時器改變輸出電平,因此,比較寄存器決定了PWM輸出的開啟和關閉。
1.定時器的工作過程
S3C2410的PWM定時器采用雙buffer機制,可以在不停止當前定時器的情況下設置下一輪定時操作。定時器值可以寫到定時器計數緩沖寄存器TCNTBn,而當前定時的計數值可以從定時器觀察寄存器TCNTOn獲得,即,從TCNTBn獲得的不是當前數值而是下一次計數的初始值。
自動加載功能被打開后,當TCNTn數值遞減到0時,芯片自動將TCNTBn的數值拷貝到TCNTn,從而開始下一次循環,若TCNTBn數值為0,則不會有遞減操作,定時器停止。
第一次啟動定時器的過程如下:
(1)初始化TCNTBn和比較緩沖寄存器TCMPBn的數值;
(2)設置定時器的人工加載位,不管是否使用極性轉換功能,都將極性轉換位打開;(3)設置定時器的啟動位來啟動定時器,定時器啟動后,TCNTn開始計數作減計數,同時清除人工加載位。
(4)當TCNTn的數值和TCMPn一致時,TOUTn從低變為高,直至TCNTn計數至0,定時器產生中斷請求。
若定時器在計數過程中被停止,則TCNTn保持計數值,若需要設置新的數值需要人工加載。定時器的工作過程可以用圖4.5表示。

圖4.5 定時器的工作過程
定時器的工作過程解釋如下:
(1)使能自動加載功能,設置TCNTBn=160, TCMPBn=110,設置人工加載位并配置極性轉換位,人工加載位將TCNTBn、TCMPBn的數值加載到TCNTn(160)、TCMPn(110)。然后,設置TCNTBn、TCMPBn為80和40,作為下一次定時的參數。
(2)設置啟動位,若人工加載位為0,極性轉換關閉,自動加載開啟,則定時器開始遞減計數。
(3)當TCNTn的數值和TCMPn一致時,TOUTn從低變為高。
(4)當TCNTn計數至0,定時器產生中斷請求,同時TCNTBn、TCMPBn的數值被自動加載到TCNTn、TCMPn,前者為80,后者為40。
(5)中斷服務向量(ISR)將TCNTBn、TCMPBn設置為80和60。
(6)與(3)相似。
(7)與4相似,TCNTn、TCMPn,前者為80,后者為60。
(8)ISR服務程序中,將自動加載和中斷請求關閉。
(9)與(6)、(3)相似。
(10)TCNTn為0, TCNTn不會自動加載新的數值,定時器被關閉。
(11)沒有新的中斷發生。
同時,由上面的工作過程可以看出,通過ISR或別的方法寫入不同的TCMPBn的數值,就可以調節輸出信號的占空比,實現脈寬調制PWM。
2.定時器各寄存器配置
定時器輸入時鐘頻率計算公式如下:
定時器輸入時鐘頻率=MCLK/{預分頻值+1}/{分割值}
{預分頻值}=1~255
{分割值}=2,4,8,16,32
其中,MCLK為系統時鐘,預分頻值和分割值分別通過定時器配置寄存器TCFG0和TCFG1設置。
(1)定時器配置寄存器
在S3C2410中定時器配置寄存器有TCFG0和TCFG1,表4.10、表4.11分別表示定時器配置寄存器0(TCFG0)、1(TCFG1)各個位的含義及初始值的情況。
表4.10 定時器配置寄存器TCFG0的設置

表4.11 定時器配置寄存器TCFG1的設置

MUXn(n=0~5為分割值)可以取1/2、1/4、1/8、1/16
(2)定時器控制寄存器TCON
定時器控制寄存器TCON如表4.12所示。
表4.12 定時器控制器寄存器TCON

注意:TIMER0對應bit[3:0]:bit[3]用于確定在TCNT0計數到0時,是否自動將TCMPB0和TCNTB0寄存器的值裝入TCMP0和TCNT0寄存器中,bit[2]用于確定TOUT0是否反轉輸出,bit[1]用于手動更新TCMP0和TCNT0寄存器:在第一次使用定時器前,此位需要設為1,此時TCMPB0和TCNTB0寄存器的值裝入TCMP0和TCNT0寄存器中,bit[0]用于啟動TIMER0。
(3)定時器計數緩沖寄存器與比較緩沖寄存器(TCNTBn/TCMPBn)
定時器計數緩沖寄存器包括TCNTB0—TCNTB5;而定時器比較緩沖寄存器包括TCMPB0—TCMPB4。定時器計數緩沖寄存器TCNTBn如表4.13所示,定時器比較緩沖寄存器TCMPBn如表4.14所示。
表4.13 定時器計數緩沖寄存器TCNTBn

表4.14 定時器比較緩沖寄存器TCMPBn

(4)定時器觀察寄存器
定時器觀察寄存器包括TCNTO0~TCNTO5,定時器觀察緩沖寄存器TCNTOn如表4.15所示。
表4.15 定時器觀察緩沖寄存器TCMPBn

例:在S3C2410中定時器配置寄存器TCFG0和TCFG1的值分別設為119和0x03,這個寄存器用于設置控制邏輯(Control Logic)的時鐘,設外部時鐘源的頻率MCLK為12MHz,求時鐘輸出頻率為多少。
分析:時鐘輸出頻率計算公式如下:
Timer input clock Frequency = MCLK / {prescaler value+1} / {divider value}
對于TIMER0,預分頻值prescaler value = TCFG0[7:0]為119(0b1110111),分割值divider value由TCFG1[3:0]確定,本例中取值為0b011(0x03),因為取值0b000時,分割值為1/2;取值0b001時,分割值為1/4;取值0b010時,分割值為1/8;取值0b011時,分割值為1/16,所以:
時鐘輸出頻率= 12MHz/(119+1)/(16) = 6250Hz
例:內核時鐘FLCK(主頻)、總線時鐘HCLK、I/O接口時鐘PCLK之間的關系通常設置為1:4:8的分頻關系,如果說主頻FLCK為400MHz,那么HLCK是100 MHz, PLCK是50 MHz。閱讀下列程序回答以下問題。
#definde rLOCKTIME (*(volatile unsigned *)0x4c000000) #definde rMPLLCON (*(volatile unsigned *)0x4c000004) #definde rUPLLCON (*(volatile unsigned *)0x4c000008) #definde rCLKCON (*(volatile unsigned *)0x4c00000c) #definde rCLKSLOW (*(volatile unsigned *)0x4c000010) #definde rCLKDIVN (*(volatile unsigned *)0x4c000014) void ChangeMPllValue(int mdiv, int pdiv, int sdiv) { rMPLLCON=(mdiv<<12)|(pdiv<<4)|sdiv; } void ChangeClockDivider(int hdivn, int pdivn) { rCLKDIVN=(hdivn<<1)|pdivn; if(hdivn) MMU_SetAsyncBusMode(); else MMU_SetFastBusMode(); } void ChangeUPllValue(int mdiv, int pdiv, int sdiv) { rUPLLCON=(mdiv<<12)|(pdiv<<4)|sdiv; }
如果在主程序中有如下引用:
ChangeClockDivider(1,1); ChangeUPllValue(0xa1,0x3,0x1);
問:
(1)FCLK:HCLK:PCLK的比值是多少?
(2)FCLK為多少MHz?
3. S3C2410實時時鐘RTC
在一個嵌入式系統中,實時時鐘單元可以提供可靠的時鐘,包括時分秒和年月日;即使在系統處于關機狀態下,它也能正常工作(通常采用后備電池供電),它的外圍也不需要太多的輔助電路,典型情況就是只需要一個高精度的晶振。S3C2410的實時時鐘RTC具有下列特點:
● 時鐘數據采用BCD編碼;
● 能夠對閏年的年月日進行自動處理;
● 具有告警功能,當系統處于關機狀態時,能產生告警中斷;
● 無2000 年問題;
● 具有獨立的電源輸入;
● 提供毫秒級時鐘中斷,該中斷可用作嵌入式操作系統的內核時鐘。
RTC器件是一種能夠提供日歷/時鐘、數據存儲等功能的專用集成電路。RTC發送8位BCD碼數據到CPU,傳送的數據包括秒、分、小時、星期、日期、月份與年份。
(1)S3C2410的實時時鐘控制寄存器RTCCON
表4.16是S3C2410的實時時鐘控制寄存器RTCCON各位的設置值與相應的功能。
表4.16 RTC時鐘控制寄存器RTCCON

(2)RTC報警寄存器RTCALM
表4.17是RTC報警寄存器RTCALM中的各個位,取值可以是0或1, 0表示禁止報警,1表示報警使能。
表4.17 RTC報警寄存器RTCALM

0:禁止報警
1:報警使能
(3)RTC報警時間設置寄存器
RTC模塊的寄存器組BCDSEC、BCDMIN、BCDDAY、BCDDATE、BCDMON、BCDYEAR分別用于存放秒、分、小時、日、月、年,如表4.18所示。
表4.18 時間設置寄存器

例:下列程序是S3C2410處理器的實時時鐘(RTC)模塊,根據語句RTCCON =0x01;請分析RTC的功能、初始年份為、在函數display外RTCCON的值為多少?
void display() { int y, m, d, s, mi; RTCCON =0x01; //報警使能 while(1) { if(BCDYEAR==0x99) y=0x1999; else y=0x2000+BCDYEAR; m=BCDMON; d=BCDDAY; mi= BCDMIN; s=BCDSEC; if(s! =0) break; printf("time:%4x / %02x /%02x\n", y, m, d); RTCCON =0x0; } } void main() { RTCCON =0x01; BCDYEAR =0x08; BCDMON =0x08; BCDDAY = 0x08; BCDMIN =0x08; BCDSEC =0x59; RTCCON =0x00; while(1) { display(); delay(200); } }
分析:語句RTCCON =0x01;表示RTC使能、無復位、分頻1/32768,初始年份為2008,在函數display外RTCCON的值為0x00。