蓝桥杯驱动程序带注释--DS18B20温度采集

合集下载

DS18B20单总线温度采集实验

DS18B20单总线温度采集实验

DS18B20单总线温度采集实验一、实验目的1. 熟悉Keil IDE uVision集成开发环境软件的使用方法。

2. 学习DS18B20 单总线温度传感器的使用。

二、实验内容DS18B20 为单总线12 位(二进制)温度读数。

内部有64 位唯一的ID 编码。

工作电压从 3.0~5.5V。

测量温度范围从-55℃~125℃。

高位±0.0625℃分辨率。

三、实验要求1. 数码管显示温度数据,显示百、十、个位并保留一位小数。

2. 画出程序流程图,并独立编写C51程序。

3. 做好实验前预习,完成proteus仿真和实物搭建。

四、实验硬件电路及芯片特性DS18B20 内部框图:温度寄存器格式:DSl8B20 工作过程中的协议如下:初始化ROM 操作命令存储器操作命令处理数据初始化:单总线上的所有处理均从初始化开始。

单片机将总线拉低至少480μs 然后释放总线,DS18B20 检测到上升沿后在等待15~60μs 后拉低总线,说明器件存在。

拉低持续时间为60~240μs。

读写时序:推荐的读时序:DS18B20 的核心功能是直接数字温度传感器。

温度传感器可以配置成9、10、11 和12 位方式。

相应的精度分别为:0.5℃、0.25℃, 0.125℃和0.0625℃。

默认的分辨率为12 位。

DS18B20 在空闲低功耗状态下加电(寄生电源工作方式)。

主机必须发出Convert T [44h]命令使其对测量温度进行A-D 转换。

接下来进行采集转换,结果存于两字节高速温度寄存器并返回到空闲低功耗状态。

如果DS18B20 在外部VDD 供电方式下,单片机可以在发出Convert T 命令并总线为1 时(总线为0 表示正在转换)发出“read time slots”命令。

温度分辩率配置:五、实验步骤1. 在Keil IDE u Vision集成开发环境下建立工程文件,编辑源文件、编译、链接并生成目标文件,仿真调试验证结果。

DS18B20温度采集与控制

DS18B20温度采集与控制

(3)发送 DS18B20 功能指令。
指令名称 温度转换
指令代码 44H
指令功能 启动 DS18B20 温度转换,最长 750ms,结果存于内部 9 字节 RAM
-1-
写暂存器
4EH
读暂存器 复制暂存器 重调 EEPROM 读供电模式
BEH 48H B8H B4H
发此命令后,可向内 RAM 发 3 个字节,1st 是 TH,2st 是 TL, 3st 配置寄存器 发此命令后,依次读出内 RAM 中 0~8 字节的内容,低位在前。 复制 2、3、4 字节的内容到 EEPROM 中 EEPROM 中的内容恢复到 2、3、4 字节 当 DS18B20 寄生供电时为“0”,外部电源供电为“1”
要想完成一次测温任务,首先需要主 MCU 指挥 DS18B20 进行一次温度转换,待转换完 成后,再让主 MCU 读取 DS18B20 内部 RAM 中的温度数据。具体操作如下:
(1)主 MCU 控制“1-Wire”总线进行复位初始化。参见“对 DS18B20 进行复位初始 化”操作。
(2)主 MCU 发送跳过 ROM 的操作(CCH)命令。 (3)主 MCU 发送转换温度的操作(44H)命令,后面释放总线至少 750 毫秒,让 DS18B20 完成转换的操作。 (4)主 MCU 发出复位操作并接收 DS18B20 的应答(存在)脉冲。 (5)主 MCU 发送跳过 ROM 的操作(CCH)命令。 (6)主 MCU 发送读取 RAM 的命令(BEH),随后主机依次读取 DS18B20 发出的从第 0 一第 8,共九个字节的数据。如果只想读取温度数据,那在读完第 0 和第 1 个数据后即丢 掉(不读)后续字节的内容。 上述操作中,涉及到主 MCU 对 DS18B20 的写(发送)操作和读(读取)操作,下文将 介绍如何完成这两种操作方法。 写操作:写操作周期最少为 60 微秒,最长不超过 120 微秒。写周期开始时,主机先把总 线拉低 1 微秒表示写周期开始。之后主机若想写 0,则继续拉低电平最少 60 微秒直至写周期 结束,然后释放总线为高电平。主机若想写 1,则拉低总线电平 1 微秒后就释放总线为高电 平,一直到写周期结束。 作为从机的 DS18B20 在检测到总线被拉低后等待 15 微秒然后从 15us 到 60us 开始对总 线采样,在采样期内总线为高电平则为 1,若采样期内总线为低电平则为 0。如下图所示。

