超声波程序.docx

上传人:b****3 文档编号:5332502 上传时间:2022-12-15 格式:DOCX 页数:25 大小:27.11KB
下载 相关 举报
超声波程序.docx_第1页
第1页 / 共25页
超声波程序.docx_第2页
第2页 / 共25页
超声波程序.docx_第3页
第3页 / 共25页
超声波程序.docx_第4页
第4页 / 共25页
超声波程序.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

超声波程序.docx

《超声波程序.docx》由会员分享,可在线阅读,更多相关《超声波程序.docx(25页珍藏版)》请在冰豆网上搜索。

超声波程序.docx

超声波程序

本人收藏的的一些超声波程序,希望对大家

有用(还有原理图,需要的话去我空间去

):

程序一:

#include

#defineucharunsignedchar

#defineuintunsignedint

#definecount4

uchardataIRcode[4];//定义一个4字节的数组用来存储代码uchartable[4];

ucharenled[4]={0x1f,0x2f,0x4f,0x8f};

ucharCodeTemp,temp,tt;//编码字节缓存变量uchar

i,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2;

//延时用的循环变量

uintdistance,distance1,time;//

sbitIRsignal=P3T;//HS0038

sbitcome=P3A3;

sbitd=P1A1;//发送码

sbitBZ=P1A0;

sbits=P3A7;//38k

sbitss=P3A6;//38k

ucharm;//开关控制

//sbitn=P2;//电机反转code

距离,time

接收头OUT端直接连P3.2(INT0)

unsigned

seg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28};

显示段码

char

//

/****************************

voidtimer0()interrupt1

{

TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//

tt++;//发送超声波个数}

/****************************************************/voidDelay0_9ms(void)

定时器0中断

***********************

*/

延时0.9ms子程序

 

{

ucharj,k;

for(j=18;j>0;j--)for(k=20;k>0;k--);

}

/***************************

voidDelay1ms(void)

{

uchari,j;

for(i=2;i>0;i--)for(j=230;j>0;j--);

}

/***************************

voidDelay4_5ms(void)

{

uchari,j;

for(i=10;i>0;i--)for(j=225;j>0;j--);

}

/****************************

************************/

延日寸1ms了稈,序**********************/

延时4.5ms子程序*********************

程序

voidDelay(void)

{

uchari,j,k;

for(i=100;i>0;i--)for(j=100;j>0;j--)

for(k=3;k>0;k--);

}

/****************************

************************/

程序

//

延时程序

voidledDelay(unsignedinttc)

{unsignedinti,j;for(i=0;i<10;i++)for(j=0;j

}

/****************************************************************/

//定寸器1中断,用做超声波测距无回波

voidtimer1()interrupt3

{TR1=0;ET1=0;

EX1=0;

TH1=0;

 

TL1=0;

}

/***********************voidLed(intdate)//{inti;

table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;

显示程序*********************/

显示函数

date=0;

for(i=0;i<120;i++)

{

P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器

P0=seg7code[table[i%4]];//取出千位数,查表,输出。

ledDelay(15);

}

//外部中断1,用做判断超声波回波电平说明测试成功voidint1()interrupt2//外部中断1是0号{

EX1=0;//关闭外部中断1

TR1=0;

ET1=0;

succeed_flag=1;//测试成功标志

超声波测

路子

函数

voidsound()

{ET0=1;TR0=1;//开38K超声波输入端while(tt!

=1);//发送几个脉冲的超声tt=0;//清零重新计数

ET0=0;TR0=0;

tt=0;//清零重新计数

TF1=0;//计数溢出标志

TH1=0;//定时器1清零

TL1=0;//定时器1清零

ET1=1;//开定时器1

TR1=1;//启动定时器1

EX1=1;//打开外部中断1succeed_flag=0;

while(EX1==1);//等待回波标志if(succeed_flag==1)//测试成功

{time=TH1*256+TL1;//回波响应时间distance=time*1.72/100;//换算成路程

Led(distance);//显示测到的距离

EX1=1;//开中断1

}

if(succeed_flag==0)//测试不成功或超出时间

{

Led(3333);//表示测不到回波

}

}

红外解码

中断0解码服务子程序

P3.2(INTO)进行电平变化

如果0.9ms后IRsignal=1,说明不是引导码

如果持续了10X0.9ms=9ms的低电平,说

跳过持续4.5ms的高电平

分别读取4个字节

每个字节8个bit的判断

等待上升沿此处用得很好:

因为0与1的相同部分

