我自己编的超声波测距51单片机c语言编程错哪了,,感觉延时很久数码管才有反应,哪个地方导致的延时

我自己编的超声波测距51单片机c语言编程错哪了,,感觉延时很久数码管才有反应,哪个地方导致的延时,第1张

TH1=(65536-800)/256; //800ms定时

TL1=(65536-800)%256;

这样的赋值是800ms?51定时器工作方式1在12M下最大定时是65536ms吧

这是一个超声波避障小车的源程序,可以参考下,用的89C52单片机,舵机控制转角避障。

#include<AT89x51H>

#include <intrinsh>

#define Sevro_moto_pwm P2_7 //接舵机信号端输入PWM信号调节速度

#define ECHO P2_4 //超声波接口定义

#define TRIG P2_5 //超声波接口定义

#define Left_moto_go {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} //左边两个电机向前走

#define Left_moto_back {P1_0=0,P1_1=1,P1_2=0,P1_3=1;} //左边两个电机向后转

#define Left_moto_Stop {P1_0=0,P1_1=0,P1_2=0,P1_3=0;} //左边两个电机停转

#define Right_moto_go {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} //右边两个电机向前走

#define Right_moto_back {P1_4=0,P1_5=1,P1_6=0,P1_7=1;} //右边两个电机向前走

#define Right_moto_Stop {P1_4=0,P1_5=0,P1_6=0,P1_7=0;} //右边两个电机停转

unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/-/};

unsigned char const positon[3]={ 0xfe,0xfd,0xfb};

unsigned char disbuff[4] ={ 0,0,0,0,};

unsigned char posit=0;

unsigned char pwm_val_left = 0;//变量定义

unsigned char push_val_left =14;//舵机归中,产生约,15MS 信号

unsigned long S=0;

unsigned long S1=0;

unsigned long S2=0;

unsigned long S3=0;

unsigned long S4=0;

unsigned int time=0; //时间变量

unsigned int timer=0; //延时基准变量

unsigned char timer1=0; //扫描时间变量

//

void delay(unsigned int k) //延时函数

{

unsigned int x,y;

for(x=0;x<k;x++)

for(y=0;y<2000;y++);

}

//

void Display(void) //扫描数码管

{

if(posit==0)

{P0=(discode[disbuff[posit]])&0x7f;}//产生点

else

{P0=discode[disbuff[posit]];} if(posit==0)

{ P2_1=0;P2_2=1;P2_3=1;}

if(posit==1)

{P2_1=1;P2_2=0;P2_3=1;}

if(posit==2)

{P2_1=1;P2_2=1;P2_3=0;}

if(++posit>=3)

posit=0;

}

//

void StartModule() //启动测距信号

{

TRIG=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

TRIG=0;

}

//

void Conut(void) //计算距离

{

while(!ECHO); //当RX为零时等待

TR0=1; //开启计数

while(ECHO); //当RX为1计数并等待

TR0=0; //关闭计数

time=TH0256+TL0; //读取脉宽长度

TH0=0;

TL0=0;

S=(time17)/100; //算出来是CM

disbuff[0]=S%1000/100; //更新显示

disbuff[1]=S%1000%100/10;

disbuff[2]=S%1000%10 %10;

}

//

//前速前进

void run(void)

{

Left_moto_go ; //左电机往前走

Right_moto_go ; //右电机往前走

}

//

//前速后退

void backrun(void)

{

Left_moto_back ; //左电机往前走

Right_moto_back ; //右电机往前走

}

//

//左转

void leftrun(void)

{

Left_moto_back ; //左电机往前走

Right_moto_go ; //右电机往前走

}

//

//右转

void rightrun(void)

{

Left_moto_go ; //左电机往前走

Right_moto_back ; //右电机往前走

}

//

//STOP

void stoprun(void)

{

Left_moto_Stop ; //左电机停走

Right_moto_Stop ; //右电机停走

}

//

void COMM( void )

