滤清器厂家
免费服务热线

Free service

hotline

010-00000000
滤清器厂家
热门搜索:
技术资讯
当前位置:首页 > 技术资讯

51单片机温度传感器DS18B20 免费猫

发布时间:2020-02-17 12:55:08 阅读: 来源:滤清器厂家

51单片机-温度传感器DS18B20

温度传感器是各种传感器中最常用的一种,早期使用的是模拟温度传感器,如热敏电阻,随着环境温度的变化,它的阻值也发生线性变化,用处理器采集电阻两端的电压,然后根据某个公式就可以计算出当前环境温度。美国DALLAS半导体公司推出的数字化温度传感器DS18B20采用单总线协议,即与单片机接口仅需占用一个I/O端口,无需任何外部元件,直接将环境温度转化成数字信号,以数字码方式串行输出,从而大大简化了传感器与处理器的接口。

DS18B20的三种封装:

DS18B20的内部结构:

它采用单条信号线,既可传输时钟,又可传输数据,而且数据传输是双向的。如果要控制多个DS18B20进行温度采集,只要将所有的DS18B20的I/O口全部连接到一起就可以了。在具体操作时,通过读取每个DS18B20内部芯片的序列号来识别。64位光刻ROM中的序列号是出场前被光刻好的,他可以看做该DS18B20的地址序列码。

DS18B20的复位时序:

DS18B20复位,确定其存在: #include <reg52.h>

#define uint unsigned int

uint i;

sbit DQ = P3^3;

sbit bell = P3^4;

void reset(){

DQ = 1; //开始的时候是高脉冲

DQ=0; //然后是低脉冲

i=103;

while(i>0)i--; //低脉冲需要延迟一会儿

DQ=1; //数据线拉高,系统将总线放开,并进入接受状态

i=4;

while(i>0)i--; //延时等待,若初始化成功则在15 60ms内产生一个由

if(DQ == 0){ //DS18B20在检测到总线的上升沿后,等待15 60ms,接着

while(DQ == 0); //在T2时刻发出存在脉冲(低电平)

bell = 0;

}

else

bell = 1;

}

void main(){

reset();

while(1);

}

DS18B20的写0和写1时序:

DS18B20的读数据时序:

读出光刻ROM中的ID号,在LCD上显示:

#include <reg52.h>

#include<intrins.h>

sbit DQ = P3^3;

sbit RS = P1^0;

sbit RW = P1^1;

sbit E = P1^2;

sbit bell = P3^4;

#define uchar unsigned char

#define uint unsigned int

#define nop() _nop_()

uint i;

uchar value;

uchar DS[8];

uchar Time_Data[]={'0','1','2','3','4','5','6','7',

'8','9','A','B','C','D','E','F'};

void delay(uchar t){

while(--t);

}

void lcd_com(uchar s){

RS = 0; //低电平,写指令

P2 = s; //传数据

delay(14); //看时序图,数据需要稳定一段时间

E = 1; //给一个高脉冲,发送命令

delay(14); //如图,高脉冲延时一段时间,确保命令发送

E = 0; //发送结束E置为低电平

}

void lcd_data(uchar s){

RS = 1;

P2 = s;

delay(14);

E = 1;

delay(14);

E = 0;

}

void init_lcd(){

RS = 1; //先发指令,在初始时刻RS是高,E和RW是低

E = 0;

RW = 0;

lcd_com(0x38); //设置为16*2显示,5*7点阵,8位数据接口

lcd_com(0x0f); //开显示,显示光标,光标闪烁

lcd_com(0x06); //读写一个字符后地址指针加一

lcd_com(0x01);

}

void Display_lcd(uchar y, uchar x, uchar value){

if(y)

lcd_com(0x80+0x40+x); //如果y为1,写在第二行

else

lcd_com(0x80+x);

lcd_data(value); //写到LCD602上

}

void DS18B20_reset(){

DQ = 1; //开始的时候是高脉冲

DQ=0; //然后是低脉冲

i=103;

while(i>0)i--; //低脉冲需要延迟一会儿

DQ=1; //数据线拉高

i=4;

while(i>0)i--; //延时等待,若初始化成功则在15 60ms内产生一个由

if(DQ == 0){ //DS18B20返回的低电平

while(DQ == 0);

// bell = 0;

}

else

bell = 1;

}

uchar DS18B20_read(void)

{

uchar i = 0;

uchar Value = 0;

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

{

DQ = 1;

DQ = 0;

delay(1);

DQ = 1; //在T1时刻将总线拉高,产生读时间隙

delay(1); //读时隙在T1和T2之间有效

if(DQ)

{

Value |= 0x01 << i;

}

delay(17); //必须在T3时刻之间主机完成读操作

DQ = 1;

nop();

}

return Value;

}

void DS18B20_write(uchar Value){

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

DQ = 1;

DQ = 0; //当t0从高拉低产生写时隙,

delay(5);

DQ = Value 0x01; //必须在t0开始的15us内将数据送到总线上

delay(20); //DS18B20在t0后的15us 60us内对总线采样

DQ = 1; //如果采到低电平则写入0,高电平写入1

Value >>= 1;

delay(2);

}

}

void DS18B20_ID_read(){

DS18B20_reset();

DS18B20_write(0x33);

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

DS[ i] = DS18B20_read();

}

