单片机控制DS18B20及LCD1602的温度采集系统

单片机控制DS18B20及LCD1602的温度采集系统
单片机控制DS18B20及LCD1602的温度采集系统

程序

/******************************************************************** *文件名:温度测试LCD1602显示

*创作人:孔子先生2011-9-6

********************************************************************/ #include

#include

#define uchar unsigned char

#define uint unsigned int

#define t 6 //t表示从第二行的第t个位置开始写入温度值

sbit E=P2^7; //片选信号

sbit RW=P2^6; //LCD1602读/写信号,H读,L写

sbit RS=P2^5; //LCD1602寄存器选择信号,L为指令寄存器,H为数据寄存器sbit DQ=P2^3; //DS18B20 I/O口

uchar TMPH,TMPL,REMAIN,PER_C; //温度高位,温度低位,门周期值,每度计数值

uchar a[]={"Temperature is:"}; //第一行显示数据

/**********************************************

LCD1602 读取忙标志(BF)和地址指令

***********************************************/

void LCD_busy()

{

unsigned char i;

RW=1;

RS=0;

Loop:

P0=0xff;

E=1;

i=P0;

E=0;

if(i&0x80)

{

goto Loop;

}

}

/*********************************************

LCD1602 指令写入程序,入口为n

**********************************************/

void write(unsigned int n)

{

LCD_busy();

RS=0;

RW=0;

P0=n;

E=1;

E=0;

}

/******************************************************************** *延时子程序延时n*20 us

********************************************************************/ void delay(int n)

{

int s;

for(s=0;s

}

/******************************************************************** 18B20 *复位子程序

********************************************************************/ uchar reset()

{

uchar ready;

DQ=0;

delay(30);

DQ=1;

delay(3);

ready=DQ;

delay(30);

return ready;

}

/******************************************************************** 18B20 *位写入子程序

*形参为val

********************************************************************/ void writebit(char val)

{

DQ=0;

if(val==1)

DQ=1;

else

DQ=0;

delay(5);

DQ=1;

}

/******************************************************************** 12B20 *字节写入子程序

*形参为val

void writebyte(char val)

{

uchar i;

uchar temp;

for (i=0;i<8;i++)

{

temp=val>>i;

temp&=0x01;

writebit(temp);

}

delay(5);

}

/******************************************************************** 18B20 *位读取子程序

********************************************************************/ uchar readbit(void)

{

uchar i;

DQ=0;

DQ=1;

for(i=0;i<3;i++);

return DQ;

}

/******************************************************************** 18B20 *字节读取子程序

入口无,出口为value

********************************************************************/ uchar readbyte(void)

{

uchar i;

uchar value=0;

for(i=0;i<8;i++)

{

if(readbit())

value|=0x01<

delay(7);

}

return (value);

}

/******************************************************************** *LCD-1602显示字符串程序

X为从某行的第X个位置开始写,Y为显示在第1或第2行,*ddata为字符串首地址

void LCD_string(uchar x,uchar y,uchar *ddata)

{

uchar i=0;

if(y==1) //写在第一行

x=x+0x7f;

else if(y==2) //写在第二行

x=x+0xbf;

else

;

write(x); //设定DDRAM-AC到第Y行第X个位置

while(*ddata!='\0') //遇到字符串末尾则退出

{

LCD_busy();

P0=*ddata;

RS=1;

RW=0;

E=1;

E=0;

ddata++;

}

}

/******************************************************************** *LCD-1602显示数据程序

X为从某行的第X个位置开始写,Y为显示在第1或第2行,ddata为要显示的数据

********************************************************************/ void LCD_Display(uchar x,uchar y,uchar ddata)

{

if(y==1) //写在第一行

x=x+0x7f;

else if(y==2) //写在第二行

x=x+0xbf;

else

;

write(x); //设定DDRAM-AC到第Y行第X个位置

LCD_busy();

P0=ddata+48; //ddata+48是查字符库

RS=1;

RW=0;

E=1;

E=0;

}

/********************************************************************

*LCD-1602初始化程序

********************************************************************/ void LCD_Init()

{

write(0x01);//清屏:DDRAM填满20H(0)并且DDRAM-AC到00H

write(0x38);//功能设置:0000DLXREXX DL=1为8位MPU控制方式;RE=0为基本指令集;

write(0x0c);//显示开关设置:00001DCB D=1整体显示打开;C=1游标显示关闭;B=0游标反白关闭

write(0x14);//移位:00001S/CR/LXX S/C=0,R/L=1游标向右移动;

write(0x06);//输入方式设置:000001I/DS I/D=1游标右移;S=0画面不整体移位LCD_string(1,1,a);//显示字符串Temperature is:

LCD_Display(t+5,2,(0xdf-0x30));//显示温度单位°

LCD_Display(t+6,2,(0x43-0x30));//显示温度单位C

}

void main()

{

uchar i,j,m,n;

uint temp;

float temp_read;

LCD_Init();

while(1)

{

reset();

writebyte(0xcc);//跳过ROM序列号命令

writebyte(0x44);//温度转换命令

reset();

writebyte(0xcc);//跳过ROM序列号命令

writebyte(0xbe);//读暂存器命令

TMPL=readbyte();//读出温度低位

TMPH=readbyte();//读出温度高位

readbyte();//空读

readbyte();//空读

readbyte();//空读

readbyte();//空读

REMAIN=readbyte();//读出门周期结束后保留下来的值

PER_C=readbyte();//读出对应温度下每度的计数值

TMPL=TMPL&0xfe;//将0.5℃位(LSB)从读取的值中截去

temp_read=((TMPL+TMPH*256)*0.0625)-0.25+((PER_C-REMAIN)/PER_C);

temp=temp_read*100;//先放大100倍,方便整型运算显示

i=temp/1000%10;

j=temp/100%10;

m=temp/10%10;

n=temp%10;

LCD_Display(t,2,i);//显示温度十位

LCD_Display(t+1,2,j);//显示温度个位

LCD_Display(t+2,2,(0x2e-0x30));//显示高精度温度小数点.

LCD_Display(t+3,2,m);//显示温度十分位

LCD_Display(t+4,2,n);//显示温度百分位

}

}

接线图

单总线温度传感器接线图

LCD1602接线图

相关主题
相关文档
最新文档