新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 系統(tǒng)時鐘和定時器——PWM定時器

系統(tǒng)時鐘和定時器——PWM定時器

作者: 時間:2016-11-11 來源:網(wǎng)絡 收藏
時鐘控制邏輯給整個芯片提供3種時鐘:FCLK用于CPU核;HCLK用于AHB總線設備,比如CPU核、存儲器控制器、中斷控制器、DMA和USB主機模塊等;PCLK用于APB總線上的設備,比如WATCHDOG、IIS、IIC、PWM、MMC、ADC、RTC等等。

S3C2440 CPU核的工作電壓為1.2V時,主頻可以達到300MHz;工作電壓為1.3V時,主頻可以達到400MHz。開發(fā)板為12MHz,需要通過時鐘控制邏輯的PLL提高系統(tǒng)時鐘

本文引用地址:http://butianyuan.cn/article/201611/316624.htm

S3C2440有兩個PLL:MPLL和UPLL。UPLL專用于USB設備,MPLL用于設置FCLK、HCLK、PCLK。

圖1 上電后MPLL的啟動過程
LocK Time的長短由寄存器LOCKTIME設定。一般采用默認值。
查看芯片手冊,MPLL計算公式如下圖:

其中 m=MDIV+8, p=PDIV+2, s=SDIV

CLKDIVN寄存器:用于設置FCLK、HCLK、PCLK 三者比例。各種時鐘比例對應的寄存器設置如下圖所示:

1、 PWM(Pulse Width Modulation)定時器
S3C2440 有5個16位定時器。其中定時器0、1、2、3有PWM功能,即他們都有一個引腳,可以用過定時器來控制引腳周期性的高低電平變化;定時器4沒有輸出引腳。定時器時鐘源為PCLK。內部結構如圖所示:
定時器0 、1 共用第一個預分頻器,定時器2 、3、 4 共用第2個預分頻器。預分頻器的輸出進入第二級分頻器,它有5種頻率的時鐘:2、4、8、16分頻。預分頻通過TCFG0設置,分頻值(2、4、8、16)通過TCFG1設置。
現(xiàn)在我們可以歸結啟動一個PWM功能可以分為以下幾步:
1、設置TOUT0-TOUT3,這需要配置相關外部引腳為TOUT模式。外部引腳GPB與TOUT為復用引腳
2、設置定時器的輸出頻率,并且通過TCFG0設置prescaler(預分頻)的值。通過TCFG1設置divider的值。
3、具體脈沖寬度要通過TCMPBn與TCNTBn兩個寄存器的設置來完成。這步涉及到寄存器內部邏輯的工作流程。如下:
將TCMPBn和TCNTBn裝入初始值,在設置TCON寄存器之后會啟動定時器,這時將過TCMPBn與TCNTBn兩個寄存器的值裝入內部寄存器TCMPn和TCNTn中,在定時器n的工作頻率下,TCNTn開始減一計數(shù),在TCNTn的值等于TCMPn的值的時候,TOUTn翻轉,當TCNTn的值達到0的時候,再次翻轉,就這樣周而復始,形成了脈沖。并且觸發(fā)定時器n的中斷(如果設置中斷的話)。
4、具體控制要交給TCON寄存器。它有以下幾個功能:(先看一下數(shù)據(jù)手冊)
由此可以看出,它有以下4個作用:
1、定時器的開始/停止。TCON[0]
2、手動更新。用于手動更新TCNTBn和TCMPBn,這里要注意的是在開始定時時,一定要把這位清零,否則是不能開啟定時器。TCON[1]
3、輸出反轉。TOUTn不反轉(0)/反轉(1)TCON[2]
4、自動加載。當定時器計數(shù)到0時,TCMPBn和TCNTBn寄存器的值自動裝入內部寄存器TCMPn和TCNTn中。TCON[3]
程序分析如下:(這程序是趙春江老師的程序)

#include "2440addr.h"

#define U32 unsigned int

typedef unsigned char BOOL;

#define TRUE 1

#define FALSE 0

BOOL stop;

static void __irq Key3_ISR(void) /*暫停鍵,關閉蜂鳴器*/