从上升沿那一时刻开始延时0.9ms(因

voidint0(void)interrupt0using2{

可以这样,跳入中断,但仍可对

EA=0;//?

?

?

的读取for(k=0;k<10;k++){

Delay0_9ms();if(IRsignal==1)//

{k=10;break;}elseif(k==9)//明是引导码

{while(IRsignal==0);Delay4_5ms();//for(i=0;i<4;i++)//

{for(j=1;j<=8;j++)//

{while(IRsignal==0);//0.56ms的低电平(接收时)是代码

Delay0_9ms();//

为0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignalif(IRsignal==1)//如果IRsignal是"1",高位置"1",并向

右移一位

{

Delay1ms();//为什么要延时1ms呢?

因为要使IRsignal

跳至低电平(即0.56ms的0与1相同部分上)

CodeTemp=CodeTemp|0x80;//此处的算法很好

if(j<8)CodeTemp=CodeTemp>>1;

}elseif(j<8)

如果IRsignal是"0",则直接向右移一位,

{CodeTemp=CodeTemp>>1;}//自动补"0"

IRcode[i]=CodeTemp;

CodeTemp=0;

}

for(i=0;i<4;i++)//

{

SBUF=IRcode[i];//

while(!

TI);//

TI=0;

}

Delay();

}

}

switch(IRcode[2])//数据位

通过串口将代码发出

引导码地址码数据码数据反码等待一个字节发送完毕

{

case69:

m=0xfe;break;//电机上升

case70:

m=0xff;break;//电机停止

case71:

m=0xfc;break;//电机下降

case22:

a=0;break;

case25:

key=1;break;//功能键

case12:

a=1;;break;

case24:

a=2;;break;case94:

a=3;;break;case8:

a=4;;break;case28:

a=5;;break;case90:

a=6;;break;case66:

a=7;;break;case82:

a=8;;break;case74:

a=9;;break;

}

EA=1;//开总中断

}

I*****************************************************************

初始化程序

voidinitUart(void)

{

TMOD|=0x11;//定时器T1,TO都用方式1,16位PCON|=0x80;

TH1=0;//定时器T1高位初始化

TL1=0;//定时器T1低位初始化ET1=1;//开定时器1TR1=1;//用时才启动//TMOD=0x01;

TH0=(65536-count)/256;//定时器T0初值TL0=(65536-count)%256;//EA=1;//开总中断

ETO=O;〃先关上38KHz用到的时候再开

TRO=O;//先关上38KHz用到的时候再开}

]*****************************************************************'

//设置电机到达的高度

voidscankey()

{

while(IRcode[2]==25)

{Led(1111);//显示1111表示进入了功能菜单while(IRcode[2]!

=25)

{BZ=1;//开掉蜂鸣器

h仁10*a;〃设置10位

IRcode[2]=1;//进入个位标志

Led(h1);//显示设置多少十

while(IRcode[2]!

=1)

{h=h1+a;//十位加个位

Led(h);//显示设置到达的高度

key1=1;//作用用于退出死循环

if(IRcode[2]==25)//再次按功能键则完成设置{break;}

}

}

if(key1==1)//退出死循环

{key1=O;

IRcode[2]=O;

break;

}voidhigh()

}

高度判

断函数

{

if(95<=distance||((h-5)<=distance&&distance<=(h+5)))//提前停电机

{

IRcode[2]=0;//清零红外接收的数据

m=0xff;//关电机

BZ=0;//开蜂鸣器

Delay();

BZ=1;//关

}

}

I*****************************************************************

主程序

voidmain()

{

P2=0xFF;//数码管测试ledDelay

(1);

P2=0xff;

initUart();

IT1=1;

IT0=1;//INT0为负边沿触发,(1:

负边沿触发,0:

低电平触发)

EX0=1;//外部中断INT0开,(1:

开,0:

关)

EA=1;//开所有中断

CodeTemp=0;//初始化红外编码字节缓存变量temp=0;

tt=0;

m=0xff;

h=1;

while

(1)

{sound();//调超声测距函数测距

SBUF=P3;//P3口信息返回

if(!

TI)

{TI=0;

}

high();//高度判断

scankey();//如果按的功能键则进入此函数

}

}

程序二:

//超声波模块程序

//超声波模块程序

//Trig=P2A0

//Echo=卩3八2

#include

#defineucharunsignedchar

#defineuintunsignedint//

voiddelay(uintz)

{

uintx,y;

for(x=z;x>0;x--)for(y=110;y>0;y--);

}

//

voiddelay_20us()

{

uchara;for(a=0;a<100;a++);

}//***************************************************************

//显示数据转换程序

voiddisplay(uinttemp)

{

ucharge,shi,bai;

bai=temp/100;

shi=(temp%100)/10;

ge=temp%10;

wela=1;

P0=0xf7;

wela=0;

dula=1;

P0=table[bai];

dula=0;

delay

(1);

dula=1;

P0=0x00;//关位码dula=0;

wela=1;

P0=0xef;

wela=0;

dula=1;

P0=table[shi];

dula=0;

delay

(1);

dula=1;

P0=0x00;//关位码dula=0;

dula=1;P0=table[ge];

dula=0;wela=1;

P0=0xdf;wela=0;

delay

(1);

关位码

dula=1;

P0=0x00;//dula=0;

}

