msp430测量频率为什么用测频法

2019-07-15 15:17发布

以前用51做频率计是一般都是用计数法,就是一秒内计上升沿或者下降沿的个数,个人觉得这样不但误差小而且简单,为什么到了430,一查频率计都是用的测频法,就是测一个脉冲的时间X2得到周期,再取倒得到频率,这是为什么啊,是有什么其他的原因吗?求解。另外我如果用计数法,用timerA做一个1秒的计时,然后用P1口的外部中断来记录下降沿的次数,如果我测频率的范围是10K到300K,那可定就要用到外部高速时钟了,那么请问我是TIMERA用ACLK, MCLK用外部时钟这样可以吗,P1口的外部中断可以承受那么高的频率吗,是不是主系统时钟选了8M的外部时钟,那么执行指令的时间就是1/8M啊,口才不好,还请见谅
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
gsdafs
2019-07-15 23:39
版主V5,多多关照哈,
因为我测频率范围在10K~300K所以觉得用测脉冲的方法的话会不会误差太大,我用计数法做出来精度还可以,就是最高频率只能测到32K左右不知道为什么,郁闷啊    下面是程序
#include<msp430.h>
#define uchar unsigned char
#define uint unsigned int 
#include"Cry12864.h"
unsigned long int count,data;
uchar TimerA;
uchar fy[7];
void TimerA_Init(void)
{
  TACTL = TASSEL_1 + ID0 + TACLR ; //ACLK=32768Hz ,清除tar ,2分频
  CCTL0 = CCIE; //
  CCR0 = 819;   // (1/32768)*819 =20 ms ??
  TACTL |= MC0; //增计数   
}
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 Disply(uint data)
{
  
    fy[6]=data/1000000;
    fy[5]=data/100000%10;//(frequency-1000000*fy[6])/100000;
    fy[4]=data/10000%10;//(frequency-1000000*fy[6]-100000*fy[5])/10000;
    fy[3]=data/1000%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4])/1000;
    fy[2]=data/100%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3])/100;
    fy[1]=data/10%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3]-100*fy[2])/10;
    fy[0]=data%10;
   
      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]);
}
void main( void )

   WDTCTL = WDTPW+WDTHOLD; 
  &nbsp1IE |= BIT1;//使能
  &nbsp1IES |= BIT1;//下降沿触发
  &nbsp1IFG = 0X00;//清空中断标志(必须软件清除)
   InitSys();//                                           这两个函数我是想让TA时钟用aclk MCLK用外部8M的外部时钟,我试了一下好像是开不开外部时钟都没                                      有什么影响,因外我把InitSys()屏蔽掉以后对测量结果没什么影响,是因为外部中断的频率有限制吗?而且就只能最高到32K是跟ACLK有什么联系吗?
   TimerA_Init();
   Ini_Lcd();
  
   _EINT();//开启全局中断 
   //uchar key = 0;
   Lcd12864PutData(0,0,'d');
  while(1)
   {
    // Display(fr);
     
    fy[6]=data/1000000;
    fy[5]=data/100000%10;//(frequency-1000000*fy[6])/100000;
    fy[4]=data/10000%10;//(frequency-1000000*fy[6]-100000*fy[5])/10000;
    fy[3]=data/1000%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4])/1000;
    fy[2]=data/100%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3])/100;
    fy[1]=data/10%10;//(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3]-100*fy[2])/10;
    fy[0]=data%10;
   
      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]);
     
   }
  
   
}
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA0_ISR()

  TimerA--;
  if(TimerA==0)
  {
    TimerA=20;
   &nbsp1IE &= ~BIT1;//关闭使能
   //&nbsp2IFG = 0XFF;
    data=count;
    count = 0;
   // Display(data);                                           还有这个函数我把它写在这就会报错  不知道为啥子??????
   &nbsp1IE |= BIT1;//使能
   //&nbsp1IFG = 0X00;
  }
}
#pragma vector =&nbspORT1_VECTOR
__interrupt void&nbsp1_interrupt(void)

  count++;
 &nbsp1IFG = 0X00;//清空中断标志(必须软件清除)
}
水平有限 程序写的烂  见笑了

一周热门 更多>