以前用51做频率计是一般都是用计数法,就是一秒内计上升沿或者下降沿的个数,个人觉得这样不但误差小而且简单,为什么到了430,一查频率计都是用的测频法,就是测一个脉冲的时间X2得到周期,再取倒得到频率,这是为什么啊,是有什么其他的原因吗?求解。另外我如果用计数法,用
timerA做一个1秒的计时,然后用P1口的外部中断来记录下降沿的次数,如果我测频率的范围是10K到300K,那可定就要用到外部高速时钟了,那么请问我是TIMERA用ACLK, MCLK用外部时钟这样可以吗,P1口的外部中断可以承受那么高的频率吗,是不是主系统时钟选了8M的外部时钟,那么执行指令的时间就是1/8M啊,口才不好,还请见谅
因为我测频率范围在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;
 1IE |= BIT1;//使能
 1IES |= BIT1;//下降沿触发
 1IFG = 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;
 1IE &= ~BIT1;//关闭使能
// 2IFG = 0XFF;
data=count;
count = 0;
// Display(data); 还有这个函数我把它写在这就会报错 不知道为啥子??????
 1IE |= BIT1;//使能
// 1IFG = 0X00;
}
}
#pragma vector = ORT1_VECTOR
__interrupt void 1_interrupt(void)
{
count++;
 1IFG = 0X00;//清空中断标志(必须软件清除)
}
水平有限 程序写的烂 见笑了
一周热门 更多>