voidmain()

{

uintdistance;

首先拉低脉冲输入引脚

打开总中断0定时器1,16位工作方式

test=0;

Trig=0;//

EA=1;//

TMOD=0x10;//while

(1)

EA=0;

//

关总中断

Trig=1;

//

超声波输入端

delay_20us();//

延时20us

Trig=0;

//

产生一个20us的脉冲

while(Echo=

=0);//

等待Echo回波引脚变高电平

succeed_flag=0;//

清测量成功标志

EA=1;

EX0=1;

//

打开外部中断0

TH1=0;

//

定时器1清零

TL1=0;

//

定时器1清零

TF1=0;

//

计数溢出标志

TR1=1;

//

启动定时器1

delay(20);

//

等待测量的结果

TR1=0;

//

关闭定时器1

EX0=0;

//

关闭外部中断0

if(succeed_flag==1)

{

time=timeH*256+timeL;

distance=time*0.172;//厘米

display(distance);

if(succeed_flag==0)

{

distance=0;//没有回波则清零test=!

test;//测试灯变化

}

}

}//外部中断0,用做判断回波电平

voidexter()interrupt0{

timeH=TH1;//timeL=TL1;//succeed_flag=1;//EX0=0;//

//外部中断0是0号

取出定时器的值

取出定时器的值至成功测量的标志关闭外部中断

}

//****************************************************************

//定时器1中断,用做超声波测距计时

voidtimer1()interrupt3//{

TH1=0;

TL1=0;

}

程序三:

#include#include

#defineucharunsignedchar#defineuintunsignedintunsignedinttime;

unsignedintS,s_false;unsignedlongnum1;

bitflag;

sbitTrig=P3A6;//

定义引脚

sbitEcho=P3A7;

sbitlcdrs=P2A0;//

命令数据

sbitlcdrw=P2A1;//

读写

sbitlcde=P2A2;//

sbitled=P3A5;

voiddelay(uintz)

{

uintx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

/*voiddelay_20us()

{

uchara;

for(a=0;a<100;a++);

}

*/

//***************************************************************

voidwrite_com(unsignedcharcom)

lcdrs=0;

P0=com;

delay(5);

lcde=1;

delay(5);

lcde=0;

}

voidwrite_data(unsignedcharzifu)

{

lcdrs=1;

P0=zifu;

delay(5);

lcde=1;

delay(5);

lcde=0;

}

voidwrite_temp(uintt_emp)

{

ucharqian,bai,shi,ge;

qian=t_emp/1000;bai=(t_emp%1000)/100;

shi=(t_emp%100)/10;

ge=t_emp%10;

write_com(0x80);

write_data(0x30+qian);

delay

(1);

write_data(0x30+bai);

delay

(1);

write_data(0x30+shi);

delay

(1);

write_data(0x30+ge);

delay

(1);

delay(100);

}

/********************************************************/

voidT0_time()interrupt1//T0中断用来计数器溢出,超过测距范围

{

flag=0;//中断溢出标志,失败

TH0=0;

TL0=0;

TR0=0;//关闭计数

}

/********************************************************/

voidT1_timer()interrupt3//中断

{

TH1=(65536-50000)/256;

TL1=(65536-50000)%256;

num1++;

if(num1==20)

{

num1=0;

led=~led;

}

}

voidStartModule()//启动模块

启动一次模块

{

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;

}

/********************************************************/

voidCount(void)

{

time=TH0*256+TL0;

TH0=0;

TL0=0;

//超出测量范围显示“-

S=(time*1.7)/100;//算出来是CM

if(((S<8)||(S>=600))||flag==0)

失败

{

//flag=1;

s_false=1000;

write_com(0x80);

write_data('e');

delay(5);

write_data('r');

delay(5);

write_data('r');

delay(5);

write_data('o');

delay(5);

write_data('r');

delay(5);

//write_temp(s_false);

}

else

{

write_temp(S);

}

}

/*******************************************************

/*******************************************************

voidinit()

{

lcde=0;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);lcdrw=0;

}

 

voidmain(){

//unsignedcharTempCyc;

delay(500);//启动等待,等LCM讲入工作状态

lcdrw=0;

init();//LCM初始化

delay(500);//延时片刻(可不要)

while

(1)

{

设T0为方式1,GATE=;1

TMOD=0x11;//

TH0=0;

TL0=0;

ET0=1;//允许T0中断

ET1=1;

TR1=1;

EA=1;//

开启总中断

Trig=0;

Echo=0;

while

(1)

{

StartModule();

当echo为零时等待当echo为零时等待,中

开启计数

当echo为1计数并等待

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1