s3c2440晶元中一共有5個16位的定時器,其中有4個定時器(定時器0~定時器3)具有脈寬調變功能,即他們都有個輸出引腳,可以通過定時器來控制引腳週期性的高低電平變化,定時器4沒有輸出引腳。上次離線執行pwm測試程式實驗的時候就用到了這塊,所以這次將pwm和定時器放在一起來學習。
定時器部件的時鐘源為pclk,首先通過兩個8位預分頻器降低頻率,定時器0和1共用第乙個預分頻器,2,3,4共用第二個預分頻器。
預分頻器輸出接入第二級分頻器,可以生成5種分頻訊號(1/2,1/4,1/8,1/16,tclk),其中8位預分頻器是可程式設計,根據裝載值來分頻pclk,值儲存在tcfg0和tcfg1中。
定時器內部控制邏輯工作流程如下:
定時器n的輸出管腳toutn初始狀態為高電平,然後會兩次反轉,
也可以通過tcon暫存器設定其初始電平,這樣輸出就完全反相了。
通過設定tcmpbn、tcntbn可以設定toutn輸出訊號的占空比,這樣就是所謂的pwm。這裡pwm的原理就不做介紹了。
下面介紹定時器的幾種重要暫存器,每一種我們都以定時器0為例。
tcfg0暫存器
[7:0],[15:8]各8位分別被用於控制預分頻器0,1,值為0~255。經過預分頻器出來的時鐘頻率為:pclk/(prescaler+1)。
tcfg1暫存器
經過預分頻器得到的時鐘將進入2次分頻,這個暫存器就是設定2次分頻係數的。這樣定時器的工作頻率為:pclk/(prescaler+1)/(divider value),其中prescaler=0~255,divider value=2,4,6,8。
tcon暫存器
tcon暫存器位[3:0]、[11:8]、[15:12]、[19:16]、[22:20]分別用於定時器0~4,位[4]為死區使能位,[7:5]為保留位。除了定時器4沒有輸出反轉位外,其他位功能相似,這裡以定時器0為例加以說明。位[0]開啟停止位:0停止定時器,1開始定時器。[1]手動更新位:0無用,1將tcntbn/tcmpbn暫存器的值裝入內部暫存器tcntn\tcmpn中。[2]輸出反**0不反轉,1反轉。[3]自動載入:0不自動載入,1自動載入。
tcntbn/tcmpbn暫存器
tcnton暫存器
下面就具體介紹如何實現pwm功能。
1、pwm是通過引腳tout0~tout3輸出的,而這4個引腳是與gpb0~gpb3復用的,因此要實現pwm功能首先要把相應的引腳配置成tout輸出。
2、再設定定時器的輸出時鐘頻率,它是以pclk為基準,再除以用暫存器tcfg0配置的prescaler引數,和用暫存器tcfg1配置的divider引數。
3、然後設定脈衝的具體寬度,它的基本原理是通過暫存器tcntbn來對暫存器tcntn(內部暫存器)進行配置計數,tcntn是遞減的,如果減到零,則它又會重新裝載tcntbn裡的數,重新開始計數,而暫存器tcmpbn作為比較暫存器與計數值進行比較,當tcntn等於tcmpbn時,toutn輸出的電平會翻轉,而當tcntn減為零時,電平會又翻轉過來,就這樣周而復始。因此這一步的關鍵是設定暫存器tcntbn和tcmpbn,前者可以確定乙個計數週期的時間長度,而後者可以確定方波的占空比。由於s3c2440的定時器具有雙快取,因此可以在定時器執行的狀態下,改變這兩個暫存器的值,它會在下個週期開始有效。
4、最後就是對pwm的控制,它是通過暫存器tcon來實現的,當不想計數了,可以使自動過載無效,這樣在tcntn減為零後,不會有新的數載入給它,那麼toutn輸出會始終保持乙個電平(輸出反轉位為0時,是高電平輸出;輸出反轉位為1時,是低電平輸出),這樣就沒有pwm功能了,因此這一位可以用於停止pwm。
總的來說pwm功能其實就是對2440定時器的應用。
下面我們來分析上次離線執行pwm測試程式中沒有分析的buzzer_freq_set函式。函式如下:
void buzzer_freq_set( u32 freq )
rgpbcon &= ~3;
rgpbcon |= 2;
rtcfg0 &= ~0xff;
rtcfg0 |= 15;
rtcfg1 &= ~0xf;
rtcfg1 |= 2;
rtcntb0 = (pclk>>7)/freq;
rtcmpb0 = rtcntb0>>1;
rtcon &= ~0x1f;
rtcon |= 0xb;
rtcon &= ~2;
首先rgpbcon &= ~3;其他位不變,只是把最低2位清0。
rgpbcon |= 2;最低2位賦值為10。
這兩句話的作用是讓gpbcon暫存器最低兩位為10,即配置gpb0為復用功能tout0作為pwm輸出。
rtcfg0 &= ~0xff; tcfg0暫存器低8位清0,即使用定時器0。
rtcfg0 |= 15;賦值給tcfg0暫存器低8位,prescaler = 15。
rtcfg1 &= ~0xf; tcfg1只是最低4位清0,使用定時器0。
rtcfg1 |= 2;定時器0二次分頻divider value=8。
rtcntb0 = (pclk>>7)/freq;這裡是配置計時器的計數緩衝暫存器,讓pclk/2^7/freq得到完成乙個pwm週期需要計數值。因為通過前面的設定,我們知道定時器的工作頻率=pclk/(15+1)/8=pclk/(2^7),即pclk>>7,所以定時器工作頻率/pwm freq(pwm週期/定時器計一次數的週期)=計數值。
rtcmpb0 = rtcntb0>>1; 這裡是配置計時器的比較緩衝暫存器,讓比較值為初始值的一半,即設定了pwm的占空比為50%。
rtcon &= ~0x1f; 和rtcon |= 0xb;這兩句同上,給tcon最低5位賦值,開啟定時器,第一次使用定時器手動更新以便裝入tcntb0和tcmp0的值,關閉反相器,自動載入,disable 死區。
rtcon &= ~2; 清0手動更新位。
這就完成了pwm的設定。
當我們完成試驗退出時用到buzzer_stop函式,我們來看這個函式:
void buzzer_stop( void )
rgpbcon &= ~3;
rgpbcon |= 1;
rgpbdat &= ~1;
rgpbcon &= ~3;和rgpbcon |= 1;這兩句上面已經分析過,是配置gpbcon的,不同是這次讓gpbcon最低兩位為01,即作為輸出功能,不再作為pwm的tout了。
rgpbdat &= ~1;即gpb0輸出0,蜂鳴器不發聲。
至此pwm蜂鳴器發聲實驗就分析完了。後面使用蜂鳴器唱歌等實驗原理相似,只不過調整聲音頻率和對於聲音頻率的延時時長的控制,後面不做分析了
S3C2440定時器的使用
include mytimer.h include lhg def.h include uart.h include lhg def.h include 2440addr.h timer input clock frequency pclk pclk 50mhz prescaler 0 255 de...
S3C2440看門狗定時器
看門狗定時器的主要作用是在程式因為干擾而跑飛後,能夠使系統復位,不至於使系統永遠的死下去。它的原理與一般的定時器沒有多大區別,就是先要設定好一段時間,當超過這段時間後,就從當前執行的程式中跳出進入中斷處理程式中。但兩者的主要差別是,一般的定時器中斷是我們希望它發生的,因此我們不會在定時器中斷發生前的...
ARM9 S3C2440 定時器中斷
在講解之前,先介紹一下s3c2440時鐘系統。一般來說,mcu的主時鐘源主要是外部晶振或外部時鐘,而用的最多的是外部晶振。在正確情況下,系統內所使用的時鐘都是外部時鐘源經過一定的處理得到的。由於外部時鐘源的頻率一般不能滿足系統所需要的高頻條件,所以往往需要pll 鎖相環 進行倍頻處理。在s3c244...