DS18B20 是一款数字温度传感器,焊接在开发板黄色排座的左上部分,使用如下程序可以将传感器测得的温度显示在 LCD1602 上:
DS18B20.h:
#ifndef _DS18B20_H
#define _DS18B20_H
#include "reg52.h"
#include "intrins.h"
void delay_10us(unsigned char t);
void DS18B20_Init(void);
void DS18B20_WriteByte(unsigned char dat);
unsigned char DS18B20_ReadByte(void);
unsigned int GetTemperature(void);
#endif
DS18B20.c:
#include "DS18B20.h"
sbit Tem = P3^7;
void delay_10us(unsigned char t)
{
while(t--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
void DS18B20_Init(void)
{
Tem = 0; //拉低P3.7 500us
delay_10us(50);
Tem = 1; //拉高P3.7 60us
delay_10us(6);
while(!Tem); //等待P3.7引脚返回低电平
delay_10us(50); //延时500us
}
void DS18B20_WriteByte(unsigned char dat) //写数据
{
unsigned char i;
bit flag;
for(i=1;i<9;i++)
{
flag = dat&0x01; //0 和 1 的标志位不同
dat = dat>>1; //逐位传输
Tem = 0; //拉低总线2us
_nop_();
_nop_();
Tem = flag; //将数据放到总线上
delay_10us(6); //延时60us
Tem = 1; //拉高总线
}
}
unsigned char DS18B20_ReadByte(void) //读数据
{
unsigned char dat,flag,i;
for(i=1;i<9;i++)
{
Tem = 0; //拉低总线2us
_nop_();
_nop_();
Tem = 1; //拉高总线2us
_nop_();
_nop_();
flag = Tem; //读取总线的内容
delay_10us(6); //延时60us
dat = (dat>>1)|(flag<<7); //每次读出的数值放到右侧
}
return dat;
}
unsigned int GetTemperature(void)
{
unsigned char Temp_L,Temp_H; //定义温度数值的高低八位
unsigned int Temp; //定义十六位的温度数值
DS18B20_Init(); //初始化温度传感器
DS18B20_WriteByte(0xCC); //跳过ROM
DS18B20_WriteByte(0x44); //启动温度转换
DS18B20_Init(); //初始化温度传感器
DS18B20_WriteByte(0xCC); //跳过ROM
DS18B20_WriteByte(0xBE); //发送读温度指令
Temp_L = DS18B20_ReadByte(); //读温度低八位
Temp_H = DS18B20_ReadByte(); //读温度高八位
Temp = ((unsigned int)(Temp_H)<<8)+Temp_L; //将温度组成十六位的数据
return Temp;
}
main.c:
#include "reg52.h"
#include "DS18B20.h"
#include "LCD1602.H"
unsigned int time;
unsigned int Temperature;
unsigned char t[10]; //温度储存数组
void Timer0_Init(void);
void Timer0_Init(void)
{
TMOD = 0x01; //工作方式1,16位定时器
TH0 = 0x4C; //定时50ms初值高八位
TL0 = 0x00; //定时50ms初值低八位
ET0 = 1; //开定时器0中断
EA = 1; //开总中断
TR0 = 1; //开启定时器0
}
void main(void)
{
Timer0_Init(); //定时器初始化
LCD_Init(); //LCD初始化
LCD_WriteString(1,1,"Temperature:");
while(1)
{
if(time == 20) //1s时间到
{
time = 0; //重新计时
EA = 0; //关总中断,防止与温度采集冲突
Temperature = GetTemperature(); //将读取的温度值放入Temperature中
t[0] = ( Temperature>>4 )/10+'0';
t[1] = ( Temperature>>4 )%10+'0'; //两位数温度的整数部分
t[2] = '.';
if( (Temperature >>3)%10 ) //温度左移三位取余后为1
{
t[3] = '5';
}
else
{
t[3] = '0';
}
t[4] = '0';
LCD_WriteString(2,1,t);
EA = 1;
}
}
}
void Timer0() interrupt 1 using 1
{
time++;
TH0 = 0x4C; //重装初值,定时50ms初值高八位
TL0 = 0x00; //定时50ms初值低八位
}