{

push_val_left=5; //舵机向左转90度

timer=0;

while(timer<=4000); //延时400MS让舵机转到其位置

StartModule(); //启动超声波测距

Conut(); //计算距离

S2=S;

push_val_left=23; //舵机向右转90度

timer=0;

while(timer<=4000); //延时400MS让舵机转到其位置

StartModule(); //启动超声波测距

Conut(); //计算距离

S4=S;

push_val_left=14; //舵机归中

timer=0;

while(timer<=4000); //延时400MS让舵机转到其位置 StartModule(); //启动超声波测距

Conut(); //计算距离

S1=S; if((S2<20)||(S4<20)) //只要左右各有距离小于20CM小车后退

{

backrun(); //后退

timer=0;

while(timer<=4000);

}

if(S2>S4)

{

rightrun(); //车的左边比车的右边距离小 右转

timer=0;

while(timer<=4000);

}

else

{

leftrun(); //车的左边比车的右边距离大 左转

timer=0;

while(timer<=4000);

}

} //

/ PWM调制电机转速 /

//

/ 左电机调速 /

/调节push_val_left的值改变电机转速,占空比 /

void pwm_Servomoto(void)

{

if(pwm_val_left<=push_val_left)

Sevro_moto_pwm=1;

else

Sevro_moto_pwm=0;

if(pwm_val_left>=200)

pwm_val_left=0;

}

//

///TIMER1中断服务子函数产生PWM信号/

void time1()interrupt 3 using 2

{

TH1=(65536-100)/256; //100US定时

TL1=(65536-100)%256;

timer++; //定时器100US为准。在这个基础上延时

pwm_val_left++;

pwm_Servomoto(); timer1++; //2MS扫一次数码管

if(timer1>=20)

{

timer1=0;

Display();

}

}

//

///TIMER0中断服务子函数产生PWM信号/

void timer0()interrupt 1 using 0

{

} // void main(void)

{ TMOD=0X11;

TH1=(65536-100)/256; //100US定时

TL1=(65536-100)%256;

TH0=0;

TL0=0;

TR1= 1;

ET1= 1;

ET0= 1;

EA = 1; delay(100);

push_val_left=14; //舵机归中

while(1) /无限循环/

{ if(timer>=1000) //100MS检测启动检测一次

{

timer=0;

StartModule(); //启动检测

Conut(); //计算距离

if(S<30) //距离小于20CM

{

stoprun(); //小车停止

COMM(); //方向函数

}

else

if(S>30) //距离大于,30CM往前走

run();

}

}

}

//

下面是头文件:

头文件(一)

/--------------------------------------------------------------------------

AT89X51H Header file for the low voltage Flash Atmel AT89C51 and AT89LV51

Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc

All rights reserved

--------------------------------------------------------------------------/

#ifndef __AT89X51_H__

#define __AT89X51_H__

/------------------------------------------------

Byte Registers

------------------------------------------------/

sfr P0 = 0x80;

sfr SP = 0x81;

sfr DPL = 0x82;

sfr DPH = 0x83;

sfr PCON = 0x87;

sfr TCON = 0x88;

sfr TMOD = 0x89;

sfr TL0 = 0x8A;

sfr TL1 = 0x8B;

sfr TH0 = 0x8C;

sfr TH1 = 0x8D;

sfr P1 = 0x90;

sfr SCON = 0x98;

sfr SBUF = 0x99;

sfr P2 = 0xA0;

sfr IE = 0xA8;

sfr P3 = 0xB0;

sfr IP = 0xB8;

sfr PSW = 0xD0;

sfr ACC = 0xE0;

sfr B = 0xF0;

/------------------------------------------------

P0 Bit Registers

------------------------------------------------/

sbit P0_0 = 0x80;

sbit P0_1 = 0x81;

sbit P0_2 = 0x82;

sbit P0_3 = 0x83;

sbit P0_4 = 0x84;

sbit P0_5 = 0x85;

sbit P0_6 = 0x86;

sbit P0_7 = 0x87;

/------------------------------------------------

PCON Bit Values

------------------------------------------------/

#define IDL_ 0x01

#define STOP_ 0x02

#define PD_ 0x02 / Alternate definition /

#define GF0_ 0x04

#define GF1_ 0x08 #define SMOD_ 0x80 /

------------------------------------------------

TCON Bit Registers

------------------------------------------------/

sbit IT0 = 0x88;

sbit IE0 = 0x89;

sbit IT1 = 0x8A;

