DS18B20温度传感器
DS18B20温度传感器封装
ROM操作命令
存储器操作命令
效果图
看图知有LCD显示屏,因此可延用先前的LCD1602.C文件
代码
DS18B20.c
#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
#include<string.h>
#include<stdlib.h>
#define INT8U unsigned char
#define INT16U unsigned int
sbit DQ = P3^4; //special bit
INT8U tempValue[]={0x00, 0x00}; //代表RAM低8位和高8位
extern void delay_ms(INT16U x);
/**
* 延时函数 针对12Mhz的晶振
* _nop_()相当于一个机器周期(12个振荡周期) --> 1us
*
*@param x 延时时间(单位us)
*@return
*/
void delay_us(INT16U x)
{
while(x--)
_nop_();
}
/**
* 精确延时函数
* delay(0):延时518us 误差:518-2*256=6
* delay(1):延时7us
* delay(10):延时25us 误差:25-20=5
* delay(20):延时45us 误差:45-40=5
* delay(100):延时205us 误差:205-200=5
* delay(200):延时405us 误差:405-400=5
*
*@param x 延时时间
*@return
*/
void delay(INT16U x)
{
while(--x);
}
/**
* 初始化(先拉低再拉高才能生效,1->0->1)
* 拉低电平需要保持480us,高电平需要保持15us
*
*@return 0:初始化成功 ,1:初始化失败
*/
INT8U init()
{
INT8U status; //状态
//下面整个过程时间为480us
DQ = 1; delay_us(15);
DQ = 0; delay_us(450);
DQ = 1; delay_us(15);
status = DQ;
delay_ms(100); //延时一段时间再读取DQ时若一下子变0则初始化成功
return status;
}
/**
* 读取DQ中的数据
*
* @return 八位数据
*/
INT8U read_byte()
{
INT8U i, dat=0x00;
for(i=0x01; i!=0x00; i<<=1) // 从低到高读(从右往左移) 0000 0001 --> 0000 0010 --> 0000 0100 ........
{
DQ=0; delay_us(1);
DQ=1; delay_us(7); //有上升延是读
if(DQ)
dat = dat|i; //把每次读取的位依次放入
delay_us(25); //此延时不能少,确保读时序的长度60us。 硬件读和软件写要等它一会儿。
}
return dat;
}
/**
*写数据(与上面读相对应,该案例没用到写只用了读)
*
*@dat 八位数据
*@return
*/
void write(INT8U dat)
{
INT8U i;
for(i=0; i<8; i++)
{
DQ=0; delay_us(1); //下降延写
dat = dat>>1; //把最低位移到PSW的进/借位CY
DQ = CY; //写
delay(8);
DQ = 1;
}
}
/**
*读取温度数据值
*
*@return 1:成功,0:失败
*/
INT8U read_temp()
{
if(init()) return 0; //判断初始化是否成功
else
{
write(0xCC); //单点连线
write(0x44); //启动温度转换 (存储器操作命令)
write(0xBE); //读取温度数字值
tempValue[0] = read_byte(); //读取RAM里低8位
tempValue[1] = read_byte(); //读取RAM里高8位
return 1;
}
}
MainX.c
#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
#include<string.h>
#include<stdlib.h>
#define INT8U unsigned char
#define INT16U unsigned int
//导入外部的函数和变量
INT8U temp_buff[17];
extern INT8U tempValue[];
extern void delay_ms(INT16U x);
extern void LCD_Initialize();
extern void LCD_String(INT8U r,INT8U c,INT8U *str);
extern INT8U read_temp();
void main()
{
float tempV = 0.0;
LCD_Initialize(); //LCD初始化
LCD_String(0, 0, " DS18B20 Project"); //总共只能有16个字符
LCD_String(1, 0, " waiting.....");
read_temp(); //读取温度数据值
delay_ms(1000);
while(1)
{
if(read_temp()) //若读取温度数据值成功
{
tempV = (((int)tempValue[1]<<8) | (int)tempValue[0]) * 0.0625; //转化为16位,0.0625是精度
sprintf(temp_buff, " temp: %5.2f\xDF\x43", tempV); //格式化(tempV以这种格式拷贝到temp_buff),.2是两个小数点,\xDF\x43对应字符集里面的
LCD_String(1, 0, temp_buff); //写字符串
}
delay_ms(50);
}
}
LCD1602.c
#include<reg51.h>
#include<intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
void delay_ms(INT16U x)
{
INT8U i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void Busy_Wait()
{
INT8U LCD_Status;
do
{
P0=0xFF;
EN=0;RS=0;RW=1;
EN=1; LCD_Status=P0;
EN=0;
}
while(LCD_Status&0x80);//1000 0000
}
void Write_LCD_Command(INT8U cmd)
{
Busy_Wait();
EN=0;RS=0;RW=0;
P0=cmd;
EN=1;_nop_();EN=0;
}
void Write_LCD_Data(INT8U data1)
{
Busy_Wait();
EN=0;RS=1;RW=0;
P0=data1;
EN=1;_nop_();EN=0;
}
void LCD_String(INT8U r,INT8U c,INT8U *str)
{
INT8U i=0;
INT8U code DDRAM[]={0x80,0xC0};
Write_LCD_Command(DDRAM[r]|c);
for(i=0;i<16&&str[i];i++)
{
Write_LCD_Data(str[i]);
}
for(;i<16;i++)
Write_LCD_Data(' ');
}
void LCD_Initialize()
{
Write_LCD_Command(0x38); delay_ms(1);//置功能位,8位,双行,每一个字符占5*7
Write_LCD_Command(0x01); delay_ms(1);//清屏
Write_LCD_Command(0x06); delay_ms(1);//字符进入模式,屏幕不动,字符后移
Write_LCD_Command(0x0C); delay_ms(1);//开显示,关光标
}
喜欢的朋友可以关注我的个人公众号,后台回复java资料、单片机、安卓可免费领取资源。