文档库 最新最全的文档下载
当前位置:文档库 › LCD12864串行显示DS18B20温度和超声波测距HC-SR04

LCD12864串行显示DS18B20温度和超声波测距HC-SR04

/******************************************************
DS18B20温度检测及超声波测距(带12864液晶串行显示,修正负温度显示)
**********************************************************/
#include //包含单片机寄存器的头文件
#include //包含_nop_()函数定义的头文件
#include
#include
unsigned char code num[]={"0123456789 :.-"}; //定义字符数组显示数字
unsigned char code error[]={"Device not working!"};
unsigned char code temp[]={"Temp"};
unsigned char code cent[]={"Cent"};
unsigned int time=0; //设置全局变量,专门用于严格延时
long S=0;
bit flag=0;
unsigned char disbuff[4]={0,0,0,0,};
unsigned char distemp[4]={0,0,0,0,};
int tmpvalue;
sbit TX = P0^1;
sbit RX = P0^2;
sbit SID = P0^6; //读写选择位,将RW位定义为P0.6引脚
sbit SCLK = P0^5; //使能信号位,将E位定义为P0.5引脚
sbit DQ = P0^0; //DS18B20的总线
//HC-SR04超声波函数
void conut(void);

//LCD12864函数声明
void lcm_w_word(unsigned char x,unsigned char y, unsigned char *str) ; //写字符
void lcm_w_test(bit start, unsigned char ddata); //(0-指令,1-数据)
void lcm_w_byte(unsigned char bbyte); //写一个字节给lcm
void delaynms(unsigned char n); //延时
void lcm_init(void); //lcm初始化
void lcm_set_xy(unsigned char x, unsigned char y);

//DS18B20函数申明
void display_temp(int tmpvalue);
void display_explain(void);

/*******************************************************************************
以下是对液晶模块的操作程序LCD12864串行方式显示
*******************************************************************************/


/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i,j;
for(i=0;ifor(j=0;j<10;j++);
}

//发送一个字节(底层函数)
void lcm_w_byte(unsigned char bbyte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SID=bbyte&0x80; //取出最高位
SCLK=1;
SCLK=0;
bbyte<<=1; //左移
}
}

//写指令或数据 (0-指令,1-数据)
void lcm_w_test(bit start, unsigned char ddata)
{
unsigned char start_data,Hdata,Ldata;
if(start==0)
start_data=0xf8; //0:写指令
else
start_data=0xfa; //1:写数据

Hdata=ddata&0xf0; //取高四位
Ldata=(ddata<<4)&0xf0; //取低四位
lcm_w_byte(start_data); //发送起始信号
delaynms(1); //延时是必须的
lcm_w_byte(Hdata); //发送高四位
delaynms(1); //延时是必须的
lcm_w_byte(Ldata); //发送低四位
delaynms(1); //延时是必须的
}

//初始化LCM
void lcm_init(void)
{
delaynms(10); //启动等待,等LCM讲入工作状态
lcm_w_t

est(0,0x30); //8 位介面,基本指令集
lcm_w_test(0,0x0c); //显示打开,光标关,反白关
lcm_w_test(0,0x01); //清屏,将DDRAM的地址计数器归零
//lcm_w_test(0,0x06);
}

//设置LCD显示的位置
void lcm_set_xy(unsigned char x, unsigned char y)
{
unsigned char address;
switch(x)
{
case 1: address = 0x80 + y; break;
case 2: address = 0x90 + y; break;
case 3: address = 0x88 + y; break;
case 4: address = 0x98 + y; break;
default: address = 0x80 + y; break;
}
lcm_w_test(0,address);
}

//向LCM发送一个字符串,长度64字符之内。
void lcm_w_word(unsigned char x, unsigned char y, unsigned char *s)
{
lcm_set_xy (x , y);
while(*s)
{
lcm_w_test(1,*s);
s++;
delaynms(1);
}
}

void lcm_w_number(unsigned char s)
{
lcm_w_test(1,num[s]);
delaynms(1);
}

/************************************************************************
以下是DS18B20的操作程序
************************************************************************/