void main(){

init_lcd();

while(1){

DS18B20_ID_read();

Display_lcd(0,0,'>');

Display_lcd(0,1,':');

Display_lcd(0,2,Time_Data[DS[0]/16]);

Display_lcd(0,3,Time_Data[DS[0]%16]);

Display_lcd(0,4,'>');

Display_lcd(0,5,':');

Display_lcd(0,6,Time_Data[DS[1]/16]);

Display_lcd(0,7,Time_Data[DS[1]%16]);

Display_lcd(0,8,'>');

Display_lcd(0,9,':');

Display_lcd(0,10,Time_Data[DS[2]/16]);

Display_lcd(0,11,Time_Data[DS[2]%16]);

Display_lcd(0,12,'>');

Display_lcd(0,13,':');

Display_lcd(0,14,Time_Data[DS[3]/16]);

Display_lcd(0,15,Time_Data[DS[3]%16]);

Display_lcd(1,0,'>');

Display_lcd(1,1,':');

Display_lcd(1,2,Time_Data[DS[4]/16]);

Display_lcd(1,3,Time_Data[DS[4]%16]);

Display_lcd(1,4,'>');

Display_lcd(1,5,':');

Display_lcd(1,6,Time_Data[DS[5]/16]);

Display_lcd(1,7,Time_Data[DS[5]%16]);

Display_lcd(1,8,'>');

Display_lcd(1,9,':');

Display_lcd(1,10,Time_Data[DS[6]/16]);

Display_lcd(1,11,Time_Data[DS[6]%16]);

Display_lcd(1,12,'>');

Display_lcd(1,13,':');

Display_lcd(1,14,Time_Data[DS[7]/16]);

Display_lcd(1,15,Time_Data[DS[7]%16]);

}

}

单只DS18B20工作流程:

2只DS18B20并联工作流程:

DS18B20温度存储格式:

DS18B20暂存器的分布:

DS18B20内部ROM指令:

DS18B20内部RAM指令:

读出当前温度,在LCD上显示,温度超过一定时,报警。

#include <reg52.h>

#include<intrins.h>

sbit DQ = P3^3;

sbit RS = P1^0;

sbit RW = P1^1;

sbit E = P1^2;

sbit bell = P3^4;

#define uchar unsigned char

#define uint unsigned int

#define nop() _nop_()

uint i;

uchar value;

uchar DS[8];

uchar Time_Data[]={'0','1','2','3','4','5','6','7',

'8','9','A','B','C','D','E','F'};

void delay(uchar t){

while(--t);

}

void Lcd_Com(uchar s){

RS = 0; //低电平,写指令

P2 = s; //传数据

delay(14); //看时序图,数据需要稳定一段时间

E = 1; //给一个高脉冲,发送命令

delay(14); //如图,高脉冲延时一段时间,确保命令发送

E = 0; //发送结束E置为低电平

}

void Lcd_Data(uchar s){

RS = 1;

P2 = s;

delay(14);

E = 1;

delay(14);

E = 0;

}

void Init_Lcd(){

RS = 1; //先发指令,在初始时刻RS是高,E和RW是低

E = 0;

RW = 0;

Lcd_Com(0x38); //设置为16*2显示,5*7点阵,8位数据接口

Lcd_Com(0x0f); //开显示,显示光标,光标闪烁

Lcd_Com(0x06); //读写一个字符后地址指针加一

Lcd_Com(0x01);

}

void Display_Lcd(uchar y, uchar x, uchar value){

if(y)

Lcd_Com(0x80+0x40+x); //如果y为1,写在第二行

else

Lcd_Com(0x80+x);

Lcd_Data(value); //写到LCD602上

}

void DS18B20_Reset(){

DQ = 1; //开始的时候是高脉冲

DQ=0; //然后是低脉冲

i=103;

while(i>0)i--; //低脉冲需要延迟一会儿

DQ=1; //数据线拉高

i=4;

while(i>0)i--; //延时等待,若初始化成功则在15 60ms内产生一个由

if(DQ == 0){ //DS18B20返回的低电平

while(DQ == 0);

// bell = 0;

}

else

bell = 1;

}

uchar DS18B20_Read(void)

{

uchar i = 0;

uchar Value = 0;

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

{

DQ = 1;

DQ = 0;

delay(1);

DQ = 1;

delay(1);

if(DQ)

{

Value |= 0x01 << i;

}

delay(17);

DQ = 1;

nop();

}

return Value;

}

void DS18B20_Write(uchar Value){

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

DQ = 1;

DQ = 0;

delay(5);

DQ = Value 0x01;

delay(20);

DQ = 1;

Value >>= 1;

delay(2);

}

}

uchar DS18B20_Temp_Read(){

uchar temp_h,temp_l,temp;

DS18B20_Reset(); //复位

DS18B20_Write(0x0cc); //跳过ROM,只有一个所以跳过

DS18B20_Write(0x44); //开始温度转换

DS18B20_Reset(); //复位

DS18B20_Write(0x0cc); //跳过ROM

DS18B20_Write(0x0be); //读暂存器

temp_l = DS18B20_Read(); //读出温度低8位

temp_h = DS18B20_Read(); //读出温度高8位

temp_l >>= 4; //去掉4位小数位

temp_h <<= 4; //去掉4位符号位

temp = temp_h | temp_l;

temp = temp 0x7f; //最高位是符号位

return temp;

}

void main(){

uchar temp;

Init_Lcd();

while(1){

temp = DS18B20_Temp_Read();

if(temp > 25) //如果温度大于25报警

bell = 0;

else

bell = 1;

Display_Lcd(0,0,'T');

Display_Lcd(0,1,'E');

Display_Lcd(0,2,'M');

Display_Lcd(0,3,'P');

Display_Lcd(0,4,':');

Display_Lcd(0,5,Time_Data[temp/100]);

Display_Lcd(0,6,Time_Data[temp%100/10]);

Display_Lcd(0,7,Time_Data[temp%10]);

}

}

粗粮养生

金梅瓶小说全文免费阅读

名著小说全集免费阅读

公媳小说全集免费阅读