ds18b20多路温度采集程序

ds18b20多路温度采集程序

本程序为ds18b20的多路温度采集程序,是我自己参考其他程序后改写而成,可显示4路正负温度值,并有上下限温度报警(声音、灯光报警)。

亲测,更改端口即可使用。

(主要器件:51单片机,ds18b20,lcd显示器)附有proteus仿真图,及序列号采集程序/****上限62度下限-20度****/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit ds=P1^1;sbit rs=P1^4;sbit e=P1^6;sbit sp=P1^0;sbit d1=P1^2;sbit d2=P1^3;ucharlcdrom[4][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e} ,{0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9},{0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0},{0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}};unsigned char code table0[]={"TEMPERARTURE:U "}; unsigned char code table1[]={"0123456789ABCDEF"};int f[4];int tvalue;float ftvalue;uint warnl=320;uint warnh=992;/****lcd程序****/void delayms(uint ms)//延时{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}void wrcom(uchar com)//写指令{delayms(1);rs=0;P3=com;delayms(1);e=1;delayms(1);e=0;}void wrdat(uchar dat)//写数据{rs=1;e=0;P3=dat;delayms(5);e=1;delayms(5);e=0;}void lcdinit()//初始化lcd {delayms(15);wrcom(0x38);delayms(5);wrcom(0x0c);delayms(5);wrcom(0x06);delayms(5);wrcom(0x01);delayms(5); }void display(uchar *p)//显示{while(*p!='\0'){wrdat(*p);p++;delayms(1);}}displayinit()//初始化显示{lcdinit();wrcom(0x80);display(table0);}/****ds18b20程序****/ void dsrst()//ds18b20复位{uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit dsrd0()//读一位数据{uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar dsrd()//读1个字节数据{uchar i,j,dat;dat=0;for(i=8;i>0;i--){j=dsrd0();dat=(j<<7)|(dat>>1);}return(dat);}void dswr(uchar dat)//写数据{uint i;uchar j;bit testb;for(j=8;j>0;j--){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tmstart()//初始化ds18b20{sp=1;d1=1;d2=1;dsrst();delayms(1);dswr(0xcc);dswr(0x44);}void read_dealtemp()//读取并处理温度{uchar i,j,t;uchar a,b;for(j=0;j<4;j++){dsrst();delayms(1);dswr(0x55);for(i=0;i<8;i++){dswr(lcdrom[j][i]);//发送64位序列号}dswr(0xbe);a=dsrd();b=dsrd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0){d1=1;tvalue=~tvalue+1;wrcom(0xc0);wrdat(0x2d);if(tvalue>warnl){d2=0;sp=0;}else{d2=1;sp=1;}}else{d2=1;wrcom(0xc0);wrdat(' ');if(tvalue>warnh){d1=0;sp=0;}else{d1=1;sp=1;}}if(j==0){wrcom(0x8e); wrdat('2');}if(j==1){wrcom(0x8e);wrdat('3');}if(j==2){wrcom(0x8e);wrdat('4');}if(j==3){wrcom(0x8e);wrdat('5');}ftvalue=tvalue*0.0625;tvalue=ftvalue*10+0.5;ftvalue=ftvalue+0.05;f[j]=tvalue;//温度扩大十倍,精确到一位小数tvalue=f[j];t=tvalue/1000;wrcom(0x80+0x41);wrdat(table1[t]);//显示百位t=tvalue%1000/100;wrdat(table1[t]);//显示十位t=tvalue%100/10;wrdat(table1[t]);//显示个位wrdat(0x2e); //显示小数点儿t=tvalue%10/1;wrdat(table1[t]);//显示小数位delayms(5000);}}/****主函数****/void main(){d1=1;d2=1;sp=1;displayinit();//初始化显示while(1){tmstart();//初始化read_dealtemp();//读取温度}}/****序列号读取程序****/#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^1; //温度传感器信号线sbit rs = P1^4; //LCD数据/命令选择端(H/L)位声明sbit lcden = P1^6; //LCD使能信号端位声明void delay(uint z); //延时函数void DS18B20_Reset(void); //DQ18B20复位,初始化函数bit DS18B20_Readbit(void); //读1位数据函数uchar DS18B20_ReadByte(void); //读1个字节数据函数void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数void LCD_WriteCom(uchar com); //1602液晶命令写入函数void LCD_WriteData(uchar dat); //1602液晶数据写入函数void LCD_Init();//LCD初始化函数void Display18B20Rom(char Rom); //显示18B20序列号函数/**********************************************//* 主函数*//**********************************************/void main(){ uchar a,b,c,d,e,f,g,h;LCD_Init();DS18B20_Reset();delay(1);DS18B20_WriteByte(0x33);delay(1);a = DS18B20_ReadByte();b = DS18B20_ReadByte();c = DS18B20_ReadByte();d = DS18B20_ReadByte();e = DS18B20_ReadByte();f = DS18B20_ReadByte();g = DS18B20_ReadByte();h = DS18B20_ReadByte();LCD_WriteCom(0x80+0x40);Display18B20Rom(h);Display18B20Rom(g);Display18B20Rom(f);Display18B20Rom(e);Display18B20Rom(d);Display18B20Rom(c);Display18B20Rom(b);Display18B20Rom(a);while(1);}/***************************************************//* 延时函数:void delay() *//* 功能:延时函数*//***************************************************/void delay(uint z)//延时函数{uint x,y;for( x = z; x > 0; x-- )for( y = 110; y > 0; y-- );}/***************************************************//* DS18B20函数:void DS18B20_Reset() *//* 功能:复位18B20 *//***************************************************/void DS18B20_Reset(void)//DQ18B20复位,初始化函数{uint i;DQ = 0;i = 103;while( i > 0 ) i--;DQ = 1;i = 4;while( i > 0 ) i--;}/***************************************************//* DS18B20函数:void DS18B20_Readbit() *//* 功能:读1个字节数据函数*//***************************************************/bit DS18B20_Readbit(void) //读1位数据函数{uint i;bit dat;DQ = 0;i++; //i++起延时作用DQ = 1;i++;i++;dat = DQ;i = 8;while( i > 0 )i--;return( dat );}/***************************************************//* DS18B20函数:void DS18B20_ReadByte() *//* 功能:读1个字节数据函数*//***************************************************/uchar DS18B20_ReadByte(void) //读1个字节数据函数{uchar i,j,dat;dat = 0;for( i = 1; i <= 8; i++ ){j = DS18B20_Readbit();dat = ( j << 7 ) | ( dat >> 1 );}return(dat);}/***************************************************//* DS18B20函数:void DS18B20_WriteByte() *//* 功能:向DQ18B20写一个字节数据函数*//***************************************************/void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数{uint i;uchar j;bit testb;for( j=1; j<=8; j++){testb = dat&0x01;dat= dat>>1;if(testb) //写1{DQ = 0;i++;i++;DQ = 1;i = 8;while(i>0)i--; }else{DQ = 0; //写0 i = 8;while(i>0)i--; DQ = 1;i++;i++;}}}/* LCD函数:void LCD_WriteCom() *//* 功能:向LCD写入命令*//***********************************************/void LCD_WriteCom(uchar com){rs = 0;P3= com;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}/***********************************************//* LCD函数:void LCD_WriteData(uchar dat) *//* 功能:向LCD写入数据*/void LCD_WriteData(uchar dat){rs = 1; //选择LCD为写入数据状态lcden = 0;P3= dat; //将待写入数据放到总线上delay(5);lcden = 1; //给LCD使能端一个脉冲delay(5); //信号将之前放到总线上lcden = 0; //的数据写入LCDdelay(5);}/***********************************************//* LCD函数:void LCD_Init() *//* 功能:初始化LCD,设定LCD的初始状态*/void LCD_Init(){LCD_WriteCom(0x38); //LCD显示模式设定delay(15);LCD_WriteCom(0x08); //关闭LCD显示delay(3);LCD_WriteCom(0x01); //LCD显示清屏delay(3);LCD_WriteCom(0x06); //设定光标地址指针为自动加1delay(3);LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标}/**********************************************//* *//* 显示18B20序列号*//* *//**********************************************/void Display18B20Rom(char Rom){uchar h,l;l = Rom & 0x0f; //取低4位h = Rom & 0xf0; //取高4位h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30);//取ASCII码elseLCD_WriteData(h+0x37);//取ASCII码if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30);//取ASCII码elseLCD_WriteData(l+0x37);//取ASCII码}。

