简易数字频率计设计.docx
《简易数字频率计设计.docx》由会员分享,可在线阅读,更多相关《简易数字频率计设计.docx(18页珍藏版)》请在冰豆网上搜索。
简易数字频率计设计
一、设计目的
1.了解数字频率计测频测周的基本原理;
2.熟练掌握数字频率计的设计与调试方法及减小测量误差的方法。
二、电路与原理
完整电路见附件一,针对电路各部分说明如下:
1.放大整形电路
频率为f的正弦波信号由共射共集放大电路放大,再经SN74LS132N整形,使之成为方波。
由T1、T2进行放大,SN74LS132N进行整形。
2.分频器
通过一片SN74LS390N的二分频和五分频功能实现十分频,两次十分频实现百分频。
由开关选择不分频、10分频或100分频。
方波信号不经过分频器直接接入单片机为不分频。
方波信号接入SN74LS390N的1B,从1QD输出对1B的五分频信号接入1A,从1QA输出对1A的二分频信号。
所以从1QA输出的信号即是对输出1B信号的十分频。
将此十分频后的信号再经过一次十分频2B—2QD—2A—2QA后,即可以实现对原方波信号的百分频。
3.单片机主控单元
经过分频器选择开关后的方波信号接入单片机的定时/计数器T1。
测量方式选择按钮分别接入单片机的INT0、INT1。
按下连接INT0的按钮选择测频方式。
按下连接INT1的按钮选择测周方式。
测频时由单片机的定时/记数器T0提供定时,测周时由T0计量信号的周期。
软件完成各种判断与数据处理工作。
P口和P2口的部分引脚控制显示。
4.显示电路
显示器是8位共阴极的LED。
单片机的P0口输出经反相器SN7406N后提供八位数码管的位选信号,P2口的低4位输出经译码器CD4511译码后提供的段选信号。
P2口的P24控制数码管低4位的小数点显示,P25控制数码管高4位的小数点显示。
LED动态扫描显示测量结果。
三、各IC作用及管脚图
1.SN74LS132整形芯片
起到将正弦信号整形成方波信号的作用。
其逻辑表达式Y=/(AB)或Y=/A+/B
2.SN74LS390N分频器
主要起到十分频和百分频的作用
2.CD4511译码器
译码显示作用(显示驱动)
管脚图
真值表
3.SN7406N反相器
由于是共阴极LED,所以需要将MCU中输出的高电平信号取反。
逻辑表达式:
Y=/(*A)
四、基于单片机的数字频率计设计框图
五、主要性能指标
低频达0.5Hz,甚至更低;
高频达450KHz(在不分频的情况下);
输入低至50mV信号时,仪器能正常工作;
在十分频下工作正常;
百分频下高频可达12MHz;
低频状态下测周稳定。
已经完成预期设计目标,而且超过设计要求。
六、软件程序(见附件二)
七、总结
1.出现问题。
问题一、模拟部分的电路分布不是很合理,显得杂乱无章。
在测试静态工作点时遇到了本次课程设计的第一个拦路虎――静态工作点极不稳定,而且稳压器7805温度比较高。
由于线路分布比较混乱,查问题也比较麻烦。
问题二、数字部分的显示部分出现了本次设计的第二只拦路虎――显示“0”、“2”、“3”时始终是错误的。
错误在显示“0”时显示的是“8”,显示“2”与“3”时,f段总是亮的。
看起来“2”显得不伦不类,“3”像个不规范的“9”。
2.分析问题
针对问题一、线路分布的不合理在于刚开始安排时没注意看电路板的结构特点。
印刷电路板已经设计了很多所谓的“大线”,从头到尾贯穿一直的是导通的,是被用作地线和电源线的。
而我只是把他们当作普通导线处理,造成容易出现问题,为防止以后在数字电路部分出现问题和影响数字部分的部线,我将模拟部分的“大线”都切断处理了,其中有一段被切为两段,一部分作为导线用,一部分作为地线用了。
另外其他部分一律与数字部分隔离。
静态工作点不稳定的原因是有一个点没有焊接,只是插到印刷板的孔里去了。
所以造成测试时接触不良。
在经过两个人一条条的“穿针引线”地查错才找到那根没焊接的点(由于焊接的不规范,将两根线插在一个孔里了,这样没焊接的导线并不是很松,所以不是很容易查出来)。
针对问题二、分析问题:
显示不正常,有两种可能。
一是硬件电路;二是所用的单片机软件。
先从硬件查起,逐条电路线用万用表进行检测,排除短路与断路的可能性(这里主要是短路的问题,因为是多亮了一条线而不是缺少线)。
硬件没排查出什么问题,各条电路均没出现短路与断路。
在换了多套程序后问题依然出现。
软件出现问题的可能性不大,因为这些程序在其他人的板子上可以正常工作。
再综合利用用软件帮助硬件的检测。
具体做法是编写了一套专门用来检测数码管的程序,这套程序的任务是让数码管逐个从“0”显示到“9”。
并循环显示。
然后逐个分析,是哪个数码管的哪位有问题,是在显示哪几个数字时错误。
最后得出问题二的判断。
下一步是分析这几个错误的共同点。
不该显示的显示了,那一定是由于某些原因被供电了,但在硬件线路检查时没发现短路。
而进一步分析问题时考虑到“这些不该点亮而被点亮的部分”是随着另一部分一起被点亮的(具体的来说就是分析2与3的笔画结构)。
这样就多了一种可能――数码管间的短路。
在通电情况下,拔下数码管,一个个检测数码管插座,发现果然有两脚短路。
按这条线索一路查下去,问题的关键在于多连接了一条线。
拆除后一切显示正常。
3.解决问题
数码管间的短路。
在通电情况下,拔下数码管,一个个检测数码管插座,发现果然有两脚短路。
按这条线索一路查下去,问题的关键在于多连接了一条线。
拆除后一切显示正常。
4.取得收获
还是老师的那几句话。
“理论指导实践”――先弄明白电路个部分功能与结构,还要弄清楚印刷板个部分功能与结构。
发现问题从理论出发,分析导致问题出现的可能原因,再逐个检测排除。
“先设计后施工”――不看到总体布局而盲目地一边走一边看,到后面将越走越难走,甚至前功尽弃。
前面的施工将为后面带来很多麻烦与障碍,原因就是没从总体来布局,没有先设计好。
具体操作上的收获。
焊接一定按规则与要求来,幸运的是,这次没出现虚焊与因焊接而造成的短路。
5.个人感受。
实验室条件太差了(当然不是指环境,而是指仪器设备条件)。
能用万用表没几块;稳定的示波器更是少得可怜;函数信号发生器也只有四台,而且只有后来用来验收的几台比较好,其他的两台极不稳定;电烙铁也没几个是好的,后来主要靠个人带进去的电烙铁来焊接线头比较密集的区域。
示波器的缺乏导致我直到验收才知道自己的设计作品所达到的性能指标,验收前根本没有机会测试。
万用表的缺少和电烙铁质量的低劣也提高了我们的焊接水平。
尽量提高自己的焊接水平,仔细焊接,减少虚焊与短路情况发生从而减少使用万用表的次数。
函数发生器的缺乏减少了我们检测与调试过程,从而降低了标或者不能有效控制设计仪器的性能指。
总之,本次课程设计是比较成功的,尤其是一个人能够提前较好地完成任务是让人比较欣慰的。
但也有一些遗憾所在,比如在软件方面没能仔细分析并重新编写程序,只是将程序作了适应性(适应硬件电路需要)的修改。
八、致谢
首先感谢鲁老师的指导,其次感谢韩师姐在模拟部分和数字去耦等方面的具体指导与帮助。
这一次,虽然没有组队一个人“单枪匹马”的干,但在做的过程中得到了很多热心同学的帮助。
这里只是具体说明其中几人的具体帮助。
感谢李景同学在模拟部分出现问题时与我一同检查电路并给予了有效的建议,虽然没查出什么问题,但还是估计花费了他1个多小时的时间而且还影响了他的午饭时间。
感谢郑伟林同学在我整个电路焊接完毕后同我一道全面检查电路,大大方便了我和提高了这次课程设计的进度。
感谢李军同学在数字显示部分在“火烧眉毛”的情况下(马上就要验收了)帮助我检查和分析问题并实际解决了问题。
附件一
1.完整电路图(PROTEL99SE绘制)
2.模拟部分抽出放大图为
3.数字部分抽出放大图为
附件二
1.主程序详单
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbitP24=P2^4;
uchartime=80;
ucharj=0;//显示位数
uintcount=0;//计数值的高位
ucharputout[8];//显示缓存
ucharFLAG;//测量方式标志
floattemp;//数据处理时的中间结果
voiddelay_ms(uchari)//延时10MS子程序
{
ucharj;
while(i--)
{for(j=0;j<125;j++);
}
return;
}
voidout(void)using3
{
ulongresult;
uchari;
if(FLAG)//测频方式的数据处理,计算1S的脉冲数
{temp=(float)(count*65536+TH1*256+TL1)/4;//频率<10,则扩大1000倍后取整,即显示三位小数
if(temp<10)
result=(ulong)(temp*1000);//10<=频率<100。
则扩大100倍后取整,即显示两位小数
elseif(temp<100)
result=(ulong)(temp*100);//100<=频率=<1000,则扩大10倍后取整,即显示一位小数
elseif(temp<1000)
result=(ulong)(temp*10);
else//频率>=10000,则直接取整,只显示整数
result=(ulong)temp;
}
else//测周方式的数据处理,计算1个脉冲的时间后取倒数
{temp=4e+6/(count*65536+TH0*256+TL0);
result=(ulong)(temp*1000);//一般在频率<10时测周方式,则总显示三位小数
}
i=0;
j=0;
while(result)//数据输出到显示缓冲区
{putout[i]=result%10;
result=result/10;
i++;
j++;
}
while(j<4)
putout[j++]=0;//所得结果只有小数位时补置显示缓冲区地位至putout[3]位为0
return;
}
voidmea_freq(void)interrupt0using0//外中断0服务子程序
{FLAG=1;//测频方式置标志FLAG为1
P0=0;//灭数码管
TCON=0X05;//关TR0,TR1,置外中断触发方式为脉冲后沿负跳有效
TMOD=0X51;//定时器T0工作方式1,计数器T1工作方式1
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
TCON=0X55;//开TRO,TR1
return;
}
voidmea_cycle(void)interrupt2using0//外中断1服务子程序
{
FLAG=0;//测周方式置标志FLAG为0
P0=0;//灭数码管
TCON=0x05;//关TR0,TR1,置外中断触发方式为脉冲后沿负跳有效
TMOD=0x61;//定时器T0工作方式1,计数器T1工作方式2
TH1=251;
TL1=251;
TH0=0;
TL0=0;
count=0;
TR1=1;//开计数器T1
while(252-TL1);//等待一个负跳变的到来
TR0=1;//来了一个负跳变,开始计时。
计4个脉冲的时间
return;
}
voidt0_service(void)interrupt1using1//定时器0中断服务子程序
{
P0=0;//灭数码管
if(FLAG)//测频方式,定时器0溢出,判断是否时间到
{time--;
TH0=0X3C;
TL0=0XC8;
if(!
time)//time=0,则定时时间到
{TCON=0X05;//关TR0,TR1
out();//数据处理//下一次测量初始化
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
count=0;
time=80;
TCON=0X55;//开TR0,TR1,开始定时,计数
}
}
else//测周方式,计时器0溢出,计数高位加1
count++;
return;
}
voidt1_service(void)interrupt3using2//计数器1中断服务子程序
{
P0=0;//灭数码管
if(FLAG)//测频方式,计数器1溢出,计数高位加1
count++;
else//测周方式,计4个脉冲到后溢出
{
TCON=0X05;//关TR0,TR1
out();//数据处理//下一次测量初始化
TH0=0;
TL0=0;
TH1=251;
TL1=251;
TR1=1;
count=0;
while(252-TL1);
TR0=1;
}
return;
}
voiddisplay(void)//显示子函数。
{
ucharn;
ucharbit_secl;
if(j<=4)
{bit_secl=0X08;
for(n=0;n{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms
(1);
}
}
else//频率较高时,多于四位的显示。
{bit_secl=0X08;
for(n=0;n<4;n++)
{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms
(1);
}
bit_secl=0X80;
for(n=4;n{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms
(1);
}
}//显示小数点,P2口P24选中数码管的小数点
if(temp<10)
{P0=0X01;
P24=1;
}//位选选中D3位的数码管
elseif(temp<100)
{P0=0X02;
P24=1;
}//位选选中D2位数码管
elseif(temp<1000)
{P0=0X04;
P24=1;
}//位选选中D1位数码管
delay_ms
(1);
return;
}
voidmain(void)
{FLAG=1;//默认测量方式为测频
TCON=0X05;//关TR0,TR1,置外中断请求触发方式为脉冲后沿负跳有效
TMOD=0X51;//定时器0方式1,计数器1方式1
count=0;//计数值的高位初始化
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
IE=0X8F;//开中断
TCON=0X55;//开TR0,TR1,开始定时,计数
for(;;)
{display();
}
}
2.显示故障检测程序
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
voiddelay_ms(ulongi)//延时子程序
{ucharj;
while(i--)
{for(j=0;j<125;j++);}
return;
}
voiddisplay1(void)
{ucharn;
ucharbit_secl=0x01;
for(n=0;n<8;n++)//显示数字
{P0=bit_secl;
P2=0x01;
bit_secl=bit_secl<<1;
delay_ms(1500);延时时间
}
return;
}
…………(这里省略部分为显示数字子程序)
voidmain(void)
{
for(;;)
{display0();
display1();
display2();
display3();
display4();
display5();
display6();
display7();
display8();
……
}
}
附件三
实物效果图见封面(为数码相机所拍)。