S3C2440中有5個16位定時器,timer0,timer1,timer2,timer3和timer4。其中,只有timer4是一個沒有輸出引腳的內部定時器。所以,只有定時器0,1,2,3有脈寬調製功能(PWM)。定時器0有一個用於大電流設備的死區生成器。(以下,以定時器0爲例)
S3C2440的PWM輸出,主要是利用比較寄存器TCMPB0(0x51000010)。
在定時器使能時,定時器計數緩存寄存器(TCNTBn)得到一個被裝載到遞減計數器中的初始值。定時器比較緩存寄存器(TCMPBn)有一個被裝載比較器中用來和遞減計數器得值作比較的初始值。
每個定時器有一個自己的由定時器時鐘驅動的16位遞減計數器。當遞減計數器爲零時,定時器中斷請求生成通知CPU定時器操作已經完成。當定時器計數器達到0,相應的TCNTBn的值也知道裝載到遞減計數器中以繼續下一個操作(自動裝載)。但是,如果定時器停止了,例如在定時器運行模式下通過對TCONn的定時器使能位清零,則TCNTBn的值不會裝載到計數器中。
TCMPBn的值用於脈寬調製。當遞減計數器的值和定時器控制邏輯中的比較寄存器的值匹配時,定時器控制邏輯改變輸出電平。因此,比較寄存器決定了PWM輸出的開啓時間。
有了以上知識,可以知道
在初始化定時器時,主要要設定以下幾個寄存器(以定時器0爲例):
定時器輸出時鐘頻率=PCLK/(prescaler value + 1)/(divider value)
TCFG0(0x51000000),如:TCFG0=99;//prescaler value="99"
TCFG1(0x51000004),如: TCFG1=0x03;//divider value="1/16"
這樣,當PCLK=400M時。定時器輸出頻率爲6.25M
下面就要給定時器裝初值了,
TCNTB0(0x5100000c),如,TCNTB0=62500;//裝入初值 1s中斷一次
TCMPB0(0x51000010),如,TCMPB0=rTCNTB0>>1;//50%
如果不使用PWM的話,可以不設TCMPB0,或將其設爲0。
接着就可以啓動定時器了,不過第一次必須手動裝載TCON=1<<1;
裝載後,改爲自動裝載,並啓動定時器TCON=0x09;
其中TCON(0x51000008)
爲了驅動蜂鳴器,還要初始化一下I/O口。
我用的板子是友善的,蜂鳴器連在了GPB0上。
通過改變GPBCON(0x56000010)的最後兩位,使能PWM
void GPIO_init(void)
{
rGPBCON &= ~3;
rGPBCON |= 2;
}