超声波程序.docx
- 文档编号:5064457
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:27
- 大小:32.09KB
超声波程序.docx
《超声波程序.docx》由会员分享,可在线阅读,更多相关《超声波程序.docx(27页珍藏版)》请在冰豆网上搜索。
超声波程序
本人收藏的的一些超声波程序,希望对大家
有用(还有原理图,需要的话去我空间去下):
程序一:
#include
#defineucharunsignedchar
#defineuintunsignedint
#definecount4
uchardataIRcode[4];//定义一个4字节的数组用来存储代码
uchartable[4];
ucharenled[4]={0x1f,0x2f,0x4f,0x8f};
ucharCodeTemp,temp,tt;//编码字节缓存变量
uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2;//延时用的循环变量
uintdistance,distance1,time;/距/离,time
sbitIRsignal=P3T;//HS0038接收头OUT端直接连P3.2(INT0)
sbitcome=P3A3;
sbitd=P1A1;//发送码
sbitBZ=P1A0;
sbits=P3A7;//38k
sbitss=P3A6;//38kucharm;//开关控制
//sbitn=P2;//电机反转
Seg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28显示段码
定时器0中断
***********************
*/
voidtimer0()interrupt1
{
TH0=(65536-count)/256;
TL0=(65536-count)%256;
S=~S;//产生38K信号
SS=~SS;//
tt++;//发送超声波个数
}
延时0.9ms子程序
voidDelay0_9mS(void)
{
ucharj,k;
for(j=18;j>0;j--)
for(k=20;k>0;k--);
}
延时1ms子程序
voidDelay1ms(void)
uchari,j;
for(i=2;i>0;i--)
for(j=230;j>0;j--);
延时4.5ms子程序
for(j=225;j>0;j--);
}
解码延时子程序
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;//打开外部中断1 succeed_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解码服务子程序 voidint0(void)interrupt0using2 { EA=0;//? ? ? 可以这样, 跳入中断,但仍可对P3.2(INT0)进行电平变化的 读取 for(k=0;k<10;k++) { Delay0_9ms(); if(IRsignal==1) { //如果0.9ms后IRsignal=1,说明不是引导码 k=10;break; } elseif(k==9) //如果持续了10X0.9ms=9ms的低电平,说明是 引导码 { while(IRsignal==0); Delay4_5ms(); //跳过持续4.5ms的高电平 for(i=0;i<4;i++)//分别读取4个字节 { for(j=1;j<=8;j++) //每个字节8个bit的判断 { while(IRsignal==0);//等待上升沿此处用得很好: 因为0.56ms的低电平(接收时)是代码0与1的相同部分 Delay0_9ms();//从上升沿那一时刻开始延时0.9ms(因为 0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal if(IRsignal==1)//如果IRsignal是"1",高位置"1",并向右移一 位 { Delay1ms();//为什么要延时1ms呢? 因为要使IRsignal跳至 低电平(即0.56ms的0与1相同部分上) CodeTemp=CodeTemp|0x80;//此处的算法很好 if(j<8)CodeTemp=CodeTemp>>1; } elseif(j<8) {CodeTemp=CodeTemp>>1;}〃如果IRsignal是"0",则直接向右移一位,自动补"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;//开总中断 } 初始化程序 voidinitUart(void) { TMOD|=0x11;//定时器T1,T0都用方式1,16位PCON|=0x80; TH1=0;//定时器T1高位初始化 TL1=0;//定时器T1低位初始化 ET1=1;//开定时器1 TR1=1;//用时才启动//TMOD=0x01; TH0=(65536-count)/256;//定时器T0初值TL0=(65536-count)%256;// EA=1;//开总中断 ET0=0;//先关上38KHz,用到的时候再开 TR0=0;//先关上38KHz,用到的时候再开} I***************************************************************** //设置电机到达的高度 voidscankey() { while(IRcode[2]==25) {Led(1111);//显示1111表示进入了功能菜单 while(IRcode[2]! =25) {BZ=1;//开掉蜂鸣器 h1=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=0; IRcode[2]=0; break; } 高度判断函数 voidhigh() { if(95<=distance||((h-5)<=distance&&distance<=(h+5)))//提前停电机 { IRcode[2]=0;//清零红外接收的数据 m=0xff;//关电机 BZ=0;//开蜂鸣器 Delay(); BZ=1;//关 } } 主程序 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; test=0; Trig=0;//首先拉低脉冲输入引脚 EA=1;//打开总中断0 TMOD=0x10; //定时器1,16位工作方式 while (1) { EA=0; //关总中断 Trig=1; //超声波输入端 delay_20us();//延时20us Trig=O;//产生一个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//外部中断0是0号 { timeH=TH1;//取出定时器的值 timeL=TL1;//取出定时器的值 succeed_flag=1;〃至成功测量的标志 EX0=0;//关闭外部中断 } //定时器1中断,用做超声波测距计时voidtimer1()interrupt3// { TH1=0; TL1=0; } 程序三: #include #include #defineucharunsignedchar #defineuintunsignedint unsignedinttime; unsignedintS,s_false; unsignedlongnum1; bitflag; sbitTrig=P3A6;//定义引脚 (zlu'5)Aea)ppo> LnvedHPQ七qs揺注CXIvCXIdgpo七qsMM注LVCXIdHMJPo七qsif報令&注ovCMdus」po一七qszvcoduolp山七qs Osno0IAea)ppo? 、 亍aoaaollha)」04 (}xoaxnhx)」04 -Axlu'5 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) { TMOD=0x11;//设T0为方式1,GATE=1; TH0=0; TL0=0; ET0=1;//允许T0中断 ET1=1; TR1=1; EA=1;//开启总中断 Trig=0; Echo=0; while (1) { StartModule(); flag=1; //while(! Echo); while((! Echo)&&flag); 跳出等待 TR0=1; while(Echo&&flag); TR0=0; Count(); delay(120); } } } 程序四: #include //当echo为零时等待 //当echo为零时等待,中断flag //开启计数 //当echo为1计数并等待 //关闭计数 //计算 //80MS #include #defineuintunsignedintunsignedinttime;unsignedintS,s_false;unsignedlongnum1; bitflag; sbitTrig=P3A6;//定义引脚 sbitEcho=P3A7; sbitlcdrs=P2A0;//命令数据sbitlcdrw=P2A1;//读写sbitlcde=P2A2;〃能 sbitled=P3A5; voiddelay
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 超声波 程序