基于51单片机制作频率计-测脉冲数法

b43078ef18484e4f8717df5f4170a459.png

本文为LED-执棋困局,csdn原创首发。
> 发布人:LED-执棋困局
> 欢迎大家与LED-执棋困局相互点赞+关注+收藏+评论,也祝大家顺顺利利,平平安安。
> 我的格言是:“尽最大努力,做最好的自己!
版权声明:本文为CSDN博主「LCD-执棋困局」的原创文章。

目录

一、频率计简介

1.1频率计概述

1.2频率计组成

1.3频率计原理

1.4测量原理

二、仿真设计

2.1频率计仿真

2.2仿真展示

三、软件程序设计

3.1主程序程序设计

3.2定时器初始化程序设计

3.3中断程序设计

3.4计数程序设计

3.5数码管程序设计

四、提高测量精度

4.1结果展现

4.2测量误差

4.3提高精度


一、频率计简介

1.1频率计概述

数字频率计是计算机、通讯设备、音频视频等各领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量方波信号及其他各种单位时间内变化的物理量。在进行模拟、数字电路的设计、安装、调试过程中,由于其使用十进制数显示,测量迅速,精确度高等因素,经常要用到频率计。

1.2频率计组成

本文频率计为简易基础版,由定时器1中断服务模块、计数器0计数模块、数码管显示模块和主程序模块四个部分组成。

1.3频率计原理

本文频率计时钟频率为12MHZ,测量的脉冲频率可以自调。频率计以at89c51为核心,利用内部自带的定时器和计数器。每个at89c51内部自带2个定时器/计数器,可以通过编程方法来完成定时器和计数器的工作,让定时器每1ms中断一次,时间累加到1s时,暂停计数,TR0=0,每次定时器进入中断时,暂时关闭定时器1,能有效防止中断还没结束,下一个中断就来执行的情况,提高测量的精度,同时计数器T0计数,利用高8位TH0和低8位TL0计算出1s内的脉冲数/频率。

1.4测量原理

测量频率有两种方法,一个叫计数测量法(测量1s内脉冲数),另一种叫测量周期法(利用定时器测量周期,再利用f=1/T求出频率)。

前者适用于高频测量,后者适用于低频测量。

本文采用计数测量法

计数测量法如何计算频率?

频率f定义:单位时间内的脉冲数。

在t时间内测量到N个脉冲,则频率f=N/t,特殊情况下(t=1s),f=N。

如下图(定时器T0定时累加1s),f=50hz,则频率f=脉冲数N=1s/0.02s=50。

93b415de5e424832871e56b61ecefe70.png

二、仿真设计

2.1频率计仿真

如图所示,是在proteus软件频率计的仿真。由于要测量1s内的脉冲数,所以要接计数器T0的引脚INT0。

db7d7a6892d14affa128ca818aa3a374.png

d5a91eb8501e42779ec8a04dd63fa161.png

255c3834b93548dca34154515d0d2ead.png

2.2仿真展示

数码管线码a、b、c、d、e、f、g、DP接P0,由于P0口电流过小,驱动能力不足,所以一定要接排阻respack-8提高驱动能力,至于74HC245芯片也是提高驱动能力的,可以不用。而段码接到P2低4位。频率计接到计数器T0引脚INT0。

以上是我自己接的,大家也可以接其他引脚。

218ec6b184764237a31dd25896fda84a.png

三、软件程序设计

3.1主程序程序设计

主程序调用定时器T1和计数器T0初始化,在while(1)调用数码管显示服务模块。

/******************************************************************
功能:1s内脉冲数及频率的测量
******************************************************************/
#include <reg51.h>
#include "display.h"

void Timer0_Init();
void Timer1_Init();
void dis_service();

unsigned int cnd=0;//控制测量脉冲数时间变量
unsigned int num;//脉冲数变量

void main()
{
	Timer0_Init();
	Timer1_Init();
	EA=1;
	while(1)
	{
		dis_service();
	}
}

3.2定时器初始化程序设计

void Timer1_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	ET1=1;           //定时器1中断打开
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
}

3.3中断程序设计

1ms中断一次,要求测量时间为1s,所以定义变量cnd,让其累加到1000(中断1000次)后,开始计算脉冲数。计算脉冲数后,要将cnd、TH0、TL0清0,确保下次计算的正确性。

void T1_timer() interrupt 3 //1s测量脉冲数及频率
{
	TR1=0;
	cnd++;
	if(cnd>=1000)//1s
	{
		TR0=0;
		cnd=0;
		num=TH0*256+TL0;//脉冲数
		TH0=TL0=0;//重新赋予计数初值
		TR0=1;
	}
	display();
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TR1=1;
}

3.4计数程序设计

脉冲数从0开始测量,所以TL0、TH0初值为0。

void Timer0_Init(void)		//计数器T0
{
	TMOD &= 0xf0;			//设置计数器模式 0000 0101
	TMOD |= 0x05;			//设置计数器模式
	TL0 = 0;				//设置计数初始值
	TH0 = 0;				//设置计数初始值
	TF0 = 0;				//清除TF1标志
	ET0=1;          //计数器0中断打开
	TR0 = 1;				//计数器1开始计时
}

3.5数码管程序设计

用于显示数码管的每一位。

void dis_service()
{
	LEDBuf[0]=num/1000;
	LEDBuf[1]=num/100%10;
	LEDBuf[2]=num/10%10;
	LEDBuf[3]=num%10;
}

