msp430f5529定時器
定時器A是一個復(fù)合了捕獲/比較寄存器的十六位的定時(加減)計數(shù)器。定時器A支持多重捕獲/比較,PWM輸出和內(nèi)部定時,具有擴(kuò)展中斷功能,中斷可以由定時器溢出產(chǎn)生或由捕獲/比較寄存器產(chǎn)生。
特征簡介:
○四種運(yùn)行模式的異步16位定時/計數(shù)器
○自身時鐘源可選擇配置
○最多達(dá)5個可配置的捕獲/比較寄存器(CCR)
capture/compare registers
○可配置的PWM輸出
○異步輸入和輸出鎖存
○對所有Timer_A中斷快速響應(yīng)的中斷向量寄存器
下面這張圖形象的解釋了Timer_A的結(jié)構(gòu)特性
6.2 TA(Timer_A)的幾個基本操作設(shè)置(含寄存器介紹及設(shè)置)
聲明:所有寄存器同樣支持字和字節(jié)操作,不要忘記這是什么意思
所有寄存器初始化都為0x0000
6.2.1 TA控制寄存器TACTL(最常用最基本)
再次說明一下例如:TA0CTL、TA1CTL、TA2CTL分別表示3個不同
定時器A的控制寄存器
rw-(0)表示默認(rèn)讀寫均為0
TASSELx :時鐘源選擇。盡量不要選TASSEL0-TACLK外部時鐘源,因?yàn)槿绻鸗ACLK和CPU時鐘不同步,很容易出問題。(TA0CLK接P1.0引腳)
00 TACLK
01 ACLK
10 SMCLK
11 ~TACLK
IDx:第一次分頻控制。ID0-1分頻;ID1-2分頻;ID2-4分頻;ID3-8分頻
MC:工作模式控制。(建議在修改定時器運(yùn)行模式前先停止定時器(中斷使能、中斷標(biāo)志、TACLR例外),以避免產(chǎn)生未知的誤操作。)
00 停止模式:定時器停止
01 增模式: 定時器計數(shù)到TACCR0
10 連續(xù)模式,定時器計數(shù)到0FFFH
11增減模式:定時器加計數(shù)到TACCR0然后減計數(shù)到0000H
TACLR:定時器清零位。該位置位會復(fù)位TA寄存器,時鐘分頻和計數(shù)方向。
TACLR位會自動復(fù)位并置0
TAIE:定時器中斷使能
0:中斷禁止
1:中斷允許
TAIFG:中斷標(biāo)志位
0:沒有中斷發(fā)生
1:有中斷掛起
6.2.2 計數(shù)值存放寄存器TAR
①顯然,最大存放計數(shù)值為0xFFFFh;
②(類似51單片機(jī))可以被用來存放一個初值,然后選用連續(xù)模式。這樣不斷計滿再手動填充,從而達(dá)到精確計時的效果;
③默認(rèn)為0,且對該寄存器可以直接賦值;
6.2.3 擴(kuò)展寄存器TAEX0
很簡單,這個寄存器就是為了控制時鐘源的二次分頻(看結(jié)構(gòu)圖)。
該寄存器的低3為定義為TAIDEX:000-111分別表示1-8分頻
6.2.4 捕獲/比較寄存器TACCR0-TACCR4(共5個)
比較模式下,用來設(shè)定計數(shù)終值;
捕獲模式下用來將捕獲的TAR值存放進(jìn)TACCRx中。
6.3 MC控制的四種工作模式的詳細(xì)講解
6.3.1 MC=0停止模式
這是系統(tǒng)默認(rèn)的模式,定時計數(shù)器禁止工作。
6.3.2 MC=1增模式
總結(jié)幾句話:(紅色標(biāo)記的很重要)
①此模式下嚴(yán)禁從0xffff開始計數(shù);
②注意從0計到TACCR0,實(shí)際上記了TACCR0+1個數(shù);
③計到TACCR0后,會回到0重新開始計數(shù);
④如果TAR的值大于TACCR0,這時候會立即從0開始計數(shù);
⑤當(dāng)定時器計數(shù)到TACCR0的值時,中斷標(biāo)志CCIFG位(之后會講到)置位。當(dāng)定時器由TACCR0返回0時,TAIFG中斷標(biāo)志置位;
⑥在定時器運(yùn)行時修改TACCR0,如果新的周期值大于或等于舊的周期值,或大于當(dāng)前的定時器計數(shù)值,那么定時器立刻開始執(zhí)行新周期計數(shù)。如果新周期小于當(dāng)前的計數(shù)值,那么定時器回到0。但是,在回到0之前會多一個額外的計數(shù)。
6.3.3 MC=2連續(xù)模式
在連續(xù)模式中,定時器重復(fù)計數(shù)到0FFFFH,然后重新從0開始增計數(shù)(除非每次重裝計數(shù)初值)。當(dāng)定時器從0FFFFH到0時,TAIFG中斷標(biāo)志置位。
應(yīng)用:連續(xù)模式下利用捕獲/比較器產(chǎn)生需要的時間間隔。原理是:計數(shù)在一直進(jìn)行,捕獲器TACCRX中存有第一個計數(shù)終值,每次捕獲器計到TACCRX時,會產(chǎn)生中斷標(biāo)志,我們可以在中斷服務(wù)函數(shù)中寫入一個計算好的下一個的計數(shù)終值,這樣無限計算和中斷下去,那么該捕獲器就會產(chǎn)生一個穩(wěn)定的時間間隔序列。(其實(shí)吧,不明白也沒關(guān)系。就算明白了,也不好用,因?yàn)橛嬎闫饋砗苈闊┒乙膊缓糜?
如圖:
6.3.4 MC=3增減模式(常用于生成PWM波)
①該模式下,計數(shù)方向是固定的,即讓定時器停止后再重新啟動定時器,它就沿著停止時的計數(shù)方向和數(shù)值開始計數(shù)。如果不希望這樣,就需要將TACLR置位來清除方向。TACLR位也會清除TAR的值和定時器的時鐘分頻。
②此模式下置位情況如下圖:
③當(dāng)定時器運(yùn)行時,改變TACCR0的值,如果正處于減計數(shù)的情況,定時器會繼續(xù)減到0,新的周期在減到0后開始。
如果正處于增計數(shù)狀態(tài),新周期大于等于原來的周期,或比當(dāng)前計數(shù)值要大,定時器會增計數(shù)到新的周期;如果新周期小于原來的周期,定時器立刻開始減計數(shù),但是,在定時器開始減計數(shù)之前會多計一個數(shù)。
6.4 捕獲比較模塊
這是在以上介紹的基礎(chǔ)上正式講TA的重要功能。
先看一個寄存器TACCTL0-TACCTL6:(TA中最復(fù)雜的寄存器,用到的時候查表啦)
CMx:捕獲模式設(shè)定 00 不捕獲
01 上升沿捕獲
10 下降沿捕獲
11上升和下降沿都捕獲
CCISx:捕獲源的選擇 00 CCIxA
01 CCIxB
10 GND
11 VCC
SCS:同步捕獲源,設(shè)定是否與時鐘同步
0 異步捕獲
1 同步捕獲
SCCI:選擇的CCI輸入信號由EQUx信號鎖存,并可通過該位讀取。
CAP: 0-比較模式 1-捕獲模式
OUTMOD:輸出模式控制位。(之后會在輸出模塊詳細(xì)解釋)
CCIE:中斷使能,該位允許相應(yīng)的CCIFG標(biāo)志中斷請求 。
0-中斷禁止 1 -中斷允許
CCI 3 :捕獲比較輸入,所選擇的輸入信號可以通過該位讀取
OUT : 對于輸出模式0,該位直接控制輸出狀態(tài) 。
0-輸出低電平 1-輸出高電平
COV:捕獲溢出位。該位表示一個捕獲溢出發(fā)出,COV必須由軟件復(fù)位。
0-沒有捕獲溢出發(fā)生 1-有捕獲溢出發(fā)生
CCIFG:捕獲比較中斷標(biāo)志位。
0-沒有中斷掛起 1-有中斷掛起
最后一個寄存器TAIV:(還記得外部中斷寄存器嗎,里面同樣存儲的只是一個中斷代號)
里面沒有TACCR0的中斷標(biāo)志,因?yàn)門ACCR0優(yōu)先級最高,有一個專門的中斷向量)
這里面的標(biāo)志位需要軟件手動清零。一種情況例外:兩個中斷同時發(fā)生,先響應(yīng)優(yōu)先級高的中斷,當(dāng)該中斷服務(wù)程序結(jié)束后,該位的中斷標(biāo)志會自動清零,然后去響應(yīng)另外一個中斷。
6.4.1比較模式
TA啟動時默認(rèn)為比較模式。
(CAP=0時選擇比較模式)
比較模式簡介:(也就是一般意義上的定時計時模式)
這是定時器的默認(rèn)模式,當(dāng)在比較模式下的時候,與捕獲模式相關(guān)的硬件停止工作,如果這個時候開啟定時器中斷,然后設(shè)置定時器終值(將終值寫入TACCRx),開啟定時器,當(dāng)TAR的值增加到和某個TACCRx里面的值相等的的時候,相應(yīng)的中斷標(biāo)志位CCIFGx置一,同時中斷標(biāo)志位TAIFG置位。若中斷允許未開啟則只將中斷標(biāo)志位CCIFGx置一。
(還記得51單片機(jī)的定時器嗎)
注意:當(dāng)Timer_A要用到TACCR0的值作為終值來計數(shù)(也就是增模式或者增減模式),很顯然TACCR0的值一定要大于其TACCRx的值,否則那些比TACCR0大的計數(shù)值就沒有存在的意義了。
下面是我畫的一個圖。比較形象的解釋了工作原理。(期間TACCR的值不改變)
所謂的比較就是,如果計數(shù)器TAR中的值和某個TACCRx中的值相等了,那么相應(yīng)的標(biāo)志位就會置位。

