历史上的今天
今天是:2024年12月06日(星期五)
2020年12月06日 | 单片机+UA741放大整形1~10K频率计
2020-12-06 来源:51hei
设计要求
(1)可测正弦波、方波信号的频率,频率范围:1 Hz~10 kHz。
(2)信号Vpp为0.1 ~3 V。
(3)测试结果显示于液晶。
1.2设计总体方案
用一个定时器来定时1秒,用一个计数器来数在定时1秒内有多少次外部中断,定时器和计数器定时工作在方式1,即16位定时器/计数器。然后定时1S结束后,把计数器里面的高8位和低8位的数值取出来,换算成10进制数赋值给频率,刚好数值变化多少,频率就是多少Hz.



1.3系统结构框图

2系统硬件电路设计
2.1总体电路图

图2、总体电路图
2.2各单元模块功能
①STC89C52RC:
具有以下标准功能: 8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,3个16 位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。另外 STC89C52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35MHz,6T/12T可选。

图3、STC89C52RC引脚图
②LCD1602液晶显示屏:
1602采用标准的16脚接口,其中:
第1脚:VSS为电源地
第2脚:VCC接5V电源正极
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会 产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。
第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极。
主要功能:用来显示频率
③LM393比较器:
lm393引脚图

图4、 LM393内部结构图
LM393主要功能:
输出负载电阻能衔接在可允许电源电压范围内的任何电源电压上,不受 Vcc端电压值的限制,输出部分的陷电流被可能得到的驱动和器件的β值所限制。当达到极限电流(16mA)时,输出晶体管将退出而且输出电压将很快上升。输出饱和电压被输出晶体管大约60ohm 的γSAT限制。当负载电流很小时,输出晶体管的低失调电压(约1.0mV)允许 输出箝位在零电平。
④UA741集成运放:
UA741的2脚是反相输入端,3脚是同相输入端,6脚是输出端,7脚接正电源,4脚接负电源(双电源工作时或地(单电源工作时),1脚和5脚是失调电压调零端,8脚是空脚内部没有任何连接。如下图——

图5、 UA741引脚图
主要功能:把信号放大,得到所需要的电压幅值。
⑤11.0592Mhz晶振:
晶体振荡器,能产生振荡,其特点是固有频率十分稳定,而且震动具有多谐性,除了奇频震动外还有奇次谐波泛音震动.性能上,晶振的品质因素Q和特性阻抗都非常高,而且接入系数很小,因此具有很高的频率稳定度,提供单片机工作时钟
2.3模块电路设计
电路的关键部分还是放大整形电路,下面是放大整形电路的设计模块
总体电路:

图6 、放大整形总体电路图
放大器部分:

图7、 放大部分电路图
根据实际器件的设计,我们放大器放大倍数为Au=101倍
具体算法如下
假定放大器同向输入端电压为Ui,放大器放大输出电压端电压Uo,则回路近似有以下关系
(公式1)
则放大倍数为:
(公式2)
比较器部分:

图8、 比较电路设计图
我们给比较器反向输入端的基准电压为2.5v,输出端接一个上拉电阻增强输出引脚的驱动能力。当同向输入端电压大于反向输入端电压(2.5V)时,比较器输出高电平,当同向输入端电压低于反向输入端电压(2.5V)时,比较器输出低电平。
因此,以2.5V为界,当输入电压变化时,输出端反映出两种状态,高电位和低电位。
3系统软件设计
3.1程序流程图

3.2程序主要模块
程序包括,定时模块,计数模块,显示模块
定时模块是用来定时1秒给计数器,计数器在这1秒数了多少个数,再把数了多少个数拿去给显示模块显示。
4系统仿真及调试
4.1Proteus仿真

图10、 Proteus仿真图一

图11、 Proteus仿真图二
4.2实物研制及调试
4.2.1方波频率测试
结论
实训过程中遇到了很多问题,这个题目不仅关于如何写单片机的程序,还要理清放大整形电路的设计思路,一刚开始,我们也不知道怎么设计放大整形电路。然后去百度借鉴别人的设计思路,设计过程也很懊恼,各种器件的取值怎么选取,由于实验室的器材种类有限,我们还得根据实际出发,选择合适的器件。放大整形电路设计完成后,我们就根据电路来搭个原理图。我是第一次使用Altium Designer来画PCB的,使用操作有点陌生,我就根据老师的演示和课后看课本慢慢熟悉Altium Designer画PCB的过程,最后完成了自己的PCB电路。后面就是打印PCB焊接电路的过程了,实物做出来后,和仿真的还是有很大差别,特别是放大器部分,单电源无法工作,这就给我们的电路造成一个很大的错误,最后我们改成了双电源工作,电路其他部分因为双电源工作的影响,我们也改了一下。最终完成了我们的频率计的设计,频率也能测得出来了。总之实训过程很有趣和考验我们的设计能力,在实训中体会学习的快乐。
附录一:实物图

图12、实物图一

图13、实物图二
#include"reg51.h"
#define uint unsigned int
#define uchar unsigned char
#define DATAPORT P2
sbit RS=P3^2;
sbit RW=P3^6;
sbit E=P3^7;
sbit fangbo1=P3^0;//提供10Hz左右的自检信号
sbit fangbo2=P3^1;//提供1Hz左右的自检信号
uchar num;
uint f=0;//频率f
uchar code table[]="0123456789.";
uchar code table1[]="=sHZFT: ero!";
void init(void); //初始化函数声明
void writeCOM(uchar i); //写命令函数声明
void writeData(uchar j); //写数据函数声明
void fbusy(void); //检查忙函数声明
void display(); //写显示函数
void delay(uint mux)
{
uint i,j;
for(i=mux;i>0;i--)
for(j=120;j>0;j--);
}
void main()
{
TMOD=0x51;//定时器·0工作在方式1,计数器1工作在方式1,晶振11.0592M,机器周期为12/f.
TL0=(65536-46080)%256; //定时50ms初值为 T(定时时间,秒)*F(晶振频率 HZ)/12, 46080、45872
TH0=(65536-46080)/256;
TL1=0;
TH1=0;
ET0=1;
EA=1;
init();
while(1)
{
TR0=1;//打开定时器
TR1=1;//打开计数器
while(num==20)
{
num=0;//定时计算清
TR0=0;//关闭定时器
TR1=0; //关闭计数器
f=(TH1*256)+TL1;//计算频率
delay(10);
TH1=0;//计数清0
TL1=0;//计数清0
}
display();//显示结果
}
}
//定时1S溢出
void interr_zd2()interrupt 1
{
TL0=(65536-46080)%256;
TH0=(65536-46080)/256;
num++;
fangbo1=~fangbo1; //产生个10Hz左右的方波
if(num==10){fangbo2=~fangbo2;}//产生个1Hz左右的方波
}
//显示屏数据
void display()
{
writeCOM(0x80);
writeData(table1[4]); //显示F:
writeData(table1[6]);
writeCOM(0x8c);
writeData(table1[2]); // 显示HZ
writeData(table1[3]);
writeCOM(0xc0);
writeData(table1[5]); // 显示T:
writeData(table1[6]);
writeCOM(0xcd);
writeData(table1[1]); // 显示S
if(f<10) //频率1位数
{
writeCOM(0x85);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table[f]);
}
if((f>=10)&(f<100))//频率2位数
{
writeCOM(0x85);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table[f/10]);
writeData(table[f%10]);
}
if((f>=100)&(f<1000))//频率3位数
{
writeCOM(0x85);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table[f/100]);
writeData(table[f%100/10]);
writeData(table[f%10]);
}
if((f>=1000)&(f<10000))//频率4位数
{
writeCOM(0x85);
writeData(table1[7]);
writeData(table1[7]);
writeData(table[f/1000]);
writeData(table[f%1000/100]);
writeData(table[f%100/10]);
writeData(table[f%10]);
}
if((f>=10000)&(f<=50000))//频率5位数
{
writeCOM(0x85);
writeData(table1[7]);
writeData(table[f/10000]);
writeData(table[f%10000/1000]);
writeData(table[f%1000/100]);
writeData(table[f%100/10]);
writeData(table[f%10]);
}
if(f>50000) //超出50khz提示错误
{
writeCOM(0x84);
writeData(table1[7]);
writeData(table1[8]);
writeData(table1[9]);
writeData(table1[9]);
writeData(table1[10]);
writeData(table1[9]);
writeData(table1[11]);
writeCOM(0xc3);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[7]);
writeData(table1[8]);
writeData(table1[9]);
writeData(table1[9]);
writeData(table1[10]);
writeData(table1[9]);
writeData(table1[11]);
}
if((0
writeCOM(0xc3);
writeData(table[1000000/f/1000000]);
writeData(table[10]);
writeData(table[1000000/f%1000000/100000]);
writeData(table[1000000/f%100000/10000]);
writeData(table[1000000/f%10000/1000]);
writeData(table1[7]);
writeData(table[1000000/f%1000/100]);
writeData(table[1000000/f%100/10]);
writeData(table[1000000/f%10]);
}
if(f==0) //显示周期、频率为0时算周期比较特殊
{
writeCOM(0xc3);
writeData(table[0]);
writeData(table[10]);
writeData(table[0]);
writeData(table[0]);
writeData(table[0]);
writeData(table1[7]);
writeData(table[0]);
writeData(table[0]);
writeData(table[0]);
}
}
//初始化函数
void init()
{
writeCOM(0x01); //清屏
writeCOM(0x38); //读8位数据,显示两行,使用5*7的字型
writeCOM(0x0c); //显示器开,光标关,字符不闪烁
writeCOM(0x06); //字符不动,光标自动右移一位
}
//检查忙函数
void fbusy()
{
DATAPORT=0xff; //读之前向端口写1,确保读数正确
RS=0;RW=1;
E=0;E=1; //正脉冲读
while(DATAPORT&0x80) //忙,等待
{E=0;E=1;}
}
//写命令函数
void writeCOM(uchar i)
{
fbusy();
RS=0;RW=0;
E=1;
DATAPORT=i;
E=0; //负脉冲写
}
//写数据函数
void writeData(uchar j)
{
fbusy();
RS=1;RW=0;
E=1;
DATAPORT=j;
E=0; //负脉冲写
}
史海拾趣
|
控制板的电源要求,板子上电时先给单片机供电,再给其他的元器件供电,以便各个部件在单片机的控制范围内。板子断电时先断其他元器件的电源,再给单片机断电。大家讨论下控制的方式……… 查看全部问答> |
|
我的平台上连着USB 3G上网卡,想达到这样的效果: 1. 点击“我的连接”时,就启动USB电源;稍等一会点“连接”就可以拔号了 2. 点“断开连接”时,就断开USB电源 不知修改哪里的代码,电源的控制很简单,设置一个使能引脚而已… 查看全部问答> |
|
我现在用的AU1250,现在读取大的图片和显示都比较慢,例如一张800*480的jpeg图片,读取图片大约150毫秒左右,显示图片在130-240毫秒左右。 在网上查的Samsung 6410有2D加速和jpeg硬加速,不知道能快多少啊?… 查看全部问答> |
|
之前发过帖子询问关于绘制窗口时的问题, A,B窗口互相独立,B弹出时会覆盖A,B隐藏时覆盖A的部分会刷白,之后在网上查询过资料后找到了解决的问题。 因为A,B窗口都是贴了PNG的图片,PNG用PS修饰之后可以显示透明的效果,于是就用了IImage绘制。 ...… 查看全部问答> |
|
我想试一下2个gprs模块的点对点通讯,但是连不通,2个模块拨通后都是10.14.x.x ip地址,为什么连不通?? 有人说是移动认为阻断了内网之间的ip连接。但是也没有查到较权威的说法?? 现在有的公司的gprs dtu产品提供点对点的通讯模式 ...… 查看全部问答> |
|
我用的是arm+linux 文件系统是用busybox制作的,再用mkfs.jffs2做成jffs文件系统; 但是现在出了个怪问题是:总的flash只有16M,分给boot和kernel 3M,还剩下13M;问题来了,我用du命令查看文件夹的大小,结果是已经有两个文件夹的大小分别是8.1M ...… 查看全部问答> |
|
我向做一个程序,要用到数据库,但是现在pda上的空间不够,我需要外部扩展的存储器,现在pda读u盘和sd卡都是正常的,我想把数据库放在sd卡里面,请问这样,如果调用数据库里面的信息能不能实现啊,是直接就当自己的存储器里面的文件用,还是需要再 ...… 查看全部问答> |
|
我用的是(STM32F103R8) PC12作下降沿触发,外部输入的时序如下图: 下载 (20.77 KB) 2010-12-3 15:28 现在出现一个情况,搞了好长时间也没查出问题。… 查看全部问答> |
|
我想试着做个小东西。。 用51做个小时钟。。 功能很简单。。 不需要什么按键。。 接个1602 。。想让他在考进程序后开始走时间。。 现在的问题是.. 我该怎么实现.. 单片机里的时间和现实时间同步呢? *由于晶振..或其他硬件因素产生的时间误差不 ...… 查看全部问答> |