sbit IE1 = 0x8B;

sbit TR0 = 0x8C;

sbit TF0 = 0x8D;

sbit TR1 = 0x8E;

sbit TF1 = 0x8F;

/------------------------------------------------

TMOD Bit Values

------------------------------------------------/

#define T0_M0_ 0x01

#define T0_M1_ 0x02

#define T0_CT_ 0x04

#define T0_GATE_ 0x08

#define T1_M0_ 0x10

#define T1_M1_ 0x20

#define T1_CT_ 0x40

#define T1_GATE_ 0x80

#define T1_MASK_ 0xF0

#define T0_MASK_ 0x0F

/------------------------------------------------

P1 Bit Registers

------------------------------------------------/

sbit P1_0 = 0x90;

sbit P1_1 = 0x91;

sbit P1_2 = 0x92;

sbit P1_3 = 0x93;

sbit P1_4 = 0x94;

sbit P1_5 = 0x95;

sbit P1_6 = 0x96;

sbit P1_7 = 0x97; /

------------------------------------------------

SCON Bit Registers

------------------------------------------------/

sbit RI = 0x98;

sbit TI = 0x99;

sbit RB8 = 0x9A;

sbit TB8 = 0x9B;

sbit REN = 0x9C;

sbit SM2 = 0x9D;

sbit SM1 = 0x9E;

sbit SM0 = 0x9F;

/------------------------------------------------

P2 Bit Registers

------------------------------------------------/

sbit P2_0 = 0xA0;

sbit P2_1 = 0xA1;

sbit P2_2 = 0xA2;

sbit P2_3 = 0xA3;

sbit P2_4 = 0xA4;

sbit P2_5 = 0xA5;

sbit P2_6 = 0xA6;

sbit P2_7 = 0xA7;

/------------------------------------------------

IE Bit Registers

------------------------------------------------/

sbit EX0 = 0xA8; / 1=Enable External interrupt 0 /

sbit ET0 = 0xA9; / 1=Enable Timer 0 interrupt /

sbit EX1 = 0xAA; / 1=Enable External interrupt 1 /

sbit ET1 = 0xAB; / 1=Enable Timer 1 interrupt /

sbit ES = 0xAC; / 1=Enable Serial port interrupt /

sbit ET2 = 0xAD; / 1=Enable Timer 2 interrupt / sbit EA = 0xAF; / 0=Disable all interrupts /

/------------------------------------------------

P3 Bit Registers (Mnemonics & Ports)

------------------------------------------------/

sbit P3_0 = 0xB0;

sbit P3_1 = 0xB1;

sbit P3_2 = 0xB2;

sbit P3_3 = 0xB3;

sbit P3_4 = 0xB4;

sbit P3_5 = 0xB5;

sbit P3_6 = 0xB6;

sbit P3_7 = 0xB7; sbit RXD = 0xB0; / Serial data input /

sbit TXD = 0xB1; / Serial data output /

sbit INT0 = 0xB2; / External interrupt 0 /

sbit INT1 = 0xB3; / External interrupt 1 /

sbit T0 = 0xB4; / Timer 0 external input /

sbit T1 = 0xB5; / Timer 1 external input /

sbit WR = 0xB6; / External data memory write strobe /

sbit RD = 0xB7; / External data memory read strobe /

/------------------------------------------------

IP Bit Registers

------------------------------------------------/

sbit PX0 = 0xB8;

sbit PT0 = 0xB9;

sbit PX1 = 0xBA;

sbit PT1 = 0xBB;

sbit PS = 0xBC;

sbit PT2 = 0xBD;

/------------------------------------------------

PSW Bit Registers

------------------------------------------------/

sbit P = 0xD0;

sbit FL = 0xD1;

sbit OV = 0xD2;

sbit RS0 = 0xD3;

sbit RS1 = 0xD4;

sbit F0 = 0xD5;

sbit AC = 0xD6;

sbit CY = 0xD7;

/------------------------------------------------

Interrupt Vectors:

Interrupt Address = (Number 8) + 3

------------------------------------------------/

#define IE0_VECTOR 0 / 0x03 External Interrupt 0 /

#define TF0_VECTOR 1 / 0x0B Timer 0 /

