測頻(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)
2018-5-20 09:48 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|