设计要求
通过超声波的发送与接收来实现一定距离的探测,并能够显示出来。同时要求带有温度补偿功能,即根据当前温度值的不同进行声速的调整,然后计算,更准确地得到所测距离。并且要求可以随时进行当前温度的现实,实现测距测温两用。
方案设计
(1)主控芯片采用AT89S52
(2)显示部分采用四位共阳数码管,驱动采用9012三极管
(3)温度传感器采用DS18B20
(4)超声波选用TCT40-10F和TCT40-1-S1一套发射接收
硬件电路共分为六大部分:主控制器、显示部分、案件、温度检测、超声波发射和接收。以下就是系统的组成框图。
硬件电路设计
发射电路主要有反相器74LS04和超声波发射换能器LS2构成,单片机的P10端口输出的40kHz方波信一路经一级反相器后送到超声波换能器的一个电极,另一路经两级反相器后进行到超声波华能器的另一个电极。用这种推挽形式将方波信号加到超声波换能器两端,可以提高超声波的大射强度。输出端采用两个反相器并联,用以提高驱动能力。上拉电阻R1和R5,一方面可以提高反相器74LS04输出高电平的驱动能力,另一方面可以增加超声换能器的阻尼效果,缩短其自有振荡的时间。
超声波检测接收电路选用CX20106A,一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控采用的载波频率38kHz与测距的超声波频率40kHz较为接近,适当地更改电容C1的大小,可以改变接受电路的灵敏度和抗干扰能力。
软件设计
(1)超声波测距的算法设计
下图示意了超声波测距的原理,即超声波发生器T在某一时刻发出一个超声波信号,当这个超声波遇到被测物体后反射回来,就被超声波接收器R所接收到。这样,只要计算出从发出信号声波信号到接收到返回信号所用的时间,就可算出超声波发生器与反射物体的距离。距离的计算公式为:d = s/2 =(c * t)/2,其中,d为被测物与测距器的距离;s为声波来回的路程;c为声速;t为声波来回所用的时间。
由于超声波也是一种声波,其声速c与温度有关。下表列出了几种不同温度下的超声波声速。在程序中先通过采集温度,在与表中比对,得到当前声速,在计算出距离。
(2)超声波测距程序
外部中算0用来接收返回的脉冲,当接受到以后进行中断处理,优先级最高;定时器0用来计时,选择的是十六位定时模式,用来计算超声波脉冲从发射到接收所用的时间;定时器1用来作为测试距离的显示定时,每中断一次就扫描一位数码管。
#include<reg52.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long sbit we0=P2^0; sbit we1=P2^1; sbit we2=P2^2; sbit we3=P2^3; sbit fasong=P1^0; sbit jieshou=P3^2; sbit k1=P3^6; sbit k2=P3^7; sbit ds=P1^4; uchar timers,mi,fenmi,limi,num2,num1,shi,ge,shifen,shengsu; bit flag,kaiflag,temflag; ulong t,s; uint temp,num; float n; uchar code table[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; void init(); void delay100us() { uchar i,j; for(i=40;i>0;i--) for(j=248;j>0;j--); } void delay(uchar a) { while(a>0) a--; } void shijian(uint x) { uint i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void reset() { ds=0; delay(103); ds=1; delay(4); } void write(uchar date) { uchar temp,i; uint j; temp=date; for(i=0;i<8;i++) { temp=temp>>1; if(CY) { ds=0; j++;j++; ds=1; delay(8); } else { ds=0; delay(8); ds=1; j++;j++; } } } uchar read() { uchar j,dat; for(j=0;j<8;j++) { ds=0; dat>>=1; ds=1; delay(1); if(ds) dat|=0x80; delay(8); } return(dat); } uint get() { uchar gao,di; reset(); shijian(1); write(0xcc); write(0x44); reset(); shijian(1); write(0xcc); write(0xbe); di=read(); gao=read(); temp=gao<<8; temp=temp|di; n=temp*0.065+0.5; temp=n*10; return(temp); } void send() { uchar i; while(TF0==0) { we0=0; timers++; fasong=~fasong; for(i=12;i>0;i--); if(timers==4) break; } we0=1; timers=0; TH0=0X00; TL0=0X32; TR0=1; EX0=1; delay100us(); delay100us(); delay100us(); // delay100us(); // delay100us(); } void keyscan() { if(k1==0) { shijian(10); if(k1==0) kaiflag=~kaiflag; while(k1==0); } if(k2==0) { shijian(10); if(k2==0) temflag=~temflag; while(k2==0); } } void temdisplay() { num=get(); shi=num/100; ge=num%100/10; shifen=num%10; P0=table[shi]; we1=0; we0=1; we2=1; we3=1; shijian(6); P0=table[ge+10]; we1=1; we0=1; we2=0; we3=1; shijian(6); P0=table[shifen]; we3=0; we1=1; we0=1; we2=1; shijian(1); } void init() { TMOD=0x21; TH0=0X00; TL0=0X32; TH1=0x00; TL1=0x00; TR1=0; TR0=0; EA=1; ET0=1; ET1=1; EX0=1; IT0=1; P2=0xff; P0=0xff; kaiflag=0; temflag=0; } void main() { init(); while(1) { keyscan(); if((kaiflag==1)&&(temflag==1)) { temdisplay(); TR1=0; TR0=0; EX0=0; } if((kaiflag==1)&&(temflag==0)) { send(); num=get(); TR1=1; } if(kaiflag==0) { TR1=0; TR0=0; init(); } } }
本文暂时没有评论,来添加一个吧(●'◡'●)