发布网友
共1个回答
热心网友
1.实验任务
利用51单片机的T0、T1的定时计数器功能,来完成对输入的信号进行频率计数,计数的频率结果通过8位动态数码管显示出来。要求能够对0-250KHZ的信号频率进行准确计数,计数误差不超过±1HZ。
2.电路原理图
见插图
3.程序设计内容
(1).定时/计数器T0和T1的工作方式设置,由图可知,T0是工作在计数状态下,对输入的频率信号进行计数,但对工作在计数状态下的T0,最大计数值为fOSC/24,由于fOSC=12MHz,因此:T0的最大计数频率为250KHz。对于频率的概念就是在一秒只数脉冲的个数,即为频率值。所以T1工作在定时状态下,每定时1秒中到,就停止T0的计数,而从T0的计数单元中读取计数的数值,然后进行数据处理。送到数码管显示出来。
(2).T1工作在定时状态下,最大定时时间为65ms,达不到1秒的定时,所以采用定时50ms,共定时20次,即可完成1秒的定时功能。
4.C语言源程序
/******************************************************************************
* 定时器+计数器测频
*
* file: frequency.c
* name: zhzhchang
* time: 2010.3.17
* V 1.0
* blog:http://blog.csdn.net/zhzht19861011
* Nots: 本程序定义6个数码管,经过实测,在200HZ~50KHZ时结果较准确,误差小于0.4%,
* 50KHZ以上频率未进行测量.据资料表明,可以测量到120KHZ,本程序未证明.
*********************************************************************************/
#include<reg52.h>
bit int_flag; //定时器0 1S到标志位
unsigned char volatile int_count; //定时器0中断次数
unsigned char volatile T1count; //定时器1中断次数
unsigned char code dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值01234567
unsigned long sum; //1S内脉冲总个数
unsigned char led[6]; //LED显示缓存
///////////////软件延时/////////////
void delay(unsigned int cnt)
{
while(--cnt);
}
///定时器0初始化
void init_t0(void)
{
TMOD=(TMOD&0xF0)||0x01; //定时器0工作于方式1
TH0=(65536-50000)/256; //定时50ms
TL0=(65535-50000)%256;
}
// 定时器1初始化
void init_t1(void)
{
TMOD=(TMOD&0x0F)|0x50; //timer 1 for count
TH1 =0x00;
TL1 =0x00;
}
//显示
void disp(void)
{
unsigned char i;
for(i=0;i<6;i++)
{
P0=dofly[(led[i])];//取显示数据
P2=5-i; //取段码
delay(100); //扫描间隙延时,根据单片机调整,延时1ms即可
}
}
///////////////////////////////////////////////////////
void main (void)
{
EA=1; //开总中断
init_t0(); //初始化定时器
init_t1();
TR0=1; //定时器开始工作
TR1=1;
ET0=1; //开T0中断
while(1)
{
if(int_flag==1)
{
int_flag=0;
sum=TL1+TH1*256+T1count*65536; //计算1秒内的脉冲个数
//以下将数据格式化,转成LED可显示的BCD码
led[0]=sum%10; //最低位
sum=sum/10;
led[1]=sum%10; //第二位
sum=sum/10;
led[2]=sum%10;
sum=sum/10;
led[3]=sum%10;
sum=sum/10;
led[4]=sum%10;
led[5]=sum/10;
int_count=0x00;
T1count=0;
TH1=0x00;
TL1=0x00;
TR1=1;
}
disp();
}
}
//定时器0中断服务程序
void int_t0(void) interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
int_count++;
if(int_count==20)
{
TR1=0;
int_flag=1;
int_count=0x00;
}
}
//定时器1中断服务程序
void int_t1(void) interrupt 3
{
T1count++;
}
别说你的设计要求用汇编啊!!!
不过既然是课程设计,我这个只是给你参考,你自己一定要弄懂,变成自己的。我实测过,程序没问题,但用到你的硬件上可能需要改一下,因为你的硬件数码管不一定和我的硬件接法一样,但整体思路我都给你了。