DS18B20温度采集和显示程序

DS18B20温度采集和显示程序

这个是我自己制作的51单片机板上的DS18B20温度采集和显示程序,你如果有现成的51板稍微修改一下可以用,在我这里是可以用没问题的。

环境是KEIL。

我这个51板也完全符合你的要求。

#pragma db code#include<AT89X52.H>//#include "reg52.h"#include "INTRINS.H"// 此实验是使用18B20检测温度,然后在数码管上显示#define uchar unsigned char#define uint unsigned int#define BUSY1 (DQ1==0)sbit LED_0=P1^0;sbit LED_1=P1^1;sbit LED_2=P1^2;sbit LED_3=P1^3;sbit DQ1=P1^6;//void delay(uint x);void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);void ds_reset_1(void);void wr_ds18_1(char dat);void time_delay(unsigned char time);int get_temp_1(void);void delay(unsigned int x);void read_ROM(void);int get_temp_d(void);/*=====0-9=====A-G=====*/uchar a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82}; unsigned char ResultSignal;int ResultTemperatureLH,ResultT emperatureLL,ResultTemperatureH; unsigned char ROM[8];unsigned char idata TMP;unsigned char idata TMP_d;unsigned char f;unsigned char rd_ds18_1();unsigned int TemH,TemL;void main(){unsigned int TemH,TemL,k=0;ds_reset_1();ds_reset_1(); //resetwr_ds18_1(0xcc); //skip rom_nop_();wr_ds18_1(0x7f);ds_reset_1();wr_ds18_1(0xcc);_nop_();wr_ds18_1(0x44);for(k=0;k<11000;k++)time_delay(255);ds_reset_1();while(1){wr_ds18_1(0xcc);wr_ds18_1(0xbe);TemH=get_temp_1();TemL=get_temp_d();TemH&=0x00ff;TemL&=0x00ff;display((TemH/10),(T emH%10),(TemL/10),(TemL%10));}}/***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time){time=time-10;time=time/6;while(time!=0)time--;}/*****************************************************//* reset ds18b20 */ /*****************************************************/void ds_reset_1(void){unsigned char idata count=0;DQ1=0;time_delay(240);time_delay(240);DQ1=1;return;}void check_pre_1(void){while(DQ1);while(~DQ1);time_delay(30);}void read_ROM(void){int n;check_pre_1();wr_ds18_1(0x33);for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}}/*****************************************************//* Read a bit from 1820 位读取*/ /*****************************************************/bit tmrbit_1(void){idata char i=0;bit dat;DQ1=0;_nop_();DQ1=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();dat = DQ1;time_delay(50);return dat;}/*****************************************************//* read a bety from ds18b20 字节读取*/ /*****************************************************/unsigned char rd_ds18_1(){unsigned char idata i,j,dat=0;for(i=1;i<=8;i++){j=tmrbit_1();dat=(j<<(i-1))|dat;}return dat;}/*****************************************************//* write a bety from ds18b20 写字节*/ /****************************************************/void wr_ds18_1(char dat){signed char idata i=0;unsigned char idata j;bit testb;for(j=1;j<=8;j++){testb=dat & 0x01;dat = dat>>1;if(testb){DQ1=0;_nop_();_nop_();DQ1=1;time_delay(60);}else{DQ1=0;time_delay(50);DQ1=1;_nop_();_nop_();}}}int get_temp_1(void){unsigned char idata a=0,b=0; unsigned char idata i;EA=0;ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);if (a>8){TMP=(TMP+1);}}else{f=1;a=a>>4;b=b<<4;TMP=(a|b);TMP=~TMP;TMP=(TMP+1);}EA=1;return(TMP);}int get_temp_d(void){unsigned char idata a=0,b=0; unsigned char idata i,m;EA=0;ds_reset_1();//复位check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4)); a=(a&0x0f);TMP_d=a;}else{f=1;a=~a;a=(a+1);b=~b;b=(b+1);m=a;a=a>>4;b=b<<4;TMP=(a|b);m=(m&0x0f);TMP_d=m;}EA=1;return(TMP_d);}void delay(unsigned int x) {unsigned int i;for(i=0;i<x;i++);}void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4) {P2=a[d1];LED_0=0;delay(100);LED_0=1;P2=a[d2];LED_1=0;delay(100);LED_1=1;P2=a[d3];LED_2=0;delay(100);LED_2=1;P2=a[d4];LED_3=0;delay(100);LED_3=1;}。

