51数显简易频率计设计

51数显简易频率计设计

设计实验条件

电路及程序设计:Proteus8.7、Keil4 仿真及编程环境

设计任务及基本要求

自行设计输入电路,测量信号类型方波、正弦波、三角波等常规周期信号; 输入信号频率范围:10HZ—1MHZ,频率量程自行设定;频率信号的实时显示。其他附加功能自行创新设计。
1、总体方案设计
(1)系统总体结构
(2)芯片选择
(3)定时与计数方式
2、硬件电路设计
(1)AT89C51 单片机最小系统
(2)AT89C51 单片机波形产生及测量电路设计
(3)显示电路与 AT89C51 单片机接口电路设计
(4)键盘电路与 AT89C51 单片机接口电路设计
3、软件设计
(1)程序框图
(2)波形产生程序框图
(3)波形频率测量程序框图
(4)键盘输入
(5)显示程序框图
4、调试与测试结果分析
(1)实验系统连线图
(2)程序调试
(3)实验结果分析
5、程序清单和系统原理图

设计报告

前言

课题背景

频率计是一种基础测量仪器,到目前为止已有 30 多年的发展历史。由于电子器件之间的互相干扰,从而影响频率计的精度,同时由 于其体积较大,已经不适应电子设计的发展要求。随着科学技术的发展,频率计也日益发展。目前已经有操作方便、量程(足够)宽、可靠性高的频率计;也有适应高分辨率、高精度、高稳定度、高测量速度的频率计。
频率计的基本原理是用一个频率稳定度高的频率源作为基准时钟,对比测量其他信号的频率。通常情况下计算每秒内待测信号的脉冲个数,此时我们称闸门时间为 1 秒。频率计是用数字显示被测信号 频率的仪器,被测信号可以是正弦波,方波或其它周期性变化的信号。

设计意义

单片机是一门发展极快,应用方式极其灵活的使用技术。单片机频率计以其可靠性高、体积小、价格低、功能全等优点,广泛地应用于各种智能仪器中。另外,在电子技术中,频率是最基本的参数之一, 并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此频率计在教学、科研、测量仪器、工业控制等方面都有较广泛的应用。

设计主体

总体方案设计

本课程设计的总体思路是以 AT89S51 微控制器为主控,结合外设及硬件电路实现对输入信号频率的测量。由外部中断 1 引脚接入被测信号,定时 1 秒计信号的下降沿个数作为被测信号的频率,并由 LED 数码管进行输出显示。51数显简易频率计设计

硬件电路设计

最小系统设计

(1)时钟电路:选取 12MHz 的石英晶振,机器周期为 1us,电容选取 33pf 的瓷片电容,时钟电路两输出分别接到单片机的 19 号引脚 XTAL1 和 18 号引脚 XTAL2;
(2)复位电路:AT89S51 复位信号为高电平有效,对应引脚为 9 号引脚 RST;
(3)电源电路:40 引脚 VCC 接 5V 电源正极,20 引脚 GND 接电源负极。
51数显简易频率计设计

波形处理及测量电路设计

由于输入信号类型及幅值不同,在此设计运算放大电路对幅值进行放大并对波形进行整形,根据三极管的特性可将各种波形的信号转换为矩形波。 信号经整形后通过开关接到单片机的 13 引脚 INT1’,开关可控制信号是否输入单片机。
51数显简易频率计设计

显示电路设计

测得频率由 7 段共阴极数码管,共 8 个,共阴数码管由低电平选通,选通信号由 74LS138 经过译码产生。
51数显简易频率计设计

检测电路设计

通过三个不同颜色的 LED 灯对单片机运行状态及频率是否超限进行显示。
51数显简易频率计设计

软件程序设计

根据自己的已有思路写出来基本的程序,但由于各种原因程序无法实现,如写的程序过于复杂,51 单片机系统资源不足带不动,不可控的外部中断频繁触发使得程序无法按正常的逻辑执行,另外,LED 数码管需要不断刷新占用大量的 CPU 执行时间。 经不断完善程序,采取了分时执行的方法,测频时不显示,显示时关闭外部中断不测频。
51数显简易频率计设计
51数显简易频率计设计
51数显简易频率计设计

调试与测试结果分析

(1)断开信号输入开关,侧的频率值为 0;
(2)设定频率上限为 1000,下限为 100,闭合信号输入开关,
1)接 500Hz 的正弦波,示波器观察到输入波形为矩形波,绿灯每隔 1 秒亮 1 秒,绿灯亮时数码管不显示,绿灯不亮时数码管显示 86610500;
2)接 1.5kHz 正弦波,示波器观察到输入波形为矩形波,绿灯每隔 1 秒亮 1 秒,绿灯亮时数码管不显示,绿灯不亮时数码管显示 86611500,且数码管显示同时红灯亮起; 3)接 5Hz 正弦波,示波器观察到输入波形近似为矩形波, 绿灯每隔 1 秒亮 1 秒,绿灯亮时数码管不显示,绿灯不亮时数码管显 示 86610050,且数码管显示同时黄灯亮起;
(3)输入其他类型的信号时,如三角波、矩形波、锯齿波,观 察到的结果与(2)类似;
(4)经多次测量,测量误差在 5% 以内;

硬件电路实现

实现了频率计的实物制作,由于硬件电路不够稳定以及实物模型的执行延迟,在测量上存在一定的偏差,不过实现了大体的功能。
51数显简易频率计设计

