超声波测距仪是怎么定时的?
来源:学生作业帮助网 编辑:六六作业网 时间:2024/11/21 19:38:03
超声波测距仪是怎么定时的?
超声波测距仪是怎么定时的?
超声波测距仪是怎么定时的?
利用单片机定时器的TMOD中的Gate,和外部中断一起使用.
声波发出时候,启动某个定时器开始定时,声波返回时,定时停止,此时定时所得时间即所得。
超声波测距是借助于超声脉冲回波渡越时间法来实现的。设超声波脉冲由传感器发 出到接收所经历的时间为 t,超声波在空气中的传播速度为 c,则从传感器到目标物体 的距离 D 可用下式求出:
D = ct /2
这是它的程序
#include
#include
#define uchar un...
全部展开
超声波测距是借助于超声脉冲回波渡越时间法来实现的。设超声波脉冲由传感器发 出到接收所经历的时间为 t,超声波在空气中的传播速度为 c,则从传感器到目标物体 的距离 D 可用下式求出:
D = ct /2
这是它的程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define RX P1_1
#define TX P1_2
sbit SDATA_595=P0^0; //串行数据输入
sbit SCLK_595 =P0^2; //移位时钟脉冲
sbit RCK_595 =P0^1; //输出锁存器控制脉冲
sbit FM=P3^7; //蜂鸣器
unsigned int time=0;
unsigned int timer=0;
unsigned long S=0;
bit flag =0;
uchar temp=0;
uchar i =0;
const uchar discode[12]={ 0xC0, 0xF9,0xA4, 0xB0,0x99,0x92,0x82,0xF8,0x80, 0x90,0xBF,0xff};
const uchar disposit[4]={ 0x7f, 0xbf, 0xdf,0xef };//,0xf7,0xfb,0xfd,0xfe };
uchar disbuff[4]= { 11,0,0,0 };
/********************************************************/
/*
/*将显示数据送入74HC595内部移位寄存器
/*
/********************************************************/
void WR_595(void)
{
uchar j;
for (j=0;j<8;j++)
{
temp=temp<<1;
SDATA_595=CY;
SCLK_595=1; //上升沿发生移位
SCLK_595=0;
}
}
/********************************************************/
/*
/*将移位寄存器内的数据锁存到输出寄存器并显示
/*
/********************************************************/
void OUT_595(uchar a,uchar b)
{
temp=a; //选择通数据
WR_595();
temp=b; //显示代码
WR_595();
RCK_595=0;
RCK_595=1; //上升沿将数据送到输出锁存器
RCK_595=0;
}
/********************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
if((S>=700)||flag==1) //超出测量范围显示“-”
{
flag=0;
disbuff[1]=10; //“-”
disbuff[2]=10; //“-”
disbuff[3]=10; //“-”
}
else
{
disbuff[1]=S%1000/100;
disbuff[2]=S%1000%100/10;
disbuff[3]=S%1000%10 %10;
}
}
/********************************************************/
void Display(void)
{
if(i==1)
OUT_595(disposit[i],(discode[disbuff[i]])&0x7f); //显示点
else
OUT_595(disposit[i],discode[disbuff[i]]);
i++;
if(i>=4)i=0; //扫描四个数码管
}
/********************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/********************************************************/
void deng() //指示灯
{
int m;
m=(int)disbuff[2];
switch(m){
case 0:P2=0xFF;break;
case 1:P2=0x7F;break;
case 2:P2=0x3F;break;
case 3:P2=0x1F;break;
case 4:P2=0x0F;break;
case 5:P2=0x07;FM=0;break;
case 6:P2=0x03;FM=0;break;
case 7:P2=0x01;FM=0;break;
case 8:P2=0x00;FM=0;break;
default:return;}
}
/********************************************************/
void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8;
TL1=0x30;
Display();
deng(); //p2指示灯
timer++;
if(timer>=400)
{
timer=0;
TX=1; //800MS 启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
/********************************************************/
void main(void)
{
TMOD=0x11; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
TH1=0xf8; //2MS定时
TL1=0x30;
ET0=1; //允许T0中断
ET1=1; //允许T1中断
TR1=1; //开启定时器
EA=1; //开启总中断
SCLK_595=0;
RCK_595=1;
while(1)
{
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
}
}
/********************************************************/
收起