#define IE1_VECTOR 2 / 0x13 External Interrupt 1 /

#define TF1_VECTOR 3 / 0x1B Timer 1 /

#define SIO_VECTOR 4 / 0x23 Serial port / #endif

头文件(二)

/--------------------------------------------------------------------------

INTRINSH Intrinsic functions for C51

Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc

All rights reserved

--------------------------------------------------------------------------/

#ifndef __INTRINS_H__

#define __INTRINS_H__ extern void _nop_ (void);

extern bit _testbit_ (bit);

extern unsigned char _cror_ (unsigned char, unsigned char);

extern unsigned int _iror_ (unsigned int, unsigned char);

extern unsigned long _lror_ (unsigned long, unsigned char);

extern unsigned char _crol_ (unsigned char, unsigned char);

extern unsigned int _irol_ (unsigned int, unsigned char);

extern unsigned long _lrol_ (unsigned long, unsigned char);

extern unsigned char _chkfloat_(float); #endif

超声波测距学习板,可应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于如液位、井深、管道长度的测量等场合。要求测量范围在027~400m,测量精度1cm,测量时与被测物体无直接接触,能够清晰稳定地显示测量结果。超声波测距原理

超声波发生器内部结构有两个压电晶片和一个共振板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频时,压电晶片将会发生共振,并带动共振板振动,便产生超声波。反之,如果两电极间未外加电压,当共振板接收到超声波本时,将压迫压电晶片作振动,将机械能转换为电信号,就成为超声波接收器。在超声探测电路中,发射端得到输出脉冲为一系列方波,其宽度为发射超声的时间间隔,被测物距离越大,脉冲宽度越大,输出脉冲个数与被测距离成正比。超声测距大致有以下方法:① 取输出脉冲的平均值电压,该电压 (其幅值基本固定 )与距离成正比,测量电压即可测得距离;② 测量输出脉冲的宽度,即发射超声波与接收超声波的时间间隔 t,故被测距离为 S=1/2vt。本测量电路采用第二种方案。由于超 声波 的声速 与温度有关,如果温度变化不大,则可认为声速基本不变 。如果测距精度要求很高,则应通 过温度补偿 的方法加以校正。超声波测距适用于高精度的中长距离测量。因为超声波在标准空气中的传播速度为33145米/秒,由单片机负责计时,单片机使用120M晶振,所以此系统的测量精度理论上可以达到毫米级。

采用AT89C51或AT89S51单片机,晶振:12M,单片机用P10口输出超声波换能器所需的40K方波信号,利用外中断0口监测超声波接收电路输出的返回信号,显示电路采用简单的4位共阳LED数码管,断码用74LS244,位码用8550驱动

超声波测距的算法设计: 超声波在空气中传播速度为每秒钟340米(15℃时)。X2是声波返回的时刻,X1是声波发声的时刻,X2-X1得出的是一个时间差的绝对值,假定X2-X1=003S,则有340m×003S=102m。由于在这102m的时间里,超声波发出到遇到返射物返回的距离。

硬件部分采用AT89C51或AT89S51单片机,晶振:12M,单片机用P10口输出超声波换能器所需的40K方波信号,利用外中断0口监测超声波接收电路输出的返回信号,显示电路采用简单的4位共阳LED数码管,断码用74LS244,位码用8550驱动 主要由单片机系统及显示电路、超声波发射电路和超声波检测接收电路三部分组成。采用AT89S51来实现对CX20106A红外接收芯片和TCT40-10系列超声波转换模块的控制。单片机通过P10引脚经反相器来控制超声波的发送,然后单片机不停的检测INT0引脚,当INT0引脚的电平由高电平变为低电平时就认为超声波已经返回。计数器所计的数据就是超声波所经历的时间,通过换算就可以得到传感器与障碍物之间的距离。

1单片机系统及显示电路

单片机采用89S51或其兼容系列。采用12MHz高精度的晶振,以获得较稳定的时钟频率,减小测量误差。

单片机用P10端口输出超声波转化器所需的40KHz方波信号,利用外中断0口检测超声波接受电路输出的返回信号。显示电路采用简单实用的4位共阳LED数码管,段码用74LS244驱动,位码用PNP三极管驱动。单片机系统及显示电路如下图所示

