#include //STC89C52头文件
#define uchar unsigned char
#define uint unsigned int
unsigned int time=0;
unsigned int timer=0;
unsigned long S=0; //距离变量
bit flag =0; //超声波模块量程溢出标志(>5米时置1)
sbit echo=P1^0; //超声波模块的发射端
sbit trig=P1^1; //超声波模块的接收端
sbit ds=P2^2; //DS18B20的信号线
sbit P24=P2^4;
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
sbit P07=P0^7;
int temp;
//八位共阳极
unsigned char code shuzu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//毫秒级延时
void delayms(unsigned char z)
{
unsigned char a,b;
for(a=z; a>0; a--)
for(b=110; b>0; b--);
}
//微秒级延时
void delayus(unsigned char z)
{
while(z)
z--;
}
void delay_ms(unsigned int ms) //1ms延时
{
uchar a;
while(ms--)
for(a=123;a>0;a--);
}
//DS18B20初始化
void ds18b20init()
{
ds=0;
delayus(80); //延时480-960us
ds=1;
delayus(4); //等待应答
}
//DS18B20读命令子程序(读一字节)
uchar dushuju()
{
uchar i,dat,m;
for(i=8;i>0;i--)
{
ds=0;
delayus(1);
ds=1;
delayus(2);
m=ds;
dat=(m<<7)|(dat>>1); //读出的数据最低位在最前面,刚好一个字节在dat里
delayus(8);
}
return dat;
}
//DS18B20写命令子程序(写一字节)
void xiemingling(uint shuju)
{
uint i;
bit m;
for(i=8;i>0;i--)
{
m=shuju&0x01;
shuju=shuju>>1;
if(m) //写1
{
ds=0;
delayus(2);
ds=1;
delayus(8);
}
else //写0
{
ds=0;
delayus(8);
ds=1;
delayus(2);
}
}
}
//DS18B20开始获取温度并转换
void zhuanhuan()
{
ds18b20init();
delayms(1);
xiemingling(0xcc); //写跳过读ROM指令
xiemingling(0x44); //写温度转换命令
}
//DS18B20读寄存器中存储的温度数据
int duwendu()
{
uint a,b;
ds18b20init();
delayms(1);
xiemingling(0xcc); //跳过ROM,忽略64位ROM地址
xiemingling(0xbe); //读内部RAM中的9字节的温度数据
a=dushuju(); //读低8位
b=dushuju(); //读高8位
b=b<<8; //高8位左移8位
temp=b|a; // 高8位和低8位组合为1个字
temp=temp*0.0625; //温度在寄存器中位12位,分辨率为0.0625度
return temp;
}
//显示子程序
void xianshi(unsigned long num)
{
unsigned char bai,shi,ge;
bai=num/100; //分离三位距离数据
shi=num%100/10;
ge=num%10;
P24=0;
P0=shuzu[ge];
delay_ms(1);
P24=1;
P25=0;
P0=shuzu[shi];
P07=1;
delay_ms(1);
P25=1;
P26=0;
P0=shuzu[bai];
delay_ms(1);
P26=1;
// P24=0;
// P0=shuzu[bai];
// P07=1;
// delay_ms(1);
// P24=1;
}
//计算距离子程序
void Conut()
{
float a;
time=TH0*256+TL0; //这是最后计算到的时间,但应该再乘以12/11.092
//时间应该是time*12/11.0592
TH0=0; //定时器0的初始值位0
TL0=0;
a=(331.5+0.607*temp); //声速与温度的函数关系:声速=331.5+0.607*温度
S=(time*a/200)/100; //算出来是cm
if (S>=500) //最大距离为5m,即500cm
S=888;
if (flag==1) //判断是否溢出
{
S=888;
flag=0;
TH0=0;
TL0=0;
}
}
//初始化定时器0和定时器1
void T0_init()
{
TMOD=0x11;
TH0=0;
TL0=0;
TH1=0xf8; //定时器1赋初值,应该是2ms
TL1=0x30;
ET0=1;
ET1=1;
TR1=1;
EA=1;
}
void main( )
{
unsigned int i;
T0_init();
while(1)
{
duwendu(); //获取温度后计算相应声速,从而计算距离
while(!echo); //当echo为0时等待
TR0=1; //开启定时器0
while(echo); //当echo为1计数并等待
TR0=0; //关闭定时器0
Conut(); //计算距离
for(i=150;i>0;i--)
{
xianshi(S); //数码管显示
}
}
}
void zd0() interrupt 1
{
flag=1; //中断溢出标志
}
void zd3() interrupt 3
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………