各位大佬 小弟做了个测频率的东西 单片机测得的频率严重出错啊 可以告诉我为什么么
- //#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 );
- }
- }
复制代码 |