DS18B20智能温度控制器(附软件程序)

DS18B20智能温度控制器(附软件程序)

DS18B20智能温度控制器DALLAS最新单线数字温度传感器DS18B20简介新的“一线器件”体积更小、适用电压更宽、更经济 Dallas 半导体公司的数字化温度传感器DS1820是世界上第一片支持“一线总线”接口的温度传感器。

一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。

DS18B20、 DS1822 “一线总线”数字化温度传感器同DS1820一样,DS18B20也支持“一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。

DS1822的精度较差为± 2°C 。

现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。

适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。

与前一代产品不同,新的产品支持3V~5.5V 的电压范围,使系统设计更灵活、方便。

而且新一代产品更便宜,体积更小。

DS18B20、 DS1822 的特性 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。

可选更小的封装方式,更宽的电压适用范围。

分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。

DS18B20的性能是新一代产品中最好的!性能价格比也非常出色! DS1822与 DS18B20软件兼容,是DS18B20的简化版本。

省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。

继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。

DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。

DS18B20的内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。

DS18B20测温程序

DS18B20测温程序

DS18B20测温程序(数码显示)*;************************************************************************** ;*接线方法: *;* 1、用一8P的数据线,一头插在J1,另一头插在J5,接通数码管的段选*;* 2、用一8P的数据线,一头插在J4,另一头插在J6,接通数码管的位选*;* 3、将DS18B20插在主机上的测温部份 *;* 4、用一根单根的数据线,一头插在DS18B20所在数据插针,另一头插到P2.7 * ;**************************************************************************TEMPER_L EQU 36H ;从DS18B20中读回高位,低位暂存区TEMPER_H EQU 35H ;TEMPER_NUM EQU 60H;温度值存储TEMPER_GE EQU 61HTEMPER_SHI EQU 62HTEMPER_SAVE EQU 63HFLAG1 BIT 00HFLAG2 BIT 01HRS BIT p3.0;液晶控制接口RW BIT p3.1E BIT p3.2DQ BIT P2.7;单总线口ORG 0000HA JMP MAINORG 0030HMAIN: MOV SP,#70HLCALL GET_TEMPERLCALL TEMPER_COVLCALL DISPLAYLJMP MAINNOP;**************************************************;读出转换后的温度值;**************************************************GET_TEMPER:SETB DQ ; 定时入口BCD: LCALL INIT_1820JB FLAG1,S22LJMP BCD ;若DS18B20不存在则返回S22: LCALL DELAY1MO V A,#0CCH ; 跳过ROM匹配------0CC命令LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL DELAYCBA CALL INIT_1820JB FLAG1,ABCLJMP CBAABC CALL DELA Y1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;READ_1820RET;************************************************************** ;读DS18B20的程序,从DS18B20中读出一个字节的数据;************************************************************** READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;******************************************************;写DS18B20的程序;******************************************************WRITE_1820:MOV R2,#8CLR CWR1:MOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;****************************************************;读DS18B20的程序,从DS18B20中读出两个字节的温度数据;****************************************************READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;;****************************************************;将从DS18B20中读出的温度数据进行转换;;****************************************************TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,A ;得到低四位MOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUM ;得到高四位,再与低四位相或得到值MOV TEMPER_NUM,A ; 保存变换后的温度数据LCALL BIN_BCDRET;;**************************************************** ;将16进制的温度数据转换成压缩BCD码;;**************************************************** BIN_BCD:MOV A,TEMPER_NUMMOV B,#10DIV ABMOV TEMPER_SHI,AMOV TEMPER_GE,BMOV A,TEMPER_SAVECJNE A,TEMPER_GE,ZWFHRET:MOV TEMPER_SAVE,TEMPER_GERETZW:CALL LCDDISPAJMP FHRET;**************************************************** ;DS18B20初始化程序;;**************************************************** INIT_1820:SETB DQNOPCLR DQMOV R0,#250TSR1:DJNZ R0,TSR1 ; 延时520usSETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3;如D0为低则复位成功,DS18B20存在LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQ ;拉高总线RET;************************************************* ;数码显示程序;************************************************* Display:MOV DPTR,#disptabMOV A,TEMPER_GEMOVC A,@A+DPTRMOV P1,ACLR P2.2CALL DELAYCALL DELAYSETB P2.2MOV DPTR,#disptabMOV A,TEMPER_SHIMOVC A,@A+DPTRMOV P1,ACLR P2.3CALL DELAYCALL DELAYSETB P2.3RET;************************************************* ;液晶显示程序;*************************************************mov p0,#01h;清屏call enrwmov p0,#38h;设为8位,5*7字型两行 call enrwmov p0,#0Chcall enrwmov p0,#06hcall enrwmov p0,#80hcall enrwmov dptr,#yjtabcall rwrammov p0,#0C0hcall enrwmov dptr,#yjtab1call rwramW_TEM:mov p0,#0CChcall enrwMO V DPTR,#ASCIIMO V A,TEMPER_SHIMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eMO V DPTR,#ASCIIMO V A,TEMPER_GEMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eRE Tenrw:clr rsclr rwclr esetb eretrwram:mov r1,#00ha1: mov a,r1movc a,@a+dptrcall rwram2inc r1cjne a,#00h,a1retrwram2:mov p0,asetb rsclr rwclr ecall delaysetb eret;*************************************************;延时子程序;*************************************************DELAY:MOV R6,#250;延时500usDJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RETdisptab:db 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;字形代码表 ;0 1 2 3 4 5 6 7 8 9yjtab: db 'HTTP// ',00hyjtab1:db 'CHENZHOU_TE:**`C',00hASCII: DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39Hend。

