设计要求
(1)可测正弦波、方波信号的频率,频率范围:1 Hz~10 kHz。
(2)信号Vpp为0.1 ~3 V。
(3)测试结果显示于液晶。
1.2设计总体方案
用一个定时器来定时1秒,用一个计数器来数在定时1秒内有多少次外部中断,定时器和计数器定时工作在方式1,即16位定时器/计数器。然后定时1S结束后,把计数器里面的高8位和低8位的数值取出来,换算成10进制数赋值给频率,刚好数值变化多少,频率就是多少Hz.
制作出来的实物图如下:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
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<f)&(f<=50000)) //计算周期,显示
{
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; //负脉冲写
}
全部资料51hei下载地址:
频率计(1~10KHz).zip
(251.61 KB, 下载次数: 71)
实训文档.docx
(511.62 KB, 下载次数: 24)
|