{

rSRCPND = rSRCPND | (0x1<<2); /*定義EINT2*/

rINTPND = rINTPND | (0x1<<2);

rTCON &= ~0x8; /*禁止定時器自動重載,即關閉定時器0111*/

stop = TRUE;

}

void __irq Key2_ISR(void) /*重啟鍵,開啟蜂鳴器*/

{

rSRCPND = rSRCPND | 0x1; /*定義EINT0*/

rINTPND = rINTPND | 0x1;

stop = FALSE;

}

void delay(int a)

{

int k;

for(k=0;k

;

}

void Main(void)

{

int freq;

rGPBCON = 0x155556; /*B0為TOUT0,B5~B8為輸出,給LED 0001 0101 0101 0101 0101 0110*/

rGPBUP = 0x7ff; /*0111 1111 1111關閉上拉使能*/

rGPFCON = 0xaaaa; /*F口為EINT,給按鈕 1010 1010 1010 1010*/

/*按鈕的一些必要配置*/

rSRCPND = 0x0f; /*中斷設置*/

rINTMSK = ~0x0f;

rINTPND =0x0f;

rEXTINT0 = 0x2222; /*EINT0/EINT1均設置為下降沿觸發(fā)*/

freq = 2500;

rTCFG0 &= 0xFFFF00;

rTCFG0 |= 0x31; /*prescal 是49 3*16+1=49 timer0 and timer1*/

rTCFG1 &= ~0xF; /*低四位清零 divider value=1/2,因為PCLK為50MHz,所以50MHz/50/2=500kHz/

rTCNTB0 = 5000; /*定時器計數(shù)初始值*/

rTCMPB0 = freq; /*定時器比較值*/

rTCON &= ~0x1F;

rTCON |= 0xf; /*死區(qū)無效,自動裝載,電平反轉,手動更新,定時器開啟*/

rTCON &= ~0x2 ; /*手動更新位清零,PWM開始工作*/

pISR_EINT0 = (U32)Key2_ISR;

pISR_EINT2 = (U32)Key3_ISR;

stop = FALSE;

rGPBDAT = ~0x60; /*兩個LED亮*/

while(1)

{

/*頻率遞增*/

for ( ; freq<4950 ; )

{

freq+=10;

rTCMPB0 = freq; /*重新賦值*/

delay(20000);

while (stop == TRUE) /*是否暫停*/

{

delay(1000);

if (stop ==FALSE) /*判斷是否重啟*/

{

rTCON &= ~0x1F;

rTCON |= 0xf;

rTCON &= ~0x2 ; /*恢復PWM功能*/

}

}

/*4個LED隨著頻率的高低,時滅時亮。燈亮的數(shù)目4-3-2-1*/

if(freq == 100)

rGPBDAT = ~0x560; /*0001 1110 0000 取反之后1110 0001 1111*/

if(freq == 1300)

rGPBDAT = ~0x160; /*1110 0000取反之后 0001 1111*/

if(freq == 2500)

rGPBDAT = ~0x60; /*0110 0000取反之后 1001 1111*/

if(freq == 3700)

rGPBDAT = ~0x20; /*0010 0000取反之后 1101 1111*/

if(freq == 4900)

rGPBDAT = ~0x0; /*0000取反之后 1111111111*/

}

/*頻率遞減*/

for( ; freq>50 ; )

{

freq-=10;

rTCMPB0 = freq;

delay(20000);

while (stop == TRUE)

{

delay(1000);

if (stop ==FALSE)

{

rTCON &= ~0x1F;

rTCON |= 0xf;

rTCON &= ~0x2 ;

}

}

if(freq == 100)

rGPBDAT = ~0x560;

if(freq == 1300)

rGPBDAT = ~0x160;

if(freq == 2500)

rGPBDAT = ~0x60;

if(freq == 3700)

rGPBDAT = ~0x20;

if(freq == 4900)

rGPBDAT = ~0x0;

}

}

}

TOUT輸出的波形是:
 
上圖是頻率上升時的大致波形圖。由此可以看出高電平在每個周期中維持的時間越來越長,低電平時間越來越短。頻率下降時的波形圖正好相反。


評論


技術專區(qū)

關閉