DS18B20温度传感器详细注解及驱动程序解析

DS18B20温度传感器详细注解及驱动程序解析

DS18B20独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条线即可实现微处理器与DS18B20的双向通讯。

测温范围-55℃~+125℃,固有测温误差(注意,不是分辨率,这里之前是错误的)1℃。

支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。

工作电源:3.0~5.5V/DC(可以数据线寄生电源)在使用中不需要任何外围元件。

测量结果以9~12位数字量方式串行传送。

如果使用51单片机的话,那么中间那个引脚必须接上4.7K~10K的上拉电阻,否则,由于高电平不能正常输入/输出,要么通电后立即显示85℃,要么用几个月后温度在85℃与正常值上乱跳。

根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。

读ROM 33H 读DS1820温度传感器ROM中的编码(即64位地址)发出此命令之后,接着发出64 位ROM 编码,访问单总线上与该编码相符合ROM 55H对应的DS1820 使之作出响应,为下一步对该DS1820 的读写作准备。

用于确定挂接在同一总线上DS1820 的个数和识别64 位ROM 地址。

为搜索ROM FOH操作各器件作好准备。

跳过ROM CCH 忽略64 位ROM 地址,直接向DS1820 发温度变换命令。

告警搜索ECH 执行后只有温度超过设定值上限或下限的片子才做出响应。