/*****************************************************
函数功能:将DS18B20传感器初始化,读取应答信号
出口参数:flag
***************************************************/
bit Init_DS18B20(void)
{
bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在

DQ = 0; //再将数据线从高拉低,要求保持480~960us
for(time=0;time<103;time++) //略微延时约600微秒
; //以向DS18B20发出一持续480~960us的低电平复位脉冲
DQ = 1; //释放数据线(将数据线拉高)
for(time=0;time<4;time++)
; //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
while(DQ);
flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time=0;time<110;time++) //延时足够长时间,等待存在脉冲输出完毕
;
return (flag); //返回检测成功标志
}
/*****************************************************
函数功能:从DS18B20读取一个字节数据
出口参数:dat
***************************************************/
unsigned char ReadOneChar(void)
{
bit b;
unsigned char i_b,i,j=0;
unsigned char dat=0; //储存读出的一个字节数据
for (i=0;i<8;i++)
{
DQ=0;
j++;
DQ=1;
j++;j++;
b=DQ;
time=8;while(time>0) time--;
i_b = b;
dat = (i_b << 7)|( dat >> 1);
}
return(dat); //返回读出的十进制数据
}
/*****************************************************
函数功能:向DS18B20写入一个字节数据
入口参数:dat
***************************************************/
void WriteOneChar(unsigned char dat)
{
bit testb;
unsigned char i;
unsigned char j;
for (i=0; i<8; i++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DQ = 0;
j++;j++;


DQ = 1;
time=8;while (time>0) time--;
}
else
{
DQ = 0;
time=8;while (time>0) time--;
DQ = 1;
j++;j++;
}
}
}

/******************************************************************************
以下是与温度有关的显示设置
******************************************************************************/

/*****************************************************
函数功能:显示说明信息
***************************************************/
void display_explain(void)
{
lcm_w_word(1,0,temp);
delaynms(50);
}

/*****************************************************
函数功能:显示温度数据
***************************************************/
void display_temp(int tmpvalue)
{
unsigned int tmp=abs(tmpvalue);
distemp[1]=tmp/100;//显示十位数
distemp[2]=tmp%100/10;//显示个位数
distemp[3]=tmp%10;//显示十分位
if(tmpvalue<0)
{
lcm_set_xy(1,2);
lcm_w_number(num[10]);
lcm_w_number(num[13]);
}
lcm_set_xy(1,3);
lcm_w_number(distemp[1]);
lcm_w_number(distemp[2]);
lcm_w_number(12);
lcm_w_number(distemp[3]);

}


/*****************************************************
函数功能:显示温度的单位(Cent)
***************************************************/
void display_cent(void)
{
lcm_w_word(1,6,cent);
delaynms(50);
}




/*****************************************************
函数功能:做好读温度的准备
***************************************************/
void ReadyReadTemp(void)
{
Init_DS18B20(); //将DS18B20初始化
WriteOneChar(0xcc); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
for(time=0;time<100;time++); //温度转换需要一点时间
Init_DS18B20(); //将DS18B20初始化
for(time=0;time<110;time++); //温度转换需要一点时间
WriteOneChar(0xcc); //跳过读序号列号的操作
WriteOneChar(0xbe); //读取温度寄存器,前两个分别是温度的低位和高位
}


/**************************************************
函数功能:超声波
**************************************************/
void conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=time*1.87/100;
if(flag==1)
{
flag=0;
lcm_w_word(2,0,error);
}
else
{
disbuff[1]=S%1000/100;
disbuff[2]=S%1000%100/10;
disbuff[3]=S%1000%10%10;
lcm_set_xy(2,0);
lcm_w_number(disbuff[1]);
lcm_w_number(12);
lcm_set_xy(2,1);
lcm_w_number(disbuff[2]);
lcm_w_number(disbuff[3]);
}
}

/*****************************************************
函数功能:T0中断用来计数器溢出,超过测距范围
***************************************************/
void zd0() interrupt 1
{
flag=1;
}

/*****************************************************
函数功能:T1中断用来800MS启动一次模块
*******************

********************************/
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 main(void)
{
float value; //储存温度数值
unsigned char TL,TH;
lcm_init(); //LCD12864初始化

if(Init_DS18B20()==1)
lcm_w_word(1,0,error);

TMOD=0x01; //设T0为方式1,GATE=1
TH0=0;
TL0=0;
TR0=1;

while(1) //不断检测并显示温度
{
ReadyReadTemp(); //读温度准备
TL=ReadOneChar(); //先读的是温度值低位
TH=ReadOneChar(); //接着读的是温度值高位
tmpvalue=TH;
tmpvalue<<=8;
tmpvalue|=TL;
value=tmpvalue*0.0625;
tmpvalue = value*10 + (value>0 ? 0.5 : -0.5);
display_explain();
display_temp(tmpvalue);
display_cent();

Startmodule();
while(!RX);
TR0=1;
while(RX);
TR0=0;
conut();
delaynms(80);
}
}

相关文档
相关文档 最新文档