這只是一個原理,實(shí)際應(yīng)用的時候,會很靈活,通過一個一個設(shè)定每次的TACCR值,可以得到想要的各種時間間隔。
總結(jié):比較模式用于選擇PWM輸出信號或在特定的時間間隔中斷。當(dāng)TAR計數(shù)到TACCRx的值時:
○相應(yīng)的中斷標(biāo)志CCIFG置位;
○內(nèi)部信號EQUx=1
○EQUx根據(jù)輸出模式來影響輸出信號
○輸入信號CCI鎖存到SCCI
6.4.2 捕獲模式
當(dāng)CAP=1時,選擇捕獲模式。捕獲模式用于記錄時間事件,比如速度估計或時間測量。捕獲輸入CCIXA和CCLXB連接外部的引腳或內(nèi)部的信號,這通過CCISX位來選擇。CMX位選擇捕獲輸入信號觸發(fā)沿;上升沿、下降沿或兩者都捕獲。當(dāng)輸入信號的觸發(fā)沿到來時,捕獲事件發(fā)生:
○定時器的TAR值復(fù)制到TACCRX寄存器中
○中斷標(biāo)志位CCIFG置位
注意:①捕獲信號可能會和定時器時鐘不同步,并導(dǎo)致競爭條件的發(fā)生。將SCS位置位可以在下個定時器時鐘使捕獲同步
②如果第二次捕獲發(fā)生時,第一次捕獲的TAR值還沒有及時被存到TACCRx,捕獲比較寄存器就會產(chǎn)生一個溢出邏輯,COV位在此時置位, COV位必須軟件清除。
6.5 輸出模塊
傳統(tǒng)的定時器,都是通過標(biāo)志位的判斷來定時觸發(fā)事件的。而430則具有輸出模塊,通過和定時結(jié)合起來,可以方便的產(chǎn)生PWM信號或者其它控制信號
每個捕獲/比較器都有一個輸出口,如P1.1-P1.5對應(yīng)TA0.0-TA0.4這5個捕獲比較器的輸出。
輸出模式: 輸出模式由OUTMODx位來確定,如下表對于所有模式來說(模式0除外),OUTx信號隨著定時器時鐘的上升沿而改變。輸出模式2,3,6和7對輸出模式0無效,因?yàn)榇四J较拢珽QUx=EQU0。
(復(fù)位指的是置0)
OUTMODX模式說明
000輸出輸出信號OUTx由OUT位定義。當(dāng)OUT位更
新時,OUTx信號立刻更新
001置位當(dāng)定時器計數(shù)到TACCRX值時,輸出置位,并保
持置位直到定時器復(fù)位或選擇了另一個輸出模式
010翻轉(zhuǎn)/復(fù)位當(dāng)定時器計數(shù)到TACCRX值時,輸出翻轉(zhuǎn)。當(dāng)定
時器計數(shù)到TACCR0值時,輸出復(fù)位
011置位/復(fù)位當(dāng)定時器計數(shù)到TACCRX值時,輸出置位。當(dāng)定
時器計數(shù)到TACCR0值時,輸出復(fù)位
100翻轉(zhuǎn)當(dāng)定時器計數(shù)到TACCRX值時,輸出翻轉(zhuǎn)。輸出
信號的周期將是定時器的2倍
101復(fù)位當(dāng)定時器計數(shù)到TACCRX值時,輸出復(fù)位,并保
持復(fù)位直到選擇了另一個輸出模式
110翻轉(zhuǎn)/置位當(dāng)定時器計數(shù)到TACCRX值時,輸出翻轉(zhuǎn)。當(dāng)定
時器計數(shù)到TACCR0值時,輸出置位
111復(fù)位/置位當(dāng)定時器計數(shù)到TACCRX值時,輸出復(fù)位。當(dāng)定
時器計數(shù)到TACCR0值時,輸出置位
舉一個例子:結(jié)合上表看下圖
注意:在模式轉(zhuǎn)換的時候,一定要保持OUTMOD至少一位置位,除非轉(zhuǎn)向0模式。所以最好的做法是:先把OUTMOD置為7,然后再清除掉不需要的位。
做一個說明:比較模式下,當(dāng)計數(shù)器TAR中的值和TACCRX中的設(shè)計值相等時,相應(yīng)捕獲/比較器的EQUx就會置位。那么EQU0、EQUx和OUTMOD是怎么來影響輸出的呢?以模式2(翻轉(zhuǎn)/復(fù)位)為例,該模式的定義是這樣的:當(dāng)定時器計數(shù)到TACCRX值時,輸出翻轉(zhuǎn)。當(dāng)定時器計數(shù)到TACCR0值時,輸出復(fù)位。于是,這句話就也可以翻譯成在模式2的條件下,當(dāng)EQUX=1時,輸出翻轉(zhuǎn);當(dāng)EQU0等于1的時候,輸出復(fù)位。這兩個信號這里相當(dāng)于兩個觸發(fā)(使能)信號了。
總結(jié)
實(shí)驗(yàn)一:
/*利用Timer_A比較模式下的多路定時,讓LED閃爍*/
#include
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
P1DIR|=(BIT1+BIT2+BIT3+BIT4+BIT5);//P1.1-P1.5為輸出方向
P1OUT=0x00; //全部拉低,初始化LED全滅
TA0CCTL1=CCIE; //捕獲比較器1開啟CCIFG位中斷
TA0CCR1=13107; //置入要比較的數(shù)值0xff/5=13107
TA0CCTL2=CCIE; //捕獲比較器2開啟中斷
TA0CCR2=26214; //13107*2=26214
TA0CCTL3=CCIE; //捕獲比較器3開啟中斷
TA0CCR3=39321; //13107*3=39321
TA0CCTL4=CCIE; //捕獲比較器4開啟中斷
TA0CCR4=52428; //13107*4=52428
TA0CTL|=TACLR+TAIE; //開啟中斷并清零
TA0CTL|=TASSEL_1+MC_2+TAIE;//選擇SCLK32.768KHZ作為時鐘,選用連續(xù)模式,并開啟中斷
/*這樣的話,5個燈閃一遍的時間為0xffff/32768=2S*/
__enable_interrupt(); //開啟總中斷
while(1);
}
/*TIMER0_A0_VECTOR是計時器0的CCR0的中斷寄存器,TIMER0_A1_VECTOR是計時器0的CCR1-CCR4、TA的寄存器*/
/*同理定時器TA1也是分為兩個TIMER1_A0_VECTOR和TIMER1_A1_VECTOR*/
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TimerA(void)
{
switch(__even_in_range(TA0IV,14))
/* 這句話的意思是:只有在TA0IV的值是在0--14內(nèi)的偶數(shù)時才會執(zhí)行switch函數(shù)內(nèi)的語句
其作用是提高switch語句的效率*/
{
case 2:P1OUT=BIT1;break; //TACCR1 CCIFG置位,表明計數(shù)值和設(shè)定的13107相等了,也就是說計了0.4S了
case 4:P1OUT=BIT2;break; //TACCR2 CCIFG置位,表明計了0.8S了
case 6:P1OUT=BIT3;break; //TACCR3 CCIFG置位,表明計了1.2S了
case 8:P1OUT=BIT4;break; //TACCR4 CCIFG置位,表明計了1.6S了
case 14:P1OUT=BIT5;break; //TAIFG置位,表明計了2S了
default:break;
}
}
實(shí)驗(yàn)二:比較模式-增減模式輸出PWM波