使用CX20106A集成电路对接收探头受到的信号进行放大、滤波。其总放大增益80db。以下是CX20106A的引脚注释。

1脚:超声信号输入端,该脚的输入阻抗约为40kΩ。

2脚:该脚与地之间连接RC串联网络,它们是负反馈串联网络的一个组成部分,改变它们的数值能改变前置放大器的增益和频率特性。增大电阻R1或减小C1,将使负反馈量增大,放大倍数下降,反之则放大倍数增大。但C1的改变会影响到频率特性,一般在实际使用中不必改动,推荐选用参数为R1=47Ω,C1=1μF。

3脚:该脚与地之间连接检波电容,电容量大为平均值检波,瞬间相应灵敏度低;若容量小,则为峰值检波,瞬间相应灵敏度高,但检波输出的脉冲宽度变动大,易造成误动作,推荐参数为33μf。

4脚:接地端。

5脚:该脚与电源间接入一个电阻,用以设置带通滤波器的中心频率f0,阻值越大,中心频率越低。例如,取R=200kΩ时,f0≈42kHz,若取R=220kΩ,则中心频率f0≈38kHz。

6脚: 该脚与地之间接一个积分电容,标准值为330pF,如果该电容取得太大,会使探测距离变短。

7脚:遥控命令输出端,它是集电极开路输出方式,因此该引脚必须接上一个上拉电阻到电源端,推荐阻值为22kΩ,没有接受信号是该端输出为高电平,有信号时则产生下降。 8脚:电源正极,45~5V。

软硬件调试及性能

超声波测距仪的制作和调试,其中超声波发射和接收采用Φ16的超声波换能器TCT40-16F1(T发射)和TCT40-16S1(R接收),中心频率为40kHz,安装时应保持两换能器中心轴线平行并相距4~8cm,其余元件无特殊要求。若能将超声波接收电路用金属壳屏蔽起来,则可提高抗干扰能力。根据测量范围要求不同,可适当调整与接收换能器并接的滤波电容C4的大小,以获得合适的接收灵敏度和抗干扰能力。

硬件电路制作完成并调试好后,便可将程序编译好下载到单片机试运行。根据实际情况可以修改超声波发生子程序每次发送的脉冲宽度和两次测量的间隔时间,以适应不同距离的测量需要。根据所设计的电路参数和程序,测距仪能测的范围为007~55m,测距仪最大误差不超过1cm。系统调试完后应对测量误差和重复一致性进行多次实验分析,不断优化系统使其达到实际使用的测量要求。后续工作需实验后才能验证 根据参考电路和集成的电路器件测距范围有限10m以内为好。

超声波测距是借助于超声脉冲回波渡越时间法来实现的。设超声波脉冲由传感器发 出到接收所经历的时间为 t,超声波在空气中的传播速度为 c,则从传感器到目标物体 的距离 D 可用下式求出:

D = ct /2

这是它的程序

#include <AT89X51H>

#include <intrinsh>

#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=TH0256+TL0;

TH0=0;

TL0=0;

S=(time187)/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(); //计算

}

}

//

目前国内超声波测距器的设计大多采用汇编语言设计。由于单片机应用系统的日趋复杂,要求所写

的代码规范化,模块化,并便于多人以软件工程的形式进行协同开发,汇编语言作为传统的单片机应用系

统的编程语言,已经不能满足这样的实际需要了,而C语言以其结构化和能产生高效代码满足了这样的需

求,成为电子工程师进行单片机系统编程时的首先编程语言。在本设计中,由于C语言程序有利于实现较

复杂的算法,汇编语言程序具有较高的效率并且容易精确计算程序运行的时间,而超声波测距器的程序既

有较复杂的距离计算又要求精确计算超声波测距时程序运行的时间,所以本设计采用C语言和汇编语言

混合编程来实现。本文论述的是一种基于AT89C52单片机的超声波测距器,可用于汽车倒车等场合⋯。

1设计要求

设计一个超声波测距器,可以应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用

于如液位、井深、管道长度的测量等场合。要求测量范围在0.10—5.00 m,测量精度lem,测量时与被测物