display.c

#include "display.h"

unsigned char code leddata[]={
	              0x3F, //0
	              0x06, //1
                0x5B, //2
	              0x4F, //3
	              0x66, //4																																																																		
	              0x6D, //5
	              0x7D, //6
	              0x07, //7
	              0x7F, //8
	              0x6F, //9
	              0x77, //A																																																																							
	              0x7C, //B
	              0x39, //C
	              0x5E, //D
	              0x79, //E
	              0x71, //F
	              0x76, //H
	              0x38, //L
	              0x37, //n
                0x3E, //u	
	              0x73, //P																																																																	
	              0x5C, //o
	              0x40, //-
	              0x00  //熄灭
                             };//数码管段码表

unsigned char LEDBuf[]={0,0,0,0};//缓冲区
unsigned char code PLACE_COOE[]={0xfe,0xfd,0xfb,0xf7};//位码
/******************************************************************************************
函数名:display
功能:数码管显示函数
参数:无
返回值:无
******************************************************************************************/
void display()
{
	static unsigned char i=0;
	switch(i)
	{
		case 0:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[0]];//段码
	    IO_PLACE=PLACE_COOE[0];//位码
      i++;
		  break;
		case 1:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[1]];//段码
	    IO_PLACE=PLACE_COOE[1];//位码
      i++;
		  break;
		case 2:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[2]];//段码
	    IO_PLACE=PLACE_COOE[2];//位码
      i++;
		  break;
		case 3:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[3]];//段码
	    IO_PLACE=PLACE_COOE[3];//位码
      i=0;
		  break;
	}
}

display.h

#ifndef __DISPLAY_H__
#define __DISPLAY_H__

#include <reg51.h>

#define IO_DIG   P0 //段码IO
#define IO_PLACE P2 //位码IO

#define N 4 //数码管个数

unsigned char code leddata[];//变量声明
extern unsigned char LEDBuf[];

void display();//数码管显示函数声明

#endif

四、提高测量精度

4.1结果展现

50hz:

5873e54f317840779fb7a3ab628a3ce8.png

100hz:

e2a4bcfd7b854e46a7a94f38b95e20e1.png

500hz:

184be1d169924ab1b73e269664cbb4ff.png

1000hz:

cb77f2995eb344e28ba9130f1fa615d8.png

4.2测量误差

4.2.1误差公式

本文测的是1s内的脉冲数,即为频率。

那频率计误差怎么求呢?其实很简单,就是先计算出实际值与理论值的差的绝对值,然后除于理论值,最后乘于100%。

误差=( |实际值-理论值| /实际值)×100%

4.2.2误差计算&结果

频率计测量50hz:

[(54-50)/54 ]×100%≈7.4%

频率计测量100hz:

[(108-100)/108]×100%≈7.4%

频率计测量500hz:

[(539-500)/539]×100%≈7.24%

频率计测量1000hz:

[(1077-1000)/1077]×100%≈7.15%

随着测量频率提高,误差有所降低。

4.3提高精度

1.选择更加稳定的信号,例如使用石英晶体振荡器产生的信号。

2.本文测量时间为1s,可以提高测量时间,在较长的时间,能测量更多的信号周期,从而减小误差。

3.在软件编程,在执行中断时,可以暂时关闭定时器T1,即TR1=0,在本次中断结束时再打开定时器T1,即TR1=1。

五、总结

本文讲述了关于频率计的测量方法之一的计数测量法,就是利用频率的定义(单位时间内的脉冲数)。还学会了频率计的相关原理,利用at89c51内部的定时器T0定时累加到1s,同时利用内部的计数器T1的高8位和低8位测量脉冲数,从而借助数码管模块来显示到数码管屏幕上。此外,我们还学会了如何计算误差和提高测量精度的方法。

hello!我是博主LED-执棋困局,下一文章—基于51单片机制作门铃,我们下期再见!你们的关注支持就是我的动力!

  • 15
    点赞
  • 119
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
数字频率计可以用来测量信号的频率,常用于无线电通信、音频处理等领域。下面是基于C51单片机的数字频率计设计的一些基本步骤。 1. 选择合适的计数器:计数器是用来计算输入信号周期的器件。C51单片机有多个计数器可供选择,其中比较常用的是定时器0和定时器1。在选择计数器时需要考虑输入信号的频率范围和计数器的计数范围。 2. 配置计数器模式:计数器有多种计数模式,包括定时器模式、计数器模式和脉冲宽度测量模式等。在数字频率计中,一般使用计数器模式。 3. 设置计数器初值:计数器初值决定了计数器的计数范围和分辨率。通常将计数器初值设置为0,然后开始计数。 4. 测量输入信号的周期:当计数器计数到最大值时,会自动溢出并重新从0开始计数。每当计数器溢出时,就说明输入信号的一个周期已经结束。通过统计溢出次数和计数器计数值,可以计算出输入信号的周期。 5. 计算输入信号的频率:输入信号的频率等于周期的倒数。通过将计数器计数值和溢出次数转换成单位时间内的计数次数,就可以计算出输入信号的频率。 6. 显示测量结果:将测量结果显示在数码管或LCD屏幕上,方便用户观察和记录。 以上是基于C51单片机的数字频率计设计的基本步骤,具体实现可以根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值