主函数
#define uchar unsigned char
#define uint unsigned int
#define ULint unsigned long int
//温度零上与零下的标志位
char flag=0;
//超声波
char flags=0;
//超声波距离
char flag1s=0;
//计算定时间
uint time=0;
//计算距离
//ULint L_=0;
uchar L=0;
//温度
uint t_=0;
//显示模式 0正常 1最大值调整 2最小值调整
uchar mode=0;
uint Max=150;
uint Min=5;
//按键标志
uchar k=0;
//数值有误
uchar FW=0;
//头函数
#include <reg52.h>
#include <intrins.h>
#include "BJ_Key.h" //报警按键
#include "display.h" //显示头函数
#include "ultrasonic_wave.h"//超声波头函数
#include "DS18B20.h" //温度传感器头函数
//函数声明
void delayms(uint ms);
//主函数
void main()
{
Init_ultrasonic_wave();
//屏幕初始化
Init1602();
//温度初始化
tmpchange();
t_=tmp();
tmpchange();
t_=tmp();
tmpchange();
t_=tmp();
//循环显示
while(1)
{
Key();
//正常显示
if(mode==0)
{
StartModule();//启动超声波
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
delayms(20); //20MS
tmpchange(); //温度转换
t_=tmp(); //度温度
Conut(t_/10); //计算距离
if(L>Max||L<Min)
{
Feng_Start();
}
else
{
if(FW!=1)
Feng_Stop();
}
Display_1602(t_/10,L);
}
//调整显示
else if(mode!=0)
{
//最大最小值
Init_MaxMin();
while(mode!=0)
{
Key();
if(k==1&&mode==1)
{
Init_MaxMin();
write_com(0x8d);//设置位置
}
else if(k==1&&mode==2)
{
Init_MaxMin();
write_com(0x8d+0x40);//设置位置
}
k=0;
}
//界面初始化
Init1602();
}}}
void delayms(uint ms)
{
uchar i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}}}
//T0中断用来计数器溢出,超过测距范围
void CJ_T0() interrupt 1
{
flags=1; //中断溢出标志
}
超声波函.h
sbit RX=P2^1;
sbit TX=P2^0;
//超声波初始化
void Init_ultrasonic_wave()
{
TX=0; //关闭发射
TMOD=0x01; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
ET0=1; //允许T0中断
EA=1; //开启总中断
}
//启动超声波
void StartModule() //启动模块
{
TX=1; //启动一
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
//计算不同温度下的速度
void JS_(uchar WD)
{
//大于-30
if(WD>=30&&flag==1)
{
L=(time*3.13)/200; //算出来是CM;
}
//大于-20<-30
else if(WD>=20&&WD<30&&flag==1)
{
L=(time*3.19)/200; //算出来是CM;
}
//大于-10<-20
else if(WD>=10&&WD<20&&flag==1)
{
L=(time*3.25)/200; //算出来是CM;
}
//大于0<-10
else if(WD>=0&&WD<10&&flag==1)
{
L=(time*3.23)/200; //算出来是CM;
}
//大于0<10
else if(WD<=10&&WD>0&&flag==0)
{
L=(time*3.38)/200; //算出来是CM;
}
//大于10<20
else if(WD<=20&&WD>10&&flag==0)
{
L=(time*3.34)/200; //算出来是CM;
}
//大于20<30
else if(WD<=30&&WD>20&&flag==0)
{
L=(time*3.49)/200; //算出来是CM;
}
//大于30
else if(WD>30&&flag==0)
{
L=(time*3.86)/200; //算出来是CM;
}
}
//距离计算 SD为当时的超声速度
void Conut(uchar WD)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
JS_(WD);
//距离大于200或者超时
if(L>450||flags==1)
{
flags=0;
//无效显示
flag1s=0;
L=0;
FW=1;
Feng_Start();
}
//距离小于100
else if(L<=150)
{
flag1s=1;
FW=1;
Feng_Stop();
}}
DS1820.h
#define uchar unsigned char
#define uint unsigned int
//define interface 定义 DS18B20 接口
sbit DS=P1^4;
//variable of temperature
uint temp=0;
//延时子函数
//sign of the result positive or
void delay(uint count)
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
} }
//发送初始化及复位信号
void dsreset(void)
{
//DS18B20 初始化
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
//read a bit 读一位
bit tmpreadbit(void)
{
uint i;
bit dat;
//i++ for delay 小延时一下
DS=0;i++;
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
//read a byte date 读一个字节
uchar tmpread(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
//读出的数据最低位在最前面,这样刚好
//一个字节在 dat 里
dat=(j<<7)|(dat>>1);
}
//将一个字节数据返回
return(dat);
}
//write a byte to ds18b20
//写一个字节到 DS18B20 里
void tmpwritebyte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写 1 部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 写 0 部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
//DS18B20 begin change 发送温度转换命令
void tmpchange(void)
{
dsreset(); //初始化 DS18B20
delay(1); //延时
tmpwritebyte(0xcc); //跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
//get the temperature 获得温度
uint tmp()
{
float tt=0;
uchar a=0,b=0;
dsreset();
delay(1);
//发送读取数据命令
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
//连续读两个字节数据
a=tmpread();
b=tmpread();
//two byte compose a int variable
//两字节合成一个整型变量。
temp=b;
temp<<=8; //temp=temp<<=8 左移8位
temp=temp|a;
if(b==0xff)
{
flag=1;
temp=~temp+1; //负温度表示 取补码
}
//得到真实十进制温度值,因为 DS18B20
tt=temp*0.0625;
//可以精确到 0.0625 度,所以读回数据的最低位代表的是
//0.0625 度。
//放大十倍,这样做的目的将小数点后第一位
temp=tt*10+0.5;
//也转换为可显示数字,同时进行一个四舍五入操作。
//返回温度值
return temp;
}
display.h
sbit LCDRS = P2^7;
sbit LCDEN= P2^6;
//初始画时显示的内容
uchar code Init1[]="Temperature: C";
uchar code Init2[]="Distance:0000 CM";
//初始画时显示的内容
uchar code Init3[]=" Max------ CM";
uchar code Init4[]=" Min------ CM";
//LCD延时
void LCDdelay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
//写命令
void write_com(uchar com)
{
LCDRS=0;
P0=com;
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
//写数据
void write_data(uchar date)
{
LCDRS=1;
P0=date;
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
//1602初始化
void Init1602()
{
uchar i=0;
write_com(0x38);//屏幕初始化
write_com(0x0C);//打开显示 无光标 无光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
write_com(0x01);//清屏
write_com(0x80);//设置位置
for(i=0;i<14;i++)
{
write_data(Init1[i]);
}
write_data(0xdf);
write_data(Init1[14]);
write_com(0x80+0x40);//设置位置
for(i=0;i<16;i++)
{
write_data(Init2[i]);
}}
//温度 距离显示
void Display_1602(uchar W,uchar L)
{
//温度值显示
write_com(0x80+12);
write_data('0'+W/10);
write_data('0'+W%10);
if(L>=100)
{
write_com(0x80+0x40+0x09);
write_data(((L*10)/1000)+0x30); //百
write_data(((L*10)%1000/100)+0x30); //十
write_data(((L*10)%100/10)+0x30); //个
write_data(0x2e); //点
write_data(((L*10)%10)+0x30); //小数位1
}
else if(L>=10 && L<100)
{
write_com(0x80+0x40+0x09);
write_data((L*10/100)+0x30); //十
write_data((L*10%100/10)+0x30); //个
write_data(0x2e); //点
write_data((L*10%10)+0x30); //小数位1
}
else if(L>=0 && L<10)
{
write_com(0x80+0x40+0x09);
write_data((L*10/10)+0x30); //个
write_data(46); //点
write_data((L*10%10)+0x30); //小数位1
}
else if(flag1s==0)
{
write_com(0x80+0x40+0x0a);
write_data('-');
write_data('-');
write_data('-');
write_data('-');
}}
//1602初始化最大化最小化调整界面
void Init_MaxMin()
{
uchar i=0;
write_com(0x38);//屏幕初始化
write_com(0x0f);//打开显示 无光标 无光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
write_com(0x01);//清屏
write_com(0x80);//设置位置
for(i=0;i<16;i++)
{
write_data(Init3[i]);
}
write_com(0x80+0x40);//设置位置
for(i=0;i<16;i++)
{
write_data(Init4[i]);
}
write_com(0x8b);//设置位置
write_data('0'+Max/100);
write_data('0'+Max/10%10);
write_data('0'+Max%10);
write_com(0x80+0x40+0x0b);//设置位置
write_data('0'+Min/100);
write_data('0'+Min/10%10);
write_data('0'+Min%10);
write_com(0x8d);//设置位置
}
key.h
sbit Feng=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
sbit K3=P1^3;
//蜂鸣打开
void Feng_Start()
{
Feng=0;
}
//蜂鸣关闭
void Feng_Stop()
{
Feng=1;
}
//等待
void delay_key()
{
uchar i,j;
for(i=0;i<200;i++)
for(j=0;j<200;j++);
}
//按键检测
void Key()
{
//功能键按下
if(K1==0)
{
Feng_Start();//蜂鸣器开
delay_key(); //消抖
while(K1==0);//等待松手
Feng_Stop(); //蜂鸣器关闭
mode++; //模式++
if(mode==3) //达到最大限度归为
mode=0;
k=1; //按键标志位
}
//+键
else if(K2==0)
{
Feng_Start();//蜂鸣器开
delay_key(); //消抖
while(K2==0);//等待松手
Feng_Stop(); //蜂鸣器关闭
//最大值调整
if(mode==1) //在最大值调整下
{
Max++; //调整最大值
if(Max==201)//到达201归为200
{
Max=200;
}
}
//最小值
else if(mode==2)//最小模式下调整
{
Min++; //调整最小值
if(Min>Max) //最小值不能大于最大值
{
Min=Max;
}
}
k=1;
}
//-键
else if(K3==0)
{
Feng_Start();
delay_key();
while(K3==0);
Feng_Stop();
//最大值调整
if(mode==1)
{
Max--;
if(Max<Min)
{
Max=Min;
}
}
//最小值
else if(mode==2)
{
Min--;
if(Min==0xff)
{
Min=0;
}
}
k=1;
}
} |