结束语

通过这次数显简易频率计的设计,我对 51 单片机有了更深的理解,在编程中对执行程序的时序分配及任务周期对程序执行效果的影响有了更深的印象,之后编程会更多的注意这一点,争取让自己的程 序更有效更出彩。
这次仿真设计也让我对我本不熟悉的 Proteus 软件有了一些初步的了解,之后的科创之路上或许我会通过这款软件或类似的软件增加对硬件电路的了解。 通过对硬件电路的搭建我了解了硬件的不易,以后编程也会更多地考虑硬件执行的时间,另外,尽量不要用低效的硬件,避免程序的执行困难重重。

参考文献

【1】马淑华、高军、蔡凌.单片机原理及接口技术第三版.北京邮电大学出版社[M],2018.06

附录一(程序)

#include "reg51.h"

#define	uint8 unsigned short int

uint8 i,k;

/******  非准确延时函数  *******/
void delay_us(int t)
{
    i = t;
    while(i--)
	{}
}
/*******************************/

/*************************************  数码管显示  **************************************/
uint8 code smg_data[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//共阴数码管段显编码(0-9、不显示)
uint8 smg7,smg6,smg5,smg4,smg3,smg2,smg1,smg0;//显示数据的各位:个、十、百、千...位数值
//数码管显示信号频率
void smg(int a)
{
    smg0 = 8;
	smg1 = 6;
	smg2 = 6;
	smg3 = 1;
    smg4 = (a%10000)/1000;//频率值的千位
	smg5 = (a%1000)/100;//频率值的百位
	smg6 = (a%100)/10;//频率值的十位
	smg7 = a%10;//频率值的个位

	P2 = 0xf7;//1111 0000选中第8个数码管
	P0 = smg_data[smg7];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf6;//1111 0000选中第7个数码管
	P0 = smg_data[smg6];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf5;//1111 0000选中第6个数码管
	P0 = smg_data[smg5];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf4;//1111 0000选中第5个数码管
	P0 = smg_data[smg4];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf3;//1111 0000选中第4个数码管
	P0 = smg_data[smg3];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf2;//1111 0001选中第3个数码管
	P0 = smg_data[smg2];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf1;//1111 0010选中第2个数码管
	P0 = smg_data[smg1];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);

	P2 = 0xf0;//1111 0011选中第1个数码管
	P0 = smg_data[smg0];
	delay_us(200);
	P0 = smg_data[10];//数码管消隐
	delay_us(10);
}
/****************************************************************************************/

/**********  下降沿计数  ***********/
int count = 0;//采到下降沿的数量
//信号下降沿计数,由外部中断1采集
void single_in() interrupt 2
{
    count++;//采集到下降沿,数值加1
}
/***********************************/

/*******************  频率计算及显示  ********************/
uint8 flag = 1;//计脉冲及显示操作标志
uint8 time0_num = 0;//定时器0中断次数
int fr_cest = 0;//测得频率
void timer0() interrupt 1
{
    TH0 = 0x3c;//定时器0重新赋值,定时时间为50毫秒,65536-50000=3cb0
	TL0 = 0xb0;
	time0_num++;//定时器0中断计数
	if(time0_num>=20&&flag==0)//定时器0中断达到20次,即定时1秒,执行频率计算
	{
	    EX1 = 0;//关闭外部中断,准备开始显示
		fr_cest = count;//频率计算
		time0_num = 0;//定时器0中断计次清0
		flag = 1;//显示操作标志
	}
	else if(time0_num>=20&&flag==1)
	{
	    EX1 = 1;//开启外部中断,开始计脉冲
		count = 0;//下降沿计数清0
		time0_num = 0;//定时器0中断计次清0
		flag = 0;//记脉冲操作标志
	}
}
/*********************************************************/

/****************************  中断初始化  ******************************/
void interrupt_init()
{
    TMOD = 0x11;    //0001 0001  T1门控位清0  T1为定时器模式  01,T1选择模式1        T0门控位清0  T0为定时器模式  01,T0选择模式1
    TCON = 0x14;    //0001 0100  T1标志位清0  T1计时关闭  T0标志位清0  T0开启计时        外部1标志位清0  外部1下降沿触发  外部0标志位清0  外部0电平触发
	IP = 0x09;      //0000 1001	 --  --	 --  串口中断优先级为低        T1中断优先级为高  外部中断1优先级为低  T0中断优先级为低  外部中断0优先级为低
	IE = 0x86;      //1000 0110	 开启总中断  --  --  关闭串行中断        关闭T1中断  开启外部中断1  开启T0中断  关闭外部中断0  
}
/***********************************************************************/

void main()
{
    interrupt_init();//中断初始化
	while(1)
	{
	    if(flag==1)
		{
		    if(fr_cest>1000)
			{
			    P1 = 0x01;
			}
			else if(fr_cest<100)
			{
			    P1 = 0x04;
			}
			else
			{
			    P1 = 0x00;
			}
		    smg(fr_cest);
		}
		else
		{
		    P1 = 0x02;
		}
	}
}

附录二(系统设计电路原理图)

51数显简易频率计设计

上一篇:oracle spatial创建空间表、元数据


下一篇:震惊! 阿里的程序员也不过如此,竟被一个简单的 SQL 查询难住