/*在比較和增減模式下產(chǎn)生PWM波(矩形波) */
/*提一個PWM波的用處:驅(qū)動直流電機(jī)。我們知道對于直流電機(jī),驅(qū)動它的電流的頻率并不影響轉(zhuǎn)速 ,只有占空比會影響轉(zhuǎn)速*/
/*開發(fā)板上P2.0是有外接排針的,所以用這一端口輸出PWM*/
/*看CPU引腳發(fā)現(xiàn),P2.0為TA1.1,也就是定時器A1的1號捕獲比較器輸出口*/
#include
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
P2SEL|=BIT0; //聲明有特殊功能,不做普通I/O使用
P2DIR|=BIT0; //輸出
P2DS |=BIT0; //全力驅(qū)動,否則可能無法驅(qū)動電機(jī)
P2OUT&=~BIT0; //初始化輸出低電平
/*把SMCL配置為XT2 4MHZ*/
P5SEL=BIT2+BIT3; //聲明特殊功能,將用作外部時鐘晶振XT2輸入
UCSCTL6&=~XT2OFF; //開啟XT2
while(SFRIFG1 & OFIFG)
{
UCSCTL7 &=~(XT2OFFG+DCOFFG+XT1LFOFFG);//清除3種時鐘錯誤標(biāo)志
SFRIFG1&=~(OFIFG);//清除時鐘錯誤標(biāo)志位
} //直到XT2從起振到振蕩正常,沒有錯誤發(fā)生
UCSCTL4|=SELS_5; //把SMCLK的時鐘源選為XT2 4MHZ
TA1CCTL0=CCIE; //定時器A1的捕獲比較器0開啟CCIFG位中斷
TA1CCR0=200; //置入計數(shù)終值,則PWM頻率為10KHZ
TA1CCTL1=CCIE; //捕獲比較器1開啟中斷
TA1CCR1=50; //占空比為75%
TA1CTL|=TACLR; //將計時器A1清零
TA1CTL|=TASSEL_2+MC_3; //定時器選擇SMCLK作為時鐘源,且為增減模式
TA1CCTL1=OUTMOD_4; //定時器A1中的捕獲比較器1,輸出模式為4翻轉(zhuǎn)
while(1);
}
//呼吸燈//
// 介紹: 該程序利用TIMER A 的 UP模式 在P1.3腳產(chǎn)生PWM輸出
// 將CCR0設(shè)置為1500來定義PWM的周期,利用循環(huán)不斷改變CCR1的值,
// 實(shí)現(xiàn)利用改變PWM的占空比來改變LED亮度.
// SMCLK = MCLK = TACLK = default DCO
#include
void delay_nms(unsigned int n)// 延時函數(shù)
{
unsigned int j;
for (j=0;j<(n);j++)
{
__delay_cycles(400); //太短會使LED顯得好像在常亮,太長就要等較長時間來觀察了
}
}
void main(void)
{
unsigned const PWMPeriod = 1500; //設(shè)置PWM周期參數(shù),const聲明此值不允許改變.該數(shù)值太大,會導(dǎo)致LED閃爍
volatile unsigned int i; //聲明變量i是隨時可變的,系統(tǒng)不要去優(yōu)化這個值
WDTCTL = WDTPW + WDTHOLD; // 關(guān)閉看門狗
P1DIR |=BIT3; // 設(shè)置 P1.3為輸出
P1SEL |=BIT3; // 設(shè)置 P1.3為TA0.2輸出
TA0CCR0 = PWMPeriod; // 設(shè)置PWM 周期
TA0CCTL2 = OUTMOD_7; // 設(shè)置PWM 輸出模式為:7 - PWM復(fù)位/置位模式,
// 即輸出電平在TAR的值等于CCR2時復(fù)位為0,當(dāng)TAR的值等于CCR0時置位為1,改變CCR2,從而產(chǎn)生PWM。其實(shí)模式2也可以
TA0CTL= TASSEL_2 +MC_1; // 設(shè)置TIMERA的時鐘源為SMCLK, 計數(shù)模式為up,到CCR0再自動從0開始計數(shù)
while(1)
{
TA0CCR2=0;//確保最開始是暗的
//漸亮過程:不斷設(shè)置TA0CCR2的值,使翻轉(zhuǎn)的時間變長,改變PWM的占空比
for(i=0;i
{
TA0CCR2=i;
delay_nms(4-(i/500)); //占空比變化的延時,調(diào)整延遲時間可改變呼吸燈變暗的速度
//在暗的時候延長delay時間,可增強(qiáng)效果
}
//漸暗過程:不斷設(shè)置TA0CCR2的值,使翻轉(zhuǎn)的時間變短,改變PWM的占空比
for(i=PWMPeriod;i>0;i-=1)
{
TA0CCR2=i;
delay_nms(4-(i/500)); //占空比變化的延時,調(diào)整延遲時間可改變呼吸燈變暗的速度
//在暗的時候延長delay時間,可增強(qiáng)效果
}
TA0CCR2=0; //確保燈暗
delay_nms(250); //時間長一點(diǎn),增強(qiáng)視覺效果
}
}