各位大佬 小弟做了個測頻率的東西 單片機測得的頻率嚴重出錯啊 可以告訴我為什么么
- //#include"reg52.h" /* 調用頭文件,單片機內部寄存器都定義在此,用的時候需要先調用 */
- #include"LCD1602.H"
- #include <NEW_8051.h>
- UINT8 CounterCnt; /* 計數器次數 */
- UINT8 FreResultFlag; /* 頻率計計算結果標志 */
- /******************************** 引腳定義 **************************************
- 單片機 NE555
- P35 OUT
- ********************************************************************************/
- /*******************************************************************************
- * 函 數 名 : Init_Timer
- * 描 述 : 初始化定時器T0,計數器T1.
- * 輸 入 : 無.
- * 返 回 : 無.
- ********************************************************************************/
- void Init_Timer(void)
- {
- TMOD |= 0x51;
- /* T0工作在定時器模式1,16位定時器,T1工作在計數器模式 */
- TH0 = ( 65536 -50000 ) / 256; /* T0定時器初值,定時50ms */
- TL0 = ( 65536 -50000 ) % 256;
- TH1 = 0; /* T1從0開始計數 */
- TL1 = 0;
- ET0 = 1; /* 定時器T0中斷打開 */
- // ET1 = 1; /* 定時器T1中斷打開 */
- EA = 1; /* 總中斷打開 */
- // PT1 = 1; /* 定義T1為高優先級 */
- TR0 = 1; /* T0開關打開 */
- TR1 = 1; /* T1開關打開 */
- }
- /*******************************************************************************
- * 函 數 名 : Timer0
- * 描 述 : 中斷程序,定時時間到后重新賦值開始定時,同時將LED的狀態取反.
- * 輸 入 : 無.
- * 返 回 : 無.
- ********************************************************************************/
- void Timer0(void) interrupt 1
- {
- static UINT8 Temp;
- TH0 = ( 65536 -50000 ) / 256; /* 重新賦值 */
- TL0 = ( 65536 -50000 ) % 256;
- Temp++;
- if( Temp == 20 ) /* 大概一秒計算一次 */
- {
- Temp = 0;
-
- TR0 = 0; /* 關閉定時器T0,T1 */
- TR1 = 0;
- FreResultFlag = 1; /* 準備計算頻率 */
- }
- }
- /*******************************************************************************
- * 函 數 名 : Timer1
- * 描 述 : 計數器中斷程序.
- * 輸 入 : 無.
- * 返 回 : 無.
- ********************************************************************************/
- void Timer1(void) interrupt 3
- {
- CounterCnt++; /* 計算脈沖個數 */
- }
- /*******************************************************************************
- * 函 數 名 : DisplayFre
- * 描 述 : LCD1602顯示頻率.
- * 輸 入 : UINT32 PulseCnt:
- * 脈沖數.
- * 返 回 : 無.
- ********************************************************************************/
- void DisplayFre( UINT32 PulseCnt )
- {
- UINT8 i;
- UINT8 DisplayBuf[6];
- for( i = 0; i < 5; i++ ) /* 計算1-5位的每位數據 */
- {
- DisplayBuf[i] = PulseCnt % 10 + 0x30; /* 轉成成1602可以顯示的數值 */
- PulseCnt = PulseCnt / 10;
- }
- DisplayBuf[5] = PulseCnt + 0x30; /* 計算第6位數據 */
- for( i = 5; i > 0; i-- ) /* 處理高位為0時候的情況 */
- {
- if( DisplayBuf[ i ] == 0x30 )DisplayBuf[ i ] = 0x20;/* 檢測到高位為 0,不顯示高位,空格代替 */
- else break;
- }
- LCD1602_SetDisplayPosition( 7,2 ); /* 設置顯示位置 */
- for( i = 5; i != 0xFF; i-- )
- LCD1602_WriteData(DisplayBuf[i]); /* 顯示頻率計字符 */
- }
- /*******************************************************************************
- * 函 數 名 : main
- * 描 述 : 主程序.
- * 輸 入 : 無.
- * 返 回 : 無.
- ********************************************************************************/
- void main(void)
- {
- UINT32 FreNum; /* 計算頻率次數 */
- Init_Timer(); /* 初始化定時器 */
- LCD1602_Init(); /* 初始化LCD1602 */
- LCD1602_SetDisplayPosition(0,1); /* 設置第一行顯示位置 */
- LCD1602_WriteString("FREQUENCY METER"); /* 設置頻率計字符 */
- LCD1602_SetDisplayPosition(0,2); /* 設置第二行顯示位置 */
- LCD1602_WriteString("FRE: Hz"); /* 設置FRE: HZ字符 */
- while(1)
- {
- if( FreResultFlag ) /* 計算頻率 */
- {
- FreNum = ( CounterCnt * 65536 + TH1 * 256 + TL1); /* 計算1秒后的脈沖個數 */
- TH1 = 0; /* 清計數次數 */
- TL1 = 0;
- FreResultFlag = 0; /* 清標志 */
- // CounterCnt = 0;
- TR1 = 1;
- TR0 = 1; /* 開定時器 */
- }
- DisplayFre( FreNum );
- }
- }
復制代碼 |