测频(ps:来自论坛大佬,但具体出处忘记了,若涉及侵权立马删)
单片机源程序如下:
- #include "msp430f449.h"
- #include "string.h"
- #include "stdio.h"
- #include "time.h"
- #include "lcd.c"
- #define CPUF ((double)7995392)
- #define delay_us(x) __delay_cycles((long)(CPUF*(double)x/1000000))
- #define delay_ms(x) __delay_cycles((long)(CPUF*(double)x/1000))
- #define delay_s(x) __delay_cycles(CPUF*x)
- long Cap_num=0;
- int Cap_star=0;
- int Cap_Ns=0;
- long OV_Ns=0;
- long Ns=0;
- long Nx=0;
- long f=0;
- int flag_Capend;
- /*char str1[20]={"频率: "};
- char str2[];
- char str3[]={" HZ"};*/
- uchar lcd_buf[6]={0,0,0,0,0,0};
- void initclk()
- {
- SCFI0|=FN_4;
- SCFQCTL=121; //系统时钟倍频达到8M
- FLL_CTL0=DCOPLUS+OSCCAP1;
- }
- int main( void )
- {
- // Stop watchdog timer to prevent time out reset
- WDTCTL = WDTPW + WDTHOLD;
- initclk(); //时钟初始化
- lcd_init();
- //Display_string(0,0,"是");
- Display_string(3,0,"频率:"); //先列后行才是对的,上面一行地址是错的;
- //Display_string(10,1,"HZ"); //该显示函数自动从第0列开始 ,所以会被后来的数据覆盖,有待解决
- _EINT(); //开总中断
- Preset_gate(); //预置闸门
- Cap_signal(); //捕获被测信号
- while(1)
- {
- if(flag_Capend==2)
- {
- _DINT(); //此处关总中断防止计数值改变
- Ns=Ns+OV_Ns*500;
- f=Nx/(Ns/3980000); //理论上应是1/4M,但定时器的频率达不到那么高
-
- /* 此种显示方法会导致单片机运行崩溃,是软件原因还是程序原因不明。
- sprintf(str2,"%1.f",f); //%1.f确定f的精度即位宽,以至于不会将str1[]填满,导致str3[]装不进去
- strcat(str1,str2); //strcat函数将两个字符数组连接起来
- strcat(str1,str3);
- Display_string(0,0,str1); //直接将数组内的内容显示
- */
- lcd_buf[0]=(uchar)(f/100000%10)+0x30;
- lcd_buf[1]=(uchar)(f/10000%10)+0x30;
- lcd_buf[2]=(uchar)(f/1000%10)+0x30;
- lcd_buf[3]=(uchar)(f/100%10)+0x30;
- lcd_buf[4]=(uchar)(f/10%10)+0x30;
- lcd_buf[5]=(uchar)(f%10)+0x30;
- Display_string(6,1,lcd_buf);
- // Display_char(7,1,'H');
- // Display_char(8,1,'Z');
- Cap_num=0;
- OV_Ns=0;
- flag_Capend=0;
- TACCTL1|=CCIE;
- TACCTL2|=CCIE;
- TACCTL2|=TAIE;
- TBCCTL1|=TAIE;
- _EINT();
- }
- }
-
- }
- /****** 定时器 A1,2 中断 处理 ***********/
- #pragma vector = TIMERA1_VECTOR
- __interrupt void Timer_A1 (void)
- {
- if(flag_Capend==1) //实际闸门关闭
- {
- lcd_buf[0]=0;lcd_buf[1]=0;lcd_buf[2]=0;lcd_buf[3]=0;lcd_buf[4]=0;lcd_buf[5]=0;
- TACCTL1&=~CCIE;
- TBCCTL1&=~TAIE;
- flag_Capend=2;
- Ns=TAR;
- Nx=Cap_num-1;
- TACCTL1&=~CCIE;
- TACCTL2&=~CCIE;
- TACCTL2&=~TAIE;
- TBCCTL1&=~TAIE;
- _DINT(); //此处关总中断无用,在中断发生时,主函数中的SR入栈保存,
- //在中断函数中用的新的SR,退出中断后,这个SR是要被主函数以前的SR出栈覆盖的,
- //所以说在这个中断里面改变GIE,并不能改变退出中断以后的GIE。
- //TACCR2=0;
- }
- else
- {
- switch(TAIV)
- {
- case 2: if(Cap_num==0) //第一个被测信号上升沿
- {
- TBR=0;
- TBCTL|=MC_1; //开启1s实际闸门,增计数模式
- TAR=0; //标准信号计数清零,标准信号开始计数
- TACTL|= TAIE; //开中断,
- if(flag_Capend==0)
- Cap_num++;
- }
- else
- {
- // Cap_Ns=TAR;
- if(flag_Capend==0)
- Cap_num++; //被测信号计数Nx
- }
- break;
-
- case 10: //TACCR2=0;
- if(flag_Capend==0);
- OV_Ns++;
- break;
- default: break;
- }
- }
- }
- /****** 定时器 B 中断 处理 ***********/
- #pragma vector = TIMERB0_VECTOR
- __interrupt void Timer_B (void)
- {
- flag_Capend=1;
- }
复制代码
所有资料51hei提供下载:
测频.rar
(33.08 KB, 下载次数: 13)
|