欢迎来到得力文库 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
得力文库 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    51单片机超声波测距离(带温度补偿)(共19页).doc

    • 资源ID:16269816       资源大小:524.50KB        全文页数:19页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    51单片机超声波测距离(带温度补偿)(共19页).doc

    精选优质文档-倾情为你奉上超声波模块原理图: 发射 接收原理图PCB:51单片机原理图:软件部分C语言程序:/*= 调试要求: 1.MCU:AT89S52芯片或AT89C52 2.晶振:12MHz 调试注意: 本程序带温度补偿,采用DS18B20测量温度 1.LCD1602液晶屏有显示后,才接入超声波模块。 2.注意超声波模块电源的极性。不清楚请参好淘宝的电路图 3.没有选用频率为12MHz晶振,用了别的频率晶振,单片机定时器的测量值与 发出的40KHz频率脉冲不对。 4.使用者经常误发出20KHZ脉冲当40KHZ脉冲。(40KHz频率脉冲,周期25us, 占空比为50% = 12.5us) 5.如果是用开发板调超声波模块,请检查开发板上的电路是否与超声波模块的 控制脚复用了, 若复用了,请通过跳线分开发板上的电路。 6如果使用的是万用板,请确定单片机的复位电路和晶振电路是否正常,同时 单片机的31脚(EA)记得 接高电平。=*/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/=LCD1602接口定义=/*- |DB0-P2.0 | DB4-P2.4 | RW-P0.1 | |DB1-P2.1 | DB5-P2.5 | RS-P0.2 | |DB2-P2.2 | DB6-P2.6 | E-P0.0 | |DB3-P2.3 | DB7-P2.7 | 注意,P0.0到P0.2需要接上拉电阻 -=*/#define LCM_Data P2 /数据接口#define Busy 0x80 /用于检测LCM状态字中的Busy标识sbit LCM_RW = P01; /读写控制输入端,LCD1602的第五脚sbit LCM_RS = P02; /寄存器选择输入端,LCD1602的第四脚sbit LCM_E = P00; /使能信号输入端,LCD1602的第6脚/=超声波模块定义=sbit RemPin = P32;/ 接收端(这个不能修改,因为是外部中断(INT0)的引脚)sbit TxPin = P31;/ 发射端 /*/ds18b20数字温度传感器控制引脚定义 sbit dq_ds18b20=P33;/定义控制DS18B20/*/LCD显示模块的函数声明void WriteDataLCM(uchar WDLCM);/LCD模块写数据void WriteCommandLCM(uchar WCLCM,BuysC); /LCD模块写指令uchar ReadDataLCM(void);/LCD模块读数据uchar ReadStatusLCM(void);/读LCD模块的忙标void DisplayOneChar (uchar X,uchar Y,uchar ASCII);/在第X+1行的第Y+1位置显示一个字符void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData);void DisplayCursorPos (uchar X, uchar Y);void LCMInit (void);void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);void DisplayCharData (uchar X, uchar Y,uchar ZiFu);/*/延时函数声明void delay25us_40KHz(unsigned char us);void DelayUs(uint us);void DelayMs(uint Ms);void delay_3us();/3US的延时程序void delay_8us(unsigned int t);/8US延时基准程序void delay_50us(unsigned int t);/延时50*T微妙函数的声明/*/DS18B20测温函数定义void w_1byte_ds18b20(uchar value);/向DS18B20写一个字节 uchar r_1byte_ds18b20(void);/从DS18B20读取一个字节的数据void rest_ds18b20(void);/DS18B20复位程序void readtemp_ds18b20(void);/读取温度 void display_temp(void);/温度显示程序/*/参数定义uint length = 0; / 测距的长度0.00Muchar flag = 0; / 测距的标志有信号接收=1uchar templ,temph;uint speed;/根据温度计算出来的声音速度uchar t_b,t_s,t_g,t_x;/从左到右分别存储温度百位,十位,个位,小数位uchar flag1;/温度正负性暂存,1为正数,0为负数const unsigned char tabl3=0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09; /*= 主程序=*/void main(void) uchar i; LCMInit(); /1602初始化 EX0 = 1; /允许总中断中断,使能 INT0 外部中断 ET0 = 1; TMOD=0x11; /设定T0为16位时器,设定T1为16位时器 DisplayOneChar( 0,14,'m'); DisplayListChar(0,0,0, "Distanc: "); /显示字符串 while(1) readtemp_ds18b20(); display_temp();/显示温度 for(i=0;i<20;i+) DisplayIntData(0, 13,length,5,3);/显示测量距离 TH0=0x00; TL0=0x00; TR0=1; /启动定时器0 EA = 1; /允许所有中断 delay25us_40KHz(15); /发出脉冲信号 DelayMs(200); /*/温度显示函数void display_temp() if(flag1=1)/温度为正数时的显示程序 DisplayOneChar( 1,2,'+'); else DisplayOneChar( 1,2,'-'); /显示温度信息 DisplayOneChar( 1,0,'T'); DisplayOneChar( 1,1,':'); DisplayOneChar( 1,3,t_s+0x30); DisplayOneChar( 1,4,t_g+0x30); DisplayOneChar( 1,5,'.'); DisplayOneChar( 1,6,t_x+0x30); /显示速度信息 DisplayOneChar( 1,8,'S'); DisplayOneChar( 1,9,':'); DisplayOneChar( 1,10,speed/100%10+0x30); DisplayOneChar( 1,11,speed/10%10+0x30); DisplayOneChar( 1,12,speed%10+0x30); DisplayOneChar( 1,13,'M'); DisplayOneChar( 1,14,'/'); DisplayOneChar( 1,15,'S');/*/读取温度 void readtemp_ds18b20(void) uchar temp32; rest_ds18b20(); w_1byte_ds18b20(0xcc); /跳过读序列号的操作 w_1byte_ds18b20(0x44); /启动温度转换 delay_8us(2); rest_ds18b20(); w_1byte_ds18b20(0xcc); /跳过读序列号的操作 w_1byte_ds18b20(0xbe); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度 templ=r_1byte_ds18b20(); temph=r_1byte_ds18b20(); if(temph&0xf0)/判断温度的正负性 flag1=0; temph=-temph; templ=-templ; t_x=tabl3templ & 0x0f;/计算温度的小数 temp32=temph & 0x0f; temp32<<=4; templ>>=4; temp32=temp32 | templ; t_b=temp32/100%10;/计算温度的百位数据 t_s=temp32/10%10;/计算温度的十位数据 t_g=temp32%10;/计算温度的个位数据 speed=331.4-0.607*(temp32 | templ); else/为正数 t_x=tabl3templ & 0x0f;/计算温度的小数 temp32=temph & 0x0f; temp32<<=4; templ>>=4; temp32=temp32 | templ; t_b=temp32/100%10;/计算温度的百位数据 t_s=temp32/10%10;/计算温度的十位数据 t_g=temp32%10;/计算温度的个位数据 flag1=1; speed=311.4+0.607*(temp32 | templ); /*= 功 能: 在1602显示一个整数数据 说 明: 显示一个整数数据-9999->32625. 从右至左显示数据5位: =*/void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu) uchar i=0,k=0, BCD5=0; if(Digit>5) Digit=5; if(ZhengShu<0) k=1;/负数示志位 ZhengShu=-ZhengShu; BCD4 = ZhengShu / 10000; /求出万位数据 ZhengShu = ZhengShu % 10000; BCD3 = ZhengShu / 1000; /求出千位数据 ZhengShu = ZhengShu % 1000; BCD2 = ZhengShu / 100; /求出百位数据 ZhengShu = ZhengShu % 100; BCD1 = ZhengShu / 10; /求出十位数据 BCD0 = ZhengShu % 10; /求出个位数据 for(i=0;i<Digit;i+)/输出显示的数值 if(i=XiaoShu)&&(0!=XiaoShu) DisplayOneChar(X,Y-i,'.');/输出小数点 Y= Y-1; DisplayOneChar(X,Y-i,BCDi+0x30); /显示一个字符 if(k=1) DisplayOneChar(X,Y-1,'-');/输出负符/*/读一个字节 uchar r_1byte_ds18b20(void) uchar i=0; uchar value = 0; for (i=0;i<8;i+) value>>=1; dq_ds18b20=0;/ DQ_L; delay_3us(); dq_ds18b20=1; /DQ_H; delay_8us(2); if(dq_ds18b20=1) value|=0x80; delay_8us(6); /延时40us dq_ds18b20=1; return value;/*/子程序功能:向DS18B20写一字节的数据void w_1byte_ds18b20(uchar value) uchar i=0; for(i=0;i<8;i+) dq_ds18b20=1; delay_3us(); dq_ds18b20=0; delay_8us(2); if (value & 0x01) dq_ds18b20=1; /DQ = 1 delay_50us(1); /延时50us 以上 delay_8us(2); value>>=1; dq_ds18b20=1; /DQ = 1/;*/ds18b20复位子程序void rest_ds18b20(void) rest:delay_3us(); /稍做延时 delay_3us(); dq_ds18b20=1; delay_3us(); dq_ds18b20=0;/ DQ_L; delay_50us(11);/480us<T<960us dq_ds18b20=1;/拉高总线 delay_8us(5); if(dq_ds18b20=1) return; delay_50us(2); /延时90us if(dq_ds18b20=1) return; else goto rest; /=超声波模块测试子程序=/*= 注意:是用12MHz晶振 设定延时时间:x*25us 与 产生40KHZ的脉冲=*/void delay25us_40KHz(unsigned char us) while(us-) TxPin = 0; _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); TxPin = 1; _nop_();_nop_(); _nop_();_nop_();TxPin = 1;/*= 中断程序的入口 (注意:接收与发射的电平是相反的)=*/void init0int() interrupt 0 uint timer_us = 0;TR0=0; /关闭定时器0timer_us = TH0*256+TL0;if(timer_us>190)timer_us=timer_us-180;/修正测距的距离 if(timer_us<=735) timer_us=timer_us-96;/二次修正 if(timer_us>5059) timer_us+=29; if(timer_us>5470) timer_us+=29; if(timer_us>6410) timer_us+=29; if(timer_us>7410) timer_us+=29; if(timer_us>8410) timer_us+=29; if(timer_us>9410) timer_us+=29; if(timer_us>10410) timer_us+=29; length = (unsigned long)(speed)*timer_us)/2000;/计算长度,是扩大100倍flag = 0;EA = 0; /禁止所有中断/*= 功 能:在1602显示一个字符数据 说 明:显示一个字符数据0256. 从左至右显示数据3位=*/void DisplayCharData(uchar X, uchar Y,uchar ZiFu) uchar i=0; uchar ValueBCD3; ValueBCD0 = ZiFu / 100; /求出百位数据 ZiFu = ZiFu % 100; ValueBCD1 = ZiFu / 10; /求出十位数据 ValueBCD2 = ZiFu % 10; /求出个位数据 for(i=0;i<3;i+)/输出显示的数值 DisplayOneChar(X,Y+i,ValueBCDi+0x30); /显示一个字符 /*= 超出测量时间=*/void timer0int (void) interrupt 1 TR0=0; /关闭定时器0length = 0; /超出测量时间显示示0 flag = 1; /EA = 0; /禁止所有中断 /*= LCM初始化=*/void LCMInit(void) LCM_Data = 0; WriteCommandLCM(0x38,0); /三次显示模式设置,不检测忙信号 DelayMs(5); WriteCommandLCM(0x38,0); DelayMs(5); WriteCommandLCM(0x38,0); DelayMs(5); WriteCommandLCM(0x38,1); /显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(0x08,1); /关闭显示 WriteCommandLCM(0x01,1); /显示清屏 WriteCommandLCM(0x06,1); / 显示光标移动设置 WriteCommandLCM(0x0C,1); / 显示开及光标设置 DelayMs(100);/*= 显示光标的位置=*/void DisplayCursorPos( unsigned char X, unsigned char Y) X &= 0x1; Y &= 0xF; /限制Y不能大于15,X不能大于1 if (X) Y |= 0x40; /当要显示第二行时地址码+0x40; Y |= 0x80; / 算出指令码 WriteCommandLCM(Y, 1); /这里不检测忙信号,发送地址码/*= 按指定位置显示一串字符:第 X 行,第 y列 注意:字符串不能长于16个字符=*/void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData) unsigned char ListLength; ListLength = 0; X &= 0x1; Y &= 0xF; /限制X不能大于15,Y不能大于1 while (DDataListLength!='0') /若到达字串尾则退出 if (Y <= 0xF) /X坐标应小于0xF DisplayOneChar(X, Y, DDataListLength); /显示单个字符 ListLength+; Y+; DelayMs(delayms);/延时显示字符串 else break;/跳出循环体 /*= 设定延时时间:x*1us=*/void DelayUs(uint us) while(us-); /*= 设定延时时间:x*1ms=*/void DelayMs(uint Ms) uint i,TempCyc; for(i=0;i<Ms;i+) TempCyc = 250; while(TempCyc-); /=LCD1602显示子程序= /*= 写数据函数: E =高脉冲 RS=1 RW=0=*/void WriteDataLCM(unsigned char WDLCM) ReadStatusLCM(); /检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; /若晶振速度太高可以在这后加小的延时 LCM_E = 0; /延时 LCM_E = 1;/*= 写指令函数: E=高脉冲 RS=0 RW=0=*/void WriteCommandLCM(unsigned char WCLCM,BuysC) /BuysC为0时忽略忙检测 if (BuysC) ReadStatusLCM(); /根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1;/*=/读数据=*/unsigned char ReadDataLCM(void) LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; return(LCM_Data);/*= 正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1; DB7: 0 LCD控制器空闲,1 LCD控制器忙。 读状态=*/unsigned char ReadStatusLCM(void) LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); /检测忙信号 return(LCM_Data);/*=功 能: 在1602 指定位置显示一个字符:第一行位置015,第二行1631说 明: 第 X 行,第 y 列 注意:字符串不能长于16个字符=*/void DisplayOneChar( unsigned char X, unsigned char Y, unsigned char ASCII) X &= 0x1

    注意事项

    本文(51单片机超声波测距离(带温度补偿)(共19页).doc)为本站会员(飞****2)主动上传,得力文库 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知得力文库 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于得利文库 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

    © 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

    黑龙江省互联网违法和不良信息举报
    举报电话:0468-3380021 邮箱:hgswwxb@163.com  

    收起
    展开