RAM命令启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75m温度变换44Hs)。

结果存入内部第0、1字节RAM中。

1、复位操作复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

温度传感器DS18B20检测程序说明

温度传感器DS18B20检测程序说明

DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。

编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。

对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。

接下来我先说一下这三个部分所对应的时序图的理解吧。

初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。

上面一图是写入数据的时序图。

写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。

下面一图是读取数据的时序图。

读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。

下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。

#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1
DS18B20.h
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
#ifndef _DS18B20_H #define _DS18B20_H #include "stc15f2k60s2.h" #include "intrins.h" //注意添加头文件 sbit DQ = P1^4; //单总线接口
//单总线延时函数,针对1T单片机修改延时函数 //t*6us延时,可以视情况修改 void Delay_OneWire(unsigned int t) { unsigned char i; while(t--) { for(i=0;i<12;i++); } } //DS18B20芯片初始化 bit Init_DS18B20(void) { bit initflag = 0; DQ = 1; Delay_OneWire(12); DQ = 0; Delay_OneWire(80); DQ = 1; Delay_OneWire(10); initflag = DQ; Delay_OneWire(5); return initflag; } //通过单总线向DS18B20写一个字节 void Write_DS18B20(unsigned char dat) { unsigned char i; for(i=0;i<8;i++) { DQ = 0; DQ = dat&0x01; Delay_OneWire(5); DQ = 1; dat >>= 1; } Delay_OneWire(5); } //从DS18B20读取一个字节 unsigned char Read_DS18B20(void) { unsigned char i; unsigned char dat; for(i=0;i<8;i++) { DQ = 0; dat >>= 1; DQ = 1; if(DQ) { dat |= 0x80; } Delay_OneWire(5); }
DS18B20.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
return dat; } void Start18B20(void) { Init_DS18B20(); Write_DS18B20(0xCC); //跳过ROM操作 Write_DS18B20(0x44); //启动一次温度转换 } /*注意*/ unsigned char GetTemp(void) { unsigned char temp, LSB, MSB; Init_DS18B20(); Write_DS18B20(0xCC); //跳过ROM操作 Write_DS18B20(0xBE); //发送读命令 LSB = Read_DS18B20(); //读温度值的高字节 MSB = Read_DS18B20(); //读温度值的低字节 temp = (LSB>>4) | (MSB<<4); return temp; } #endif
2
相关文档
最新文档