×
嵌入式 > 技术百科 > 详情

msp430单片机测量频率

发布时间:2020-06-20 发布时间:
|
/*******************************************************

Author: Made by Xura
Date: 2008.8.28
程序描述:利用Timer_A捕获脉冲宽度
利用MSP430单片机定时器A和捕获/比较功能模块结合使用,实现脉冲宽度的测量
程序用到了定时器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]; //==用于存放频率显示数据==
uint pd[7]; //==用于存放周期显示数据==
uint wh[6]; //==用于存放脉宽显示数据==
const unsigned char zhouqi[]={"周期为:(us) "}; 
const unsigned char us[]={"us "};
const unsigned char pinlv[]={"频率为:(Hz) "};
const unsigned char hz[]={"HZ "};
void process(void); //==函数声明==
void delay();     //==延时函数==
void InitSys();     //==初始化时钟==
/******************************************************************
主函数
******************************************************************/
int main( void )
{
  WDTCTL = WDTPW + WDTHOLD; //==关狗==
    
  InitSys(); //==初始化时钟,SMCLK,MCLK均为8M==
  
  P1DIR&=~BIT2;
  P1SEL = BIT2; //==设置P1.2端口为功能模块使用,即:做捕获源==
  TACTL = TASSEL_2+ID_3+TACLR+TAIE+MC1;//==定时器A时钟信号选择SMCLK,8分频,同时设置定时器A计数模式为连续增计模式==
  
  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();
      }
  
}                    


/*******************************************************
初始化时钟
*******************************************************/
void InitSys() 

   unsigned int i; 
 //--- 使用XT2振荡器 --- 
   BCSCTL1&=~XT2OFF; //==打开XT2振荡器== 
   do 
   { 
   IFG1 &= ~OFIFG; //==清除振荡器失效标志== 
   for (i = 0xFF; i > 0; i--); //==延时,等待XT2起振== 
  } 
  while ((IFG1 & OFIFG) != 0); //==判断XT2是否起振== 
  BCSCTL2 =SELM_2+SELS; //==选择MCLK、SMCLK为XT2,8M==  

/*******************************************************
延时函数
*******************************************************/
void delay() 
{
  unsigned int i;
  unsigned int j=10;
  for(i=10;i>0;i--)
  {
    while(j--);
  }
}
/********************************************************************
数据处理 
********************************************************************/
void process(void)
{
  while(end   //while(endstart
    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;
}
/*******************************************************************
中断处理函数
*******************************************************************/
#pragma vector=TIMERA1_VECTOR //==定时器A中断处理==
__interrupt void timer_a(void)

 switch(TAIV) //==向量查询==
  { case 2: //==捕获中断==
       if(CCTL1&CM0) //==捕获到上升沿==
         { 
           CCTL1=(CCTL1&(~CM0))|CM1; //==更变设置为下降沿触发==


           start=TAR; //==记录初始时间==           
         }
    
       else if (CCTL1&CM1) //==捕获到下降沿==
        { 
           CCTL1=(CCTL1&(~CM1))|CM0; //==更变设置为上升沿触发==
           end=TAR; //==用start,end,overflow计算脉冲宽度==
           
        } 
       break;
                    
    default:
       break;
  } 
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
NTMD6N03R2G的技术参数