msp430單片機測量頻率
Author: Made by Xura
Date: 2008.8.28
程序描述:利用Timer_A捕獲脈沖寬度
利用MSP430單片機定時器A和捕獲/比較功能模塊結(jié)合使用,實現(xiàn)脈沖寬度的測量
程序用到了定時器A的CCI1A端口(MSP430F14X的P1.2引腳)作捕獲外部輸入
的脈沖電平跳變,start,end,兩個個變量來計算脈沖寬度
*******************************************************/
#include "msp430x14x.h"
#include "lcd12864.h"
uint start,end;
uint width; //==用于存放脈寬==
uint period; //==用于存放周期==
uint frequency; //==用于存放頻率==
uint fy[7]; //==用于存放頻率顯示數(shù)據(jù)==
uint pd[7]; //==用于存放周期顯示數(shù)據(jù)==
uint wh[6]; //==用于存放脈寬顯示數(shù)據(jù)==
const unsigned char zhouqi[]={"周期為:(us) "};
const unsigned char us[]={"us "};
const unsigned char pinlv[]={"頻率為:(Hz) "};
const unsigned char hz[]={"HZ "};
void process(void); //==函數(shù)聲明==
void delay(); //==延時函數(shù)==
voidInitSys(); //==初始化時鐘==
/******************************************************************
主函數(shù)
******************************************************************/
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; //==關(guān)狗==
InitSys(); //==初始化時鐘,SMCLK,MCLK均為8M==
P1DIR&=~BIT2;
P1SEL = BIT2; //==設(shè)置P1.2端口為功能模塊使用,即:做捕獲源==
TACTL = TASSEL_2+ID_3+TACLR+TAIE+MC1;//==定時器A時鐘信號選擇SMCLK,8分頻,同時設(shè)置定時器A計數(shù)模式為連續(xù)增計模式==
CCTL1 = CM_1+SCS+CAP+CCIE; //==輸入上升沿捕獲,CCI0A為捕獲信號源==
_EINT(); //==開全局中斷允許==
Ini_Lcd(); //==初始化液晶==
Clear_GDRAM(); //==清屏==
Disp_HZ(0x80,zhouqi,8);
Disp_HZ(0x88,pinlv,8);
while(1)
{
process();
Write_Cmd(0x90);//==寫地址==
Write_Data(0x30+pd[6]);
Write_Data(0x30+pd[5]);
Write_Data(0x30+pd[4]);
Write_Data(0x30+pd[3]);
Write_Data(0x30+pd[2]);
Write_Data(0x30+pd[1]);
Write_Data(0x30+pd[0]);
Write_Cmd(0x98);//==寫地址==
Write_Data(0x30+fy[6]);
Write_Data(0x30+fy[5]);
Write_Data(0x30+fy[4]);
Write_Data(0x30+fy[3]);
Write_Data(0x30+fy[2]);
Write_Data(0x30+fy[1]);
Write_Data(0x30+fy[0]);
delay();
}
}
/*******************************************************
初始化時鐘
*******************************************************/
voidInitSys()
{
unsignedinti;
//--- 使用XT2振蕩器 ---
BCSCTL1&=~XT2OFF;//==打開XT2振蕩器==
do
{
IFG1&=~OFIFG;//==清除振蕩器失效標(biāo)志==
for(i=0xFF;i>0;i--);//==延時,等待XT2起振==
}
while((IFG1&OFIFG)!=0);//==判斷XT2是否起振==
BCSCTL2=SELM_2+SELS;//==選擇MCLK、SMCLK為XT2,8M==
}
/*******************************************************
延時函數(shù)
*******************************************************/
voiddelay()
{
unsignedinti;
unsignedintj=10;
for(i=10;i>0;i--)
{
while(j--);
}
}
/********************************************************************
數(shù)據(jù)處理
********************************************************************/
void process(void)
{
while(end
width = end-start; //==實際脈沖寬度的計算==
period = 2* width;
frequency=1000000/period;
pd[6]=period/1000000;
pd[5]=(period-1000000*pd[6])/100000;
pd[4]=(period-1000000*pd[6]-100000*pd[5])/10000;
pd[3]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4])/1000;
pd[2]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4]-1000*pd[3])/100;
pd[1]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4]-1000*pd[3]-100*pd[2])/10;
pd[0]=period%10;
fy[6]=frequency/1000000;
fy[5]=(frequency-1000000*fy[6])/100000;
fy[4]=(frequency-1000000*fy[6]-100000*fy[5])/10000;
fy[3]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4])/1000;
fy[2]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3])/100;
fy[1]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3]-100*fy[2])/10;
fy[0]=frequency%10;
}
/*******************************************************************
中斷處理函數(shù)
*******************************************************************/
#pragma vector=TIMERA1_VECTOR //==定時器A中斷處理==
__interrupt void timer_a(void)
{
switch(TAIV) //==向量查詢==
{ case 2: //==捕獲中斷==
if(CCTL1&CM0) //==捕獲到上升沿==
{
CCTL1=(CCTL1&(~CM0))|CM1; //==更變設(shè)置為下降沿觸發(fā)==
start=TAR; //==記錄初始時間==
}
else if (CCTL1&CM1) //==捕獲到下降沿==
{
CCTL1=(CCTL1&(~CM1))|CM0; //==更變設(shè)置為上升沿觸發(fā)==
end=TAR; //==用start,end,overflow計算脈沖寬度==
}
break;
default:
break;
}
}
評論