msp430f5529捕獲例程
前段時間需要用MSP430F5529,因為是個菜鳥,很多都不會,遇到了很多問題,百度好多東西都是千篇一律的,好些東西都是Ctrl+c,Ctrl+v。而有很多老鳥,可能說不定也是菜鳥一個呢!!一副為了你好的樣子,你看手冊啊,手冊不會嗎?你用示波器打啊,示波器不會嗎?你什么單位啊,示波器都沒有嗎?所以才打算在把這個捕獲模式搞清楚后發(fā)一篇自己的心得吧.。發(fā)了半天牢騷,正文如下。
要用捕獲我們得搞清楚捕獲的原理是什么,捕獲的原理是通過計數(shù)器,記錄從使能開始到設(shè)定的沿的數(shù)值(也可以理解為時間)。在設(shè)定為捕獲模式下,使能過后,計數(shù)器TA0R就開始計數(shù)了,在單步調(diào)試過程中,可以通過觀察CCS里面的Registers各個寄存器的變化來深入的理解。
上面分別是CCS單步調(diào)試的時候的寄存器圖和MSP430F5529的引腳圖,根據(jù)引腳圖我們可以知道,關(guān)于定時器TA0.0相關(guān)的功能在P1.1引腳上,以此類推對應(yīng)起來。這次我用到的是P1.4引腳,也就是TA0.3,選擇了TA0.3那么,相對應(yīng)的捕獲到的時間的值,是在TA0CCTL3那里。
然后我們可以通過寫TA0CCTL3里面的寄存器,來選擇模式,關(guān)于什么模式下是什么作用,可以通過頭文件,看頭文件里面的注釋,也可以通過看上圖Register中Value一欄的值,如:CM下的00-CM_0功能是Capture mode 1(捕獲模式1)。
在單步調(diào)試的過程中,我們可以看到,計數(shù)器計數(shù)的過程中,TA0R每一個單步都會變,在捕獲到設(shè)定好的邊沿時,TA0R的值會賦給TA0CCR3,然后TA0R再接著計數(shù)。
單步調(diào)試的大概思路就是這樣的,我們接下來通過觀察Expressions里面的值,來看我們捕獲到的時間。
我這里沒有連超聲模塊,就沒有再次單步調(diào)試了,但是之前調(diào)試的過程是這樣的。按照這個思路來應(yīng)該沒有問題。
根據(jù)超聲模塊HC_SR04的時序圖可以知道:
超聲模塊內(nèi)部發(fā)出信號需要先10us的高電平,最后我們需要捕捉一個上升沿和下降沿就好了,就可以得出時間了。
#include
unsigned int k=0;
unsigned int LastCCR1; //上一次高電平持續(xù)的時間,和距離正相關(guān)
unsigned int dat[20]; //通過數(shù)組備份采集到的數(shù)據(jù)
void HC_SR04Init();
void HC_SR04Start();
void TimeGetInit();
void main()
{
HC_SR04Init(); //初始化超聲模塊HC_SR04
TimeGetInit(); //初始化計數(shù)捕獲引腳,模式等
_EINT();
while(1)
{
HC_SR04Start();
LPM0;
}
}
/*初始化HC_SR04Init()模塊*/
void HC_SR04Init()
{
P1DIR|=BIT2;
}
/*開始超聲發(fā)送*/
void HC_SR04Start()
{
P1OUT|=BIT2;
_delay_cycles(12); //至少持續(xù)10us的高電平
P1OUT&=~BIT2;
}
/*初始化捕獲模式,獲取時間*/
void TimeGetInit()
{
P1DIR&=~BIT4;
P1SEL|=BIT4;
TA0CTL=TASSEL_2+ID_0+MC_2+TACLR;
TA0CCTL3=CM_1+SCS+CAP+CCIE+CCIS_0;
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
_DINT(); //關(guān)中斷
static unsigned char times=1;
static unsigned char i=0;
unsigned char j;
unsigned int t;
if(times==1)
{
LastCCR1=TA0CCR3; //記錄下上次CCR3的值
TA0CCTL3&=~CM_1; //清上升沿捕獲
TA0CCTL3|=CM_2; //改為下降沿捕獲
times++;
}
if(times==0)
{
if(i<20) //把采集到的20次的值都放到數(shù)組中
{
dat[i]=TA0CCR3-LastCCR1;;
i++;
}
if(i>=20) //為了防止誤差,排序把采集到的兩頭兩尾的值去掉,取中間的平均值
{
for(i=0;i<20;i++)
{
for(j=0;j<20-i;j++)
{
if(dat[j]>dat[j+1])
{
t=dat[j];
dat[j]=dat[j+1];
dat[j+1]=t;
}
}
}
t=0;
for(i=7;i<12;i++)
{
t=t+dat[i];
}
k=t/5;
i=0;
}
TA0CCTL3&=~CM_2; //清除下降沿觸發(fā)
TA0CCTL3|=CM_1; //變?yōu)樯仙赜|發(fā)
times++; //改變times的值
}
times&=0x01; //times>1時清0
LPM0_EXIT; //退出低功耗模式
TA0CCTL3&=~CCIFG; //清除中斷響應(yīng)標(biāo)志
_EINT(); //開中斷
}
這個沒有具體的算時間,但是我根據(jù)距離S=V*(t/2)大概算了下,這里時間粗略為:t=k*1us。像那么回事,這里只是講下MSP430F5529用捕獲的方法,如果要精確的話,還需要校準(zhǔn)時鐘頻率等等。