#include <reg51.h> //这个文件是 51寄存器定义的文件,诸如P1,P2等各个端口都有定义
#include <intrins.h> //这个头文件中 有51单片机的循环移位函数 各个函数的意义可以通过百度查到
#define uchar unsigned char //宏定义变量类型 unsigned char为 uchar。这样以后定义变量类型可以用uchar 来替代 unsigned char
#define uint unsigned int //同上
#define ulint unsigned long int
//===============================LCD1602接口定义=====================
/*-----------------------------------------------------
|DB0-----P2.7 | DB4-----P2.3 | RW-------P0.6 |
|DB1-----P2.6 | DB5-----P2.2 | RS-------P0.5 |
|DB2-----P2.5 | DB6-----P2.1 | E--------P0.7 |
|DB3-----P2.4 | DB7-----P2.0 | 注意,P0.5到P0.7需要接上拉电阻
---------------------------------------------------
需要说明的是,这里我为了作电路板的时候走线美观,将P2的端口与液晶
显示的数据端口,对应的顺序颠倒了,所以为了能够准确的输入输出数据
我编写ReverseOrder 这个函数,在输入输出数据前调用,这样就把顺序
调整过来了.
=============================================================*/
#define LCM_Data P2 //数据接口
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P0^6; //读写控制输入端,LCD1602的第五脚
//sbit 不是标准C语言的函数,是51单片机的C51语言特有的,是位定义
//这里定义P0.6 为LCM_RW,以后引用LCM_RW都是在引用P0.6。
sbit LCM_RS = P0^5; //寄存器选择输入端,LCD1602的第四脚
sbit LCM_E = P0^7; //使能信号输入端,LCD1602的第6脚
//===============================超声波模块定义========================
sbit RemPin = P3^2; // 接收端,超声波接收端用终端INT0来接收
sbit TxPin = P1^0; //发射端,用的是P1.0
//***********************************************************************
//ds18b20数字温度传感器控制引脚定义
sbit dq_ds18b20=P3^3;//定义控制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);
uchar ReverseOrder( unsigned char X);
//**********************************************************************
//延时函数声明
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.00M
//uchar flag = 0; // 测距的标志 有信号接收=1-->确实是个多余的标志位,去掉好了(flag)
uchar templ,temph;
uint speed;//根据温度计算出来的声音速度
uchar t_b,t_s,t_g,t_x;//从左到右分别存储温度百位,十位,个位,小数位
uchar flag1;//温度正负性暂存,1为正数,0为负数
uchar time_out=0;
const unsigned char tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//因为51单片机处理浮点数很慢,顾常用查表的方式来代替浮点运算。这种方式是在用空间(代码的大小)来换时间(代码执行的时间)
//因此在readtemp_ds18b20这个函数中用t_x=tabl3[templ & 0x0f]; 计算温度的小数
//具体来说是这样:因为DS18B20 的小数部分在最后4位,顾首先用 templ & 0x0f来提取出第四位
//然后注意到这4位可以表示0-15个值(比如1110对应的十进制数是13),而看DS18B20的手册时(百度文库中就有很多中文的),
//可以看到DS1B820输出的最小单位是0.0625,所以网上有人直接将4位小数部分的值直接乘以0.0625,这样是对的
//但是我们只取了小数点后1位,而且因为考虑到系统的实时性,就希望用查表法来用空间换时间,这样
//0*0.0625=0,这是tab13表的第一位
//1*0.0625=1,这是tab13表的第一位,四舍五入约等于1了
//2*0.0625=1,这是tab13表的第一位,四舍五入约等于1了
//..........以此类推
/*===========================================================================
1主程序
=============================================================================*/
void main(void)
{ uchar i;
LCMInit(); //1602初始化
EX0 = 1; //允许总中断中断,使能 INT0 外部中断
ET0 = 1; //允许T0中断
TMOD=0x11; //设定T0为16位时器,设定T1为16位时器
DisplayOneChar( 0,15,'m'); //显示距离单位 ?m“ -->是的,单位为m
DisplayListChar(0,0,0, "Distance: ");
//显示字符串 参数4是延时吗?第一个参数应该是行数啊?应该是 0,0,4吧?
//是的,参看函数内部,第一条 X &= 0x1;如果是4,那么二级制代码是
//100,第一条语句的意思是将X按位与1做'&'运算,所以只要是偶数都被
//与运算成0了,这里我改回来了,改成0了,一样的
while(1) //可以算响应周期的,所谓超声波测距仪的响应周期就是这个while(1)循环了
//精确计算,还需知道每个函数的执行周期
{
readtemp_ds18b20(); //读取温度
display_temp(); //显示温度
for(i=0;i<20;i++) //这个i是控制什么的?-->主要是为了和DS18B20的检测周期分开
//因为温度不能瞬变,所以这样在while(1)的一次循环内,温度只测一次
//而距离测了20次
{
DisplayIntData(0, 14,length,5,3); //显示测量距离
time_out=1;
TH0=0x00;
TL0=0x00; //启动定时器0 的寄存器 TH0和TL0 清零
TR0=1; //启动定时器0
EA = 1; //允许所有中断
delay25us_40KHz(15); //发出脉冲信号,15?-->是本次发射,一共发射15个周期的声波
DelayMs(300);
}
}
}
/*====================================================================
2超声波模块测试子程序
注意:是用12MHz晶振
设定延时时间:x*25us 与 产生40KHZ的脉冲
====================================================================*/
void delay25us_40KHz(unsigned char us) //精确的计算要用keil的 debug,根据单片机的汇编来计算
{ //当然更常用的方法也是简便的方法是用示波器来试验
//实际上很少有人精确去算的,都是用示波器来看效果,然后
//酌情来增减_nop_();函数来调整,这是一般方法
//但是为了论文写的漂亮可以精确计算的
while(us--)
{
TxPin = 0; //此时,TX端,即 P1.0输出0V?发射超声波? 没错,TX周期性的发射1与0,每调用之前是1
//第一次调用编程0
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();
TxPin = 1; //然后又变成1
//1与0的交替进行2*US次,这里US表示的是声波的个数
_nop_();_nop_();
_nop_();_nop_();
}
TxPin = 1; //最后又重新置为高电平,等待下一次调用..
}
/*=============================================================================
3中断程序的入口即接收模块并计算距离
(注意:接收与发射的电平是相反的)
=============================================================================*/
void init0int() interrupt 0 // interrupt 0是中断关键字,意思是中断0触发后,就调用这个函数
{ //interrupt 是编译器特有的关键字,和char一样,都用黑体和普通代码区分开
uint timer_us = 0;
TR0=0; //关闭定时器0
timer_us = TH0*256+TL0; //修正测距的距离
if(timer_us>190)timer_us=timer_us-180; //修正测距的距离,
//180这个数来源于,定时器中断函
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
超声波测距的proteus (142个子文件)
01 24KB
01 24KB
output.__b 59B
output.__b 59B
chengxu2.__i 38B
chengxu2.__i 13B
STARTUP._ia 34B
STARTUP._ia 28B
STARTUP.A51 5KB
STARTUP.A51 5KB
01_uvopt.bak 59KB
01_uvopt.bak 58KB
01_uvproj.bak 13KB
01_uvproj.bak 13KB
01.Uv2.bak 2KB
01.Uv2.bak 2KB
01_Uv2.Bak 2KB
01_Uv2.Bak 2KB
01.opt.bak 2KB
01.opt.bak 2KB
01_Opt.Bak 1KB
01_Opt.Bak 1KB
Target 1.BAT 344B
Target 1.BAT 334B
STC_ISP_V480.BAT 189B
PENDB-64k.bin 64KB
BINCTR-64k.bin 64KB
nul-ffh.bin 64KB
zero-00.bin 64KB
TWOBALL-64k.bin 64KB
PENDB-62k.bin 62KB
BINCTR-62k.bin 62KB
TWOBALL-62k.bin 62KB
PENDB-32k.bin 32KB
BINCTR-32k.bin 32KB
TWOBALL-32k.bin 32KB
PENDB-16k.bin 16KB
BINCTR-16k.bin 16KB
TWOBALL-16k.bin 16KB
TWOBALL-8k.bin 8KB
BINCTR-8k.bin 8KB
PENDB-8k.bin 8KB
twoball-7k.bin 7KB
twoball-6k.bin 6KB
twoball-5k.bin 5KB
twoball-4k.bin 4KB
twoball-3k.bin 3KB
twoball-2k.bin 2KB
twoball-1k.bin 1024B
twoball-512.bin 512B
chengxu2.c 25KB
chengxu2.c 24KB
Last Loaded 超声波.DBK 133KB
Last Loaded 接收电路.DBK 91KB
Backup Of 发射电路.DBK 59KB
STC_ISP_V480.DDF 785B
msvbvm60.dll 1.33MB
MSJET35.DLL 1021KB
oleaut32.dll 541KB
MSREPL35.DLL 398KB
expsrv.dll 372KB
MSVCRT40.DLL 319KB
MSRD2X35.DLL 246KB
MSCMCCHS.DLL 122KB
MSJINT35.DLL 121KB
MSSTDFMT.DLL 116KB
VB6STKIT.DLL 101KB
VB6CHS.DLL 100KB
VB5DB.DLL 87KB
olepro32.dll 82KB
asycfilt.dll 64KB
vbajet32.dll 30KB
CMDLGCHS.DLL 28KB
DATGDCHS.DLL 25KB
MSJTER35.DLL 24KB
COMCAT.DLL 22KB
MSCOMCHS.DLL 13KB
超声波.DSN 133KB
接收电路.DSN 91KB
发射电路.DSN 68KB
STC_ISP_V480.exe 3.1MB
Table.h 2KB
Table.h 2KB
01.hex 10KB
01.hex 10KB
output1.hex 9KB
output.hex 9KB
output.hex 9KB
LOOP_P0_P1_P2_P3_P4.hex 993B
PENDB.HEX 368B
test_p0_p1_p2_p3.hex 323B
TWOBALL.HEX 198B
BINCTR.HEX 143B
output.LIB 13KB
output.LIB 13KB
output1.lnp 48B
output.lnp 47B
output.lnp 47B
01.lnp 43B
01.lnp 43B
共 142 条
- 1
- 2
资源评论
- wongwong772020-03-07不能用啊,白下了wuguangxin2020-04-16我验证过才上传的。不能用,是怎么个提示?兄弟你也不说明白。
wuguangxin
- 粉丝: 1
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于python实现的基于PyQt5和爬虫的小说阅读系统.zip
- 机械设计整经机上纱自动化sw20非常好的设计图纸100%好用.zip
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功