|
部分程序,完整程序请下载 /****************************** (C) COPYRIGHT 2013 **************************
* 文 件 名 : NE555频率计.C
* 版 本 : V1.0
* 日 期 : 2013/08/20
* 主 控 MCU : STC89C52
* 主 频 : 12MHz
* 编 译 器 : Keil C51 V4.22
* 描 述 : NE555产生方波,单片机采集方波频率后,显示在LCD1602上.
* 在本设计方案中,T0工作在定时状态下,设定T1工作在计数状态,
T1计数
* 器对输入信号进行计数,信号的频率就是每秒钟信号的脉冲个数,
T0工
* 作在定时状态下,定时时间为1秒。每定1秒钟到,就停止T1的计数,
然
* 后从T1的计数单元中读取计数的数值,即完成了信号的频率测量.
*********************************************************************************/
//#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(); /* 初始化定时器 */
// P27 = 1;
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 );
}
}
|
|