体无直接接触,能够清晰稳定地显示测量结果。

2设计思路

2.1超声波及其测距原理

超声波是指频率高于20KHz的机械波。为了以超声波作为检测手段,必须产生超声波和接收超声波。

完成这种功能的装置就是超声波传感器,习惯上称为超声波换能器或超声波探头。超声波传感器有发送

器和接收器,但一个超声波传感器也可具有发送和接收声波的双重作用。超声波传感器是利用压电效应

的原理将电能和超声波相互转化,即在发射超声波的时候,将电能转换为超声波,发射超声波;而在收到回

波的时候,则将超声振动转换成电信号。

超声波测距的原理一般采用渡越时间法TOt(time of fliight)。首先测出超声波从发射到遇到障碍物返

回所经历的时间,再乘以超声波的速度就得到二倍的声源与障碍物之间的距离。测量距离的方法有很多

种,短距离的可以用尺,远距离的有激光测距等,超声波测距适用于高精度的中长距离测量。因为超声波

收稿日期:2008-04-08

作者简介:周功明(1963一),男,副教授,主要研究方向:电子信息科学技术。

·50· 绵阳师范学院学报(自然科学版) 第27卷

在标准空气中的传播速度为331.45粑秒,由单片机负责计时,单片机使用12.0M晶振,所以此系统的测

量精度理论上可以达到毫米级。由于超声波指向性强,能量消耗缓慢,在介质中传播距离远,因而超声波

可以用于距离的测量。利用超声波检测距离,设计比较方便,计算处理也较简单,并且在测量精度方面也

能达到要求。

超声波发生器可以分为两类:一类是用电气方式产生超声波,一类是用机械方式产生超声波。本课题

属于近距离测量,可以采用常用的压电式超声波换能器来实现7。

2.2超声波测距器的系统框图

根据设计要求并综合各方面因素,可以采用AT89C52单片机作为主控制器,用动态扫描法实现LED

数字显示,超声波驱动信号用单片机的定时器完成,超声波测距器的系统框图如下图l所示¨2|:

3系统组成

3.1硬件部分

主要由单片机系统及显示电路、超声波发射电路

和超声波检测接收电路三部分组成。采用AT89C52来

实现对CX20106A红外接收芯片和TCT40—10系列超

声波转换模块的控制。单片机通过P1.0引脚经反相

超声波接收E :, LED显示单片机r

/\

Z ∑

超声波发送高控制器

:> 扫描驱动

图1 超声波测距器系统设计框图

Fig.1 Ultrasonic eLangi.g system design diagram

器来控制超声波的发送,然后单片机不停的检测INT0引脚,当INTO引脚的电平由高电平变为低电平时就

认为超声波已经返回。计数器所计的数据就是超声波所经历的时间,通过换算就可以得到传感器与障碍

物之间的距离¨≈J。

3.2软件部分

主要由主程序、超声波发生子程序、超声波接收中断程序及显示子程序等部分。

4系统硬件电路设计

4.1单片机系统及显示电路

单片机采用AT89C52或其兼容系列。采用12MHz高精度的晶振,以获得较稳定的时钟频率,减小测

量误差。单片机用P1.0端口输出超声波转化器所需的40KHz方波信号,利用外中断0口检测超声波接收

电路输出的返回信号。显示电路采用简单实用的4位共阳LED数码管,段码用74LS244驱动,位码用PNP

三极管驱动。单片机系统及显示电路如下图2所示‘1。31。

图2单片机及显示电路原理图

Fig.2 MCU and display circuit schematics

第8期周功明等:基于AT89C52单片机的超声波测距器设计·51.

4.2超声波发射电路原理图

压电超声波转换器的功能:利用压电晶体谐振工作。内部结构如图3‘3Ⅲ1所示,它有两个压电晶片和

一个共振板。当它的两极外加脉冲信号,其频

率等于压电晶片的固有振荡频率时,压电晶片PI.O

将会发生共振,并带动共振板振动产生超声波,

这时它就是一超声波发生器;如没加电压,当共

振板接收到超声波时,将压迫压电振荡器作振

动,将机械能转换为电信号,这时它就成为超声

波接收转换器。超声波发射转换器与接收转换

