6.4 捕獲比較模塊
這是在以上介紹的基礎上正式講TA的重要功能。
先看一個寄存器TACCTL0-TACCTL6:(TA中最復雜的寄存器,用到的時候查表啦)
CMx:捕獲模式設定 00 不捕獲 01 上升沿捕獲 10 下降沿捕獲 11上升和下降沿都捕獲
CCISx:捕獲源的選擇 00 CCIxA 01 CCIxB 10 GND 11 VCC
SCS:同步捕獲源,設定是否與時鍾同步 0 異步捕獲 1 同步捕獲
SCCI:選擇的CCI輸入信號由EQUx信號鎖存,並可通過該位讀取。
CAP: 0-比較模式 1-捕獲模式
OUTMOD:輸出模式控制位。(之后會在輸出模塊詳細解釋)
CCIE:中斷使能,該位允許相應的CCIFG標志中斷請求 。 0-中斷禁止 1 -中斷允許
CCI3 :捕獲比較輸入,所選擇的輸入信號可以通過該位讀取
OUT : 對於輸出模式0,該位直接控制輸出狀態 。0-輸出低電平 1-輸出高電平
COV:捕獲溢出位。該位表示一個捕獲溢出發出,COV必須由軟件復位。 0-沒有捕獲溢出發生 1-有捕獲溢出發生
CCIFG:捕獲比較中斷標志位。 0-沒有中斷掛起 1-有中斷掛起
最后一個寄存器TAIV:(還記得外部中斷寄存器嗎,里面同樣存儲的只是一個中斷代號)里面沒有TACCR0的中斷標志,因為TACCR0優先級最高,有一個專門的中斷向量)
這里面的標志位需要軟件手動清零。一種情況例外:兩個中斷同時發生,先響應優先級高的中斷,當該中斷服務程序結束后,該位的中斷標志會自動清零,然后去響應另外一個中斷。
6.4.1比較模式
TA啟動時默認為比較模式。(CAP=0時選擇比較模式)
比較模式簡介:(也就是一般意義上的定時計時模式)
這是定時器的默認模式,當在比較模式下的時候,與捕獲模式相關的硬件停止工作,如果這個時候開啟定時器中斷,然后設置定時器終值(將終值寫入TACCRx),開啟定時器,當TAR的值增加到和某個TACCRx里面的值相等的的時候,相應的中斷標志位CCIFGx置一,同時中斷標志位TAIFG置位。若中斷允許未開啟則只將中斷標志位CCIFGx置一。還記得51單片機的定時器嗎)
注意:當Timer_A要用到TACCR0的值作為終值來計數(也就是增模式或者增減模式),很顯然TACCR0的值一定要大於其TACCRx的值,否則那些比TACCR0大的計數值就沒有存在的意義了。
所謂的比較就是,如果計數器TAR中的值和某個TACCRx中的值相等了,那么相應的標志位就會置位。
這只是一個原理,實際應用的時候,會很靈活,通過一個一個設定每次的TACCR值,可以得到想要的各種時間間隔。
總結:比較模式用於選擇PWM輸出信號或在特定的時間間隔中斷。當TAR計數到TACCRx的值時:
○相應的中斷標志CCIFG置位;
○內部信號EQUx=1
○EQUx根據輸出模式來影響輸出信號
○輸入信號CCI鎖存到SCCI
6.4.2 捕獲模式
當CAP=1時,選擇捕獲模式。捕獲模式用於記錄時間事件,比如速度估計或時間測量。捕獲輸入CCIXA和CCLXB連接外部的引腳或內部的信號,這通過CCISX位來選擇。CMX位選擇捕獲輸入信號觸發沿;上升沿、下降沿或兩者都捕獲。當輸入信號的觸發沿到來時,捕獲事件發生:
○定時器的TAR值復制到TACCRX寄存器中
○中斷標志位CCIFG置位
注意:①捕獲信號可能會和定時器時鍾不同步,並導致競爭條件的發生。將SCS位置位可以在下個定時器時鍾使捕獲同步
②如果第二次捕獲發生時,第一次捕獲的TAR值還沒有及時被存到TACCRx,捕獲比較寄存器就會產生一個溢出邏輯,COV位在此時置位, COV位必須軟件清除。
6.5 輸出模塊
傳統的定時器,都是通過標志位的判斷來定時觸發事件的。而430則具有輸出模塊,通過和定時結合起來,可以方便的產生PWM信號或者其它控制信號
每個捕獲/比較器都有一個輸出口,如P1.1-P1.5對應TA0.0-TA0.4這5個捕獲比較器的輸出。
輸出模式: 輸出模式由OUTMODx位來確定,如下表對於所有模式來說(模式0除外),OUTx信號隨着定時器時鍾的上升沿而改變。輸出模式2,3,6和7對輸出模式0無效,因為此模式下,EQUx=EQU0。(復位指的是置0)
| OUTMODX |
模式 |
說明 |
| 000 |
輸出 |
輸出信號OUTx由OUT位定義。當OUT位更 新時,OUTx信號立刻更新 |
| 001 |
置位 |
當定時器計數到TACCRX值時,輸出置位,並保 持置位直到定時器復位或選擇了另一個輸出模式 |
| 010 |
翻轉/復位 |
當定時器計數到TACCRX值時,輸出翻轉。當定 時器計數到TACCR0值時,輸出復位 |
| 011 |
置位/復位 |
當定時器計數到TACCRX值時,輸出置位。當定 時器計數到TACCR0值時,輸出復位 |
| 100 |
翻轉 |
當定時器計數到TACCRX值時,輸出翻轉。輸出 信號的周期將是定時器的2倍 |
| 101 |
復位 |
當定時器計數到TACCRX值時,輸出復位,並保 持復位直到選擇了另一個輸出模式 |
| 110 |
翻轉/置位 |
當定時器計數到TACCRX值時,輸出翻轉。當定 時器計數到TACCR0值時,輸出置位 |
| 111 |
復位/置位 |
當定時器計數到TACCRX值時,輸出復位。當定 時器計數到TACCR0值時,輸出置位 |
舉一個例子:結合上表看下圖
注意:在模式轉換的時候,一定要保持OUTMOD至少一位置位,除非轉向0模式。所以最好的做法是:先把OUTMOD置為7,然后再清除掉不需要的位。
做一個說明:比較模式下,當計數器TAR中的值和TACCRX中的設計值相等時,相應捕獲/比較器的EQUx就會置位。那么EQU0、EQUx和OUTMOD是怎么來影響輸出的呢?以模式2(翻轉/復位)為例,該模式的定義是這樣的:當定時器計數到TACCRX值時,輸出翻轉。當定時器計數到TACCR0值時,輸出復位。於是,這句話就也可以翻譯成在模式2的條件下,當EQUX=1時,輸出翻轉;當EQU0等於1的時候,輸出復位。這兩個信號這里相當於兩個觸發(使能)信號了。
總結
實驗一:
/*利用Timer_A比較模式下的多路定時,讓LED閃爍*/
#include <msp430f5529.h>
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; //置入要比較的數值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作為時鍾,選用連續模式,並開啟中斷
/*這樣的話,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內的偶數時才會執行switch函數內的語句
其作用是提高switch語句的效率*/
{
case 2:P1OUT=BIT1;break; //TACCR1 CCIFG置位,表明計數值和設定的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;
}
}
實驗二:比較模式-增減模式輸出PWM波
/*在比較和增減模式下產生PWM波(矩形波) */
/*提一個PWM波的用處:驅動直流電機。我們知道對於直流電機,驅動它的電流的頻率並不影響轉速 ,只有占空比會影響轉速*/
/*開發板上P2.0是有外接排針的,所以用這一端口輸出PWM*/
/*看CPU引腳發現,P2.0為TA1.1,也就是定時器A1的1號捕獲比較器輸出口*/
#include <msp430.h>
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
P2SEL|=BIT0; //聲明有特殊功能,不做普通I/O使用
P2DIR|=BIT0; //輸出
P2DS |=BIT0; //全力驅動,否則可能無法驅動電機
P2OUT&=~BIT0; //初始化輸出低電平
/*把SMCL配置為XT2 4MHZ*/
P5SEL=BIT2+BIT3; //聲明特殊功能,將用作外部時鍾晶振XT2輸入
UCSCTL6&=~XT2OFF; //開啟XT2
while(SFRIFG1 & OFIFG)
{
UCSCTL7 &=~(XT2OFFG+DCOFFG+XT1LFOFFG);//清除3種時鍾錯誤標志
SFRIFG1&=~(OFIFG); //清除時鍾錯誤標志位
} //直到XT2從起振到振盪正常,沒有錯誤發生
UCSCTL4|=SELS_5; //把SMCLK的時鍾源選為XT2 4MHZ
TA1CCTL0=CCIE; //定時器A1的捕獲比較器0開啟CCIFG位中斷
TA1CCR0=200; //置入計數終值,則PWM頻率為10KHZ
TA1CCTL1=CCIE; //捕獲比較器1開啟中斷
TA1CCR1=50; //占空比為75%
TA1CTL|=TACLR; //將計時器A1清零
TA1CTL|=TASSEL_2+MC_3; //定時器選擇SMCLK作為時鍾源,且為增減模式
TA1CCTL1=OUTMOD_4; //定時器A1中的捕獲比較器1,輸出模式為4翻轉
while(1);
}
//呼吸燈//
// 介紹: 該程序利用TIMER A 的 UP模式 在P1.3腳產生PWM輸出
// 將CCR0設置為1500來定義PWM的周期,利用循環不斷改變CCR1的值,
// 實現利用改變PWM的占空比來改變LED亮度.
// SMCLK = MCLK = TACLK = default DCO
#include <msp430f5529.h>
void delay_nms(unsigned int n)// 延時函數
{
unsigned int j;
for (j=0;j<(n);j++)
{
__delay_cycles(400); //太短會使LED顯得好像在常亮,太長就要等較長時間來觀察了
}
}
void main(void)
{
unsigned const PWMPeriod = 1500; //設置PWM周期參數,const聲明此值不允許改變.該數值太大,會導致LED閃爍
volatile unsigned int i; //聲明變量i是隨時可變的,系統不要去優化這個值
WDTCTL = WDTPW + WDTHOLD; // 關閉看門狗
P1DIR |=BIT3; // 設置 P1.3為輸出
P1SEL |=BIT3; // 設置 P1.3為TA0.2輸出
TA0CCR0 = PWMPeriod; // 設置PWM 周期
TA0CCTL2 = OUTMOD_7; // 設置PWM 輸出模式為:7 - PWM復位/置位模式,
// 即輸出電平在TAR的值等於CCR2時復位為0,當TAR的值等於CCR0時置位為1,改變CCR2,從而產生PWM。其實模式2也可以
TA0CTL= TASSEL_2 +MC_1; // 設置TIMERA的時鍾源為SMCLK, 計數模式為up,到CCR0再自動從0開始計數
while(1)
{
TA0CCR2=0;//確保最開始是暗的
//漸亮過程:不斷設置TA0CCR2的值,使翻轉的時間變長,改變PWM的占空比
for(i=0;i<PWMPeriod;i+=1)
{
TA0CCR2=i;
delay_nms(4-(i/500)); //占空比變化的延時,調整延遲時間可改變呼吸燈變暗的速度
//在暗的時候延長delay時間,可增強效果
}
//漸暗過程:不斷設置TA0CCR2的值,使翻轉的時間變短,改變PWM的占空比
for(i=PWMPeriod;i>0;i-=1)
{
TA0CCR2=i;
delay_nms(4-(i/500)); //占空比變化的延時,調整延遲時間可改變呼吸燈變暗的速度
//在暗的時候延長delay時間,可增強效果
}
TA0CCR2=0; //確保燈暗
delay_nms(250); //時間長一點,增強視覺效果
}
}
文章摘錄於:http://blog.lehu.shu.edu.cn/879836630/A450185.html