器其结构稍有不同。

4.3超声波检测接收电路图3发射电路原理图

参考红外转化接收电路,本设计采用集成

F‘g·3 U1‘ms。nie劬啪mi‘妇c‘咖1‘∞hem蚯c

电路CX20106A,这是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控

常用的载波频率38KHz与测距超声波频率

40KHz较为接近,可以利用它作为超声波检测

电路。如图43 J[71超声波检测接收电路原理图

所示,适当改变C4的大小,可改变接收电路的

灵敏度和抗干扰能力。⋯. J。j-二

5系统程序设计

超声波测距软件设计主要由主程序,超声

波发射子程序,超声波接收中断程序及显示子

程序组成。下面对超声波测距器的算法,主程

序,超声波发射子程序和超声波接收中断程序

逐一介绍。

5.1超声波测距器的算法设计

GND

图4超声波检测接收电路原理图

Fig.4 Ultrasonic receiver and detection circuit schematic

图5_列示意了超声波测距的原理,即超声

波发生器T在某一时刻发出的一个超声波信号,当超声波遇到被测物

体后反射回来,就被超声波接收器R所接受。这样只要计算出发生信

号到接收返回信号所用的时问,就可算出超声波发生器与反射物体的

距离。

距离计算公式:d=s/2=(c木t)/2,其中d为被测物与测距器的距

离,s为声波的来回路程,c为声速,t为声波来回所用的时间。

图5超声波测距原理图

Fig.5 Ultrasonic Ranging schematic

声速c与温度有关(见表1),如温度变化不大,则可认为声速是基

本不变的。如果测距精度要求很高,则应通过温度补偿的方法加以校正。声速确定后,只要测得超声波往

返时间,即可求得距离。在系统加入温度传感器来监测环境温度,可进行温度补偿。这里可以用DSl8820

测量环境温度,根据不同的环境温度确定一声速提高测距的稳定性。为了增强系统的可靠性,可在软硬件

上采用抗干扰措施。

表1不同温度下的超声波速表

Table I Under different temperatures ultrasonic velocity Table

·52· 绵阳师范学院学报(自然科学版) 第27卷

5.2主程序

主程序首先对系统环境初始化,设置定时器1D工作模式为16位的定时计数器模式,置位总中断允许

位EA并给显示端Po和P2清0。然后调用超声波发生子程序送出一个超声波脉冲,为避免超声波从发射

器直接传送到接收器引起的直接波触发,需延迟0.1ms(这也就是测距器会有一个最小可测距离的原因)

后,才打开外中断0接收返回的超声波信号。由于采用12MHz的晶振,机器周期为lus,当主程序检测到接

收成功的标志位后,将计数器哟中的数(即超声波来回所用的时

间)按下式计算即可测得被测物体与测距仪之间的距离,设计时取

20℃时的声速为344 m/s则有:d=(C木TO)/2=172T0/10000cm

(其中,ID为计数器,ID的计数值)。

测出距离后结果将以十进制BCD码方式LED,然后再发超声

波脉冲重复测量过程。主程序框图如图6所示。

5.3超声波发生子程序和超声波接收中断程序

超声波发生子程序的作用是通过PI.0端口发送2个左右的

超声波信号频率约40KHz的方波,脉冲宽度为12 US左右,同时把

计数器,ID打开进行计时。超声波测距器主程序利用外中断0检

测返回超声波信号,一旦接收到返回超声波信号(INT0引脚出现

低电平),立即进入中断程序。进入该中断后就立即关闭计时器

,ID停止计时,并将测距成功标志字赋值l。如果当计时器溢出时

还未检测到超声波返回信号,则定时器rID溢出中断将外中断0关

闭,并将测距成功标志字赋值2以表示此次测距不成功H旬J。

5.4超声波测距器的部分程序清单

/宰超声波测距器d片机c程序使用Keil C51 ver 7.09

木/

#include<re951.h>

#define uchar unsigned int

#define uint unsigned int

#define ulong unsigned long

Extem void ca_t(void);

Extem void delay(uint);

Extem void display(unchar);

Data unehar testtok;

/木超声波测距器主程序术/

Void main(void)

{data unchar dispram[5];

data uint i;

data ulong time;

p0=0xff;

pl=0xff;

TMOD=0X11:

IE=0x80;

While(1)

{.“}

开始

系统初始化

发送超声波脉冲

等待发射超声波

计算距离

显示结果0.5s

图6主程序框图

diagram of the main program

第8期周功明等:基于AT89C52单片机的超声波测距器设计·53·

6软硬件调试

超声波测距仪的制作和调试,其中超声波发射和接收采用中15的超声波换能器TCT40一IOFl(T发

射)和TCT40—10S1(R接收),中心频率为40kHz,安装时应保持两换能器中心轴线平行并相距4—8 cm,

其余元件无特殊要求。若能将超声波接收电路用金属壳屏蔽起来,则可提高抗干扰能力。根据测量范围

要求不同,可适当调整与接收换能器并接的滤波电容C4的大小,以获得合适的接收灵敏度和抗干扰能力。

硬件电路制作完成并调试好后,便可将程序编译好下载到单片机试运行。根据实际情况可以修改超

声波发生子程序每次发送的脉冲宽度和两次测量的间隔时间,以适应不同距离的测量需要∞71。

7 结束语

本文设计的是基于AT89C52单片机的超声波测距器,可应用于汽车倒车等场合,提醒驾驶员倒车时有

效的避开可能对倒车造成危害的障碍物和行人,从而有效避免由于倒车造成的汽车碰撞或擦伤经济损失

和人身安全问题。具有较强的实用性。

参考文献:

[1] 周功明.基于AT89C2051d片机的防盗自动报警电子密码锁系统设计[J].绵阳师范学院学报,2007,26(5):112—

116.

[14]

张齐.单片机应用系统设计技术一基于c语言编程[M].北京:电子工业出版社,2006.

李光飞.单片机c程序设计实例指导[M].北京:航空航天大学业出版社,2005.

楼燃苗,李光飞.51系列单片机设计实例[M].北京:航空航天大学业出版社,2003.

Zhongbo Li.Electronic Technique[M].Beijing:Mechannic Industrical Prees,2003.

赖麒文.8051单片机c语言彻底应用[M].北京:科学业出版社,2002.

何希才.传感器及其应用电路[M].北京:电子工业出版社,2001.

丁元杰.单片微机原理及应用[M].北京:机械工业出版社,2001.

孙串友,孙晓斌.感测技术基础[M].北京:电子工业出版社,2001.

马忠梅.单片机的c语言应用程序设计[M].北京:航空航天大学业出版社,1999.

刘喜昂,周志宇.基予多超声传感器的机器人安全避障技术[J].测控技术,2003,23(2):71—73.

翟国富,刘茂恺.一种实时高精度的机器人用超声波测距处理方法[J].应用声学,1990,15(1):17—24.

Cray C,Swinhoe C F,Myinl.Target controlled infusion of ketamine曲analgessia for TIV A with propof01.Can.J Anesth,1999,

40:957.

R J Higgens.Electronics and Analog Integrated Circuits[M].N.J:Prentice—Hall Inc,2001.

上楼回答有些误区。超声波测距现在一个探头也可以完成发射与接受并测出距离。

2:超声波的测试的距离肯定>1米。关于精确到01毫米就有难度了。它不仅与探头的频率等有关还要考虑他和主机的整合行比如(盲区)等不过现在用它来测距的话必须要与被测的工件耦合。因为不管什么波形都是需要在介质比如水,钢板等中传播

3:肯定可以显示出距离!我们现在用的仪器很简单的价格就几千块

在讲讲原理超声波他通过同步电路(触发电路)产生数个脉冲触发仪器的扫描电路,发射电路就发射了,然后就是就收了也就是通过(射频器,检波器,视频放大器等回收··

如果还有什么您可以给我留言!祝您好运 谢谢了

以上就是关于我自己编的超声波测距51单片机c语言编程错哪了,,感觉延时很久数码管才有反应,哪个地方导致的延时全部的内容,包括:我自己编的超声波测距51单片机c语言编程错哪了,,感觉延时很久数码管才有反应,哪个地方导致的延时、51单片机 超声波红外避障 程序、单片机超声波测距系统原理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9286503.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存