DS18B20介绍、流程图和程序源代码

合集下载

DS18B20温度检测程序

DS18B20温度检测程序

(1)先将数据线置高电平“1”。

(2)延时(该时间要求的不是很严格,但是尽可能的短一点)(3)数据线拉到低电平“0”。

(4)延时750微秒(该时间的时间范围可以从480到960微秒)。

(5)数据线拉到高电平“1”。

(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。

据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。

(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。

(8)将数据线再次拉高到高电平“1”后结束。

(1)数据线先置低电平“0”。

(2)延时确定的时间为15微秒。

(3)按从低位到高位的顺序发送字节(一次只发送一位)。

(4)延时时间为45微秒。

(5)将数据线拉到高电平。

(6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7)最后将数据线拉高。

DS18B20的写操作时序图如图DS18B20的读操作(1)将数据线拉高“1”。

(2)延时2微秒。

(3)将数据线拉低“0”。

(4)延时15微秒。

(5)将数据线拉高“1”。

(6)延时15微秒。

(7)读数据线的状态得到1个状态位,并进行数据处理。

(8)延时30微秒。

DS18B20的读操作时序图如图所示。

DS18B20的Protues仿真图源程序代码:#include "reg51.h"#include "intrins.h" // 此头文件中有空操作语句NOP 几个微秒的延时可以用NOP 语句,但本人没用NOP,直接用了I++来延时#define uchar unsigned char#define uint unsigned intuchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};sbit ds18b20_io=P2^0; //单片机与DS18B20的连接口sbit lcdrs=P2^6; //1602与单片机的接口sbit lcden=P2^7;unsigned char flag,tflag,i;unsigned int temper0,temper1,tvalue;float temperature;void delay() //6us 在KEIL中仿真出来的时间,这是调用DELAY所用的时间{i++;i++;}void Delay_50us(unsigned char t) //50us延时程序{unsigned char j;for(;t>0;t--)for(j=20;j>0;j--);}void delay1(uint z) //这个延时主要用在1602中,1602的读写时序没有//DS18B20那么严格{uint x,y;for(x=0;x<z;x++){ for(y=0;y<121;y++){;};};}uchar ds18b20_rst(){unsigned char j;ds18b20_io=1;i++; //1usds18b20_io=0;for(j=0;j<60;j++) //543us{delay();}ds18b20_io=1;for( j=0;j<7;j++) //65us{delay();}if(!ds18b20_io) //如果读到低电平,即复位成功{flag=1;}else flag=0; //如果没有读到低电平,则复位失败Delay_50us(9); //450usds18b20_io=1;return flag;}void ds18b20_writebyte(unsigned char byte){unsigned char j;for(j=0;j<8;j++){ds18b20_io=1;i++;ds18b20_io=0;delay(); //15usdelay();i++;i++;i++;ds18b20_io=byte&0x01;delay(); delay();delay();delay(); //48usdelay(); delay();delay();byte>>=1;ds18b20_io=1;delay();}ds18b20_io=1;}unsigned char ds18b20_readbyte() {unsigned char k,jj,i;jj=0;for(k=0;k<8;k++){ds18b20_io=1;i++; i++;ds18b20_io=0;delay(); //15usdelay(); i++;i++;i++;ds18b20_io=1;delay(); //15usdelay(); i++; i++;i++;if(ds18b20_io) //17us jj=(jj>>1)|0x80;elsejj>>=1;delay();delay(); delay(); //18us }return jj;}void write_com(uchar com){lcdrs=0;P1=com;delay1(5);lcden=1;delay1(5);lcden=0;}void write_data(uchar date){lcdrs=1;P1=date;delay1(5);lcden=1;delay1(5);lcden=0;}void init(){lcden=0;write_com(0x38);write_com(0x0C);write_com(0x06);write_com(0x01);}float read_temp()/*读取温度值并转换*/{if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ ds18b20_writebyte(0x44);//*启动温度转换*/ Delay_50us(30);}if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ds18b20_writebyte(0xbe);//*读取温度*/temper0 =ds18b20_readbyte();temper1 =ds18b20_readbyte();Delay_50us(20);}if(temper1&0xf8) //判断是正温度还是负温度{ //如果是高5位是0 为正温度,反则为负温度tflag=1;tvalue=(temper1<<8)|temper0;tvalue=((~tvalue)+1);temperature=tvalue*(0.0625);}else{tflag=0;tvalue=(temper1<<8)|temper0;temperature=tvalue*0.0625; //不用把tvalue进行转换,直接乘0.0625//的精度}return(temperature);}void write_xian(float date){uint bai,shi,ge,xiaozheng,xqian,xbai,xshi,xge;float k,m; //把浮点的DATA转换为整数,得到浮点娄的整数部分bai=(int)(date)/100; //把得到的整数部分拆开分别存在BAI SHI GE 中shi=((int)(date)%100)/10;ge=(int)(date)%10;if (bai!=0) //如果百不为0 则把整数部分全部显示{write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}else if (shi!=0) //如果十不为0 则把十位和个位显示{write_data(0x30+shi);write_data(0x30+ge);}else write_data(0x30+ge);//如果百和十位都为0 ,则只显示个位数write_data(0x2e);k=date-(int)date; //取浮点娄的小数部分m=k*10000; //把得到的小数变为整数并显示xiaozheng=(int)m;xqian=(xiaozheng)/1000;xbai=((xiaozheng)%1000)/100;xshi=((xiaozheng)%100)/10;xge=(xiaozheng)%10;write_data(0x30+xqian);write_data(0x30+xbai);write_data(0x30+xshi);write_data(0x30+xge);}void main(){temperature=0.0;flag=0;tflag=0;tvalue=0;init();while(1){read_temp();if(tflag==0){write_xian(temperature); write_data(' '); write_data(' '); }if(tflag==1){write_data('-');write_xian(temperature); write_data(' '); write_data(' '); }write_com(0x80);}}。

DS18B20温度传感器实现代码

DS18B20温度传感器实现代码

DS18B20温度传感器实现代码平台: freescale CodeWarriorMCU:MC9S12G128(汽车级芯⽚)#include "Ds18b20.h"/************************************************************* DS18B20 status initialization************************************************************/#pragma MESSAGE DISABLE C12056 //屏蔽警告INT8U Ds18b20StsInit(void){INT8U ack = DB_OK;INT16U outTime = 500;//DisableInterrupts/* 初始化状态 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);/* 拉低BUS,延时500us */BUS = LOW;DelayUs(480);/* BUS上拉,延时15us-60us */BUS = HIGH;DelayUs(30);/* BUS设置为输⼊ */BUS_DIR = LOW;/* 等待DS18B20存在脉冲做出回应,0正常,60-240us */DelayUs(8);while(BUS){--outTime; //超时处理if(outTime == 0){ack = DB_ERR;break;}}/* 等待DS18B20恢复稳定 */DelayUs(128);/* BUS上拉 */BUS_DIR = HIGH;BUS = HIGH;DelayUs(280);//EnableInterruptsreturn (ack);}/************************************************************* Write data to ds18b20************************************************************/PRIVATE void Ds18b20WriteData(INT8U cmd){INT8U i;DisableInterruptsfor(i = 0; i < 8; i++){//BUS = LOW; //HIGH->LOW 启动写时序//Tim_Delay8Us(2);if(cmd & 0x01) //从低位开始发送数据,15us完成 {BUS = 0; //写1时序DelayUs(5);BUS = 1;}else{BUS = 0; //写0时序DelayUs(5);}DelayUs(60); //等待从器件采集数据BUS = HIGH; //拉⾼总线,起始状态DelayUs(8);cmd >>= 0x01;}EnableInterrupts}#if 1/************************************************************* Read data from ds18b20************************************************************/ PRIVATE INT8U Ds18b20ReadData(void){INT8U i;INT8U data = 0x00;BUS = HIGH;DelayUs(8);DisableInterruptsfor(i = 0; i < 8; i++){data >>= 0x01;BUS = LOW; //拉低总线,进⾏读时序操作 DelayUs(8);BUS = HIGH; //拉低总线,进⾏读时序操作 DelayUs(8);BUS_DIR = LOW; //配置为输⼊asm("nop");//Tim_Delay8Us(1);if(BUS){data |= 0x80;}DelayUs(60); //等待数据读缓存BUS_DIR = HIGH;BUS = HIGH;DelayUs(8);}EnableInterruptsreturn (data);#endifINT8U Dt = 0, Dt1 = 0;/************************************************************* Get data from ds18b20************************************************************/INT16U Ds18b20GetTemperature(void){INT16U data = CLEAR;INT8U temp[2] = {0};Dt = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0x44); //启动温度转换Dt1 = Ds18b20StsInit();Ds18b20WriteData(0xcc); //跳过rom命令Ds18b20WriteData(0xbe); //读暂存寄存器temp[0] = Ds18b20ReadData();temp[1] = Ds18b20ReadData();data = (temp[1] << 8) | temp[0];return (data);}调试DS18B20遇到采集数据不稳定情况: 不稳定现象:每读到⼏个正常数据后会有⼏个不正常的数据 不稳定原因:因为中断在打断我数据的读写以及采集 解决办法:因为DS18B20单总线读写时对时序要求很严格,每次读写时关闭中断即可得到稳定数据。

DS18B20,源程序

DS18B20,源程序
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;//*****************************************//
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
;//*****************************************//
TEMPER_H EQU 35H
DQ BIT P1.7
; DS18B20初始化程序
;//*****************************************//
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_1820
MOV TEMPER_NUM,A ; 将读出的温度数据保存
SWAP A
MOV TEMPER_NUM,A
MOV A,TEMPER_L
JNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值
INC TEMPER_NUM
TEMPER_COV1:
MOV A,TEMPER_H
;//*****************************************//
GET_TEMPER:
SETB DQ ; 定时入口
LCALL INIT_1820
JB FLAG1,TSS2
RET ; 若DS18B20不存在则返回

DS18B20温度传感器设计原理图及c程序代码

DS18B20温度传感器设计原理图及c程序代码

/*******************代码部分**********************//*************** writer:shopping.w ******************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}sbit DQ = P3^3;sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;uchar code Temp_Disp_Title[]={"Current Temp : "};uchar Current_Temp_Display_Buffer[]={" TEMP: "};uchar code Temperature_Char[8] ={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};uchar code df_Table[]=0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};uchar CurrentT = 0;uchar Temp_Value[]={0x00,0x00}; uchar Display_Digit[]={0,0,0,0};bit DS18B20_IS_OK = 1;void DelayXus(uint x){uchar i;while(x--){for(i=0;i<200;i++);}}bit LCD_Busy_Check(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delayNOP();result = (bit)(P0&0x80);LCD_EN=0;return result;}void Write_LCD_Command(uchar cmd) {while(LCD_Busy_Check());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();P0 = cmd;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void Write_LCD_Data(uchar dat){while(LCD_Busy_Check());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void LCD_Initialise(){Write_LCD_Command(0x01);DelayXus(5);Write_LCD_Command(0x38);DelayXus(5);Write_LCD_Command(0x0c);DelayXus(5);Write_LCD_Command(0x06);DelayXus(5);}void Set_LCD_POS(uchar pos){Write_LCD_Command(pos|0x80); }void Delay(uint x){while(--x);}uchar Init_DS18B20(){uchar status;DQ = 1;Delay(8);DQ = 0;Delay(90);DQ = 1;Delay(8);DQ = 1;return status;}uchar ReadOneByte(){uchar i,dat=0;DQ = 1;_nop_();for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;_nop_();_nop_();if(DQ)dat |= 0X80;Delay(30);DQ = 1;}return dat;}void WriteOneByte(uchar dat) {uchar i;for(i=0;i<8;i++){DQ = 0;DQ = dat& 0x01;Delay(5);DQ = 1;dat >>= 1;}}void Read_Temperature(){if(Init_DS18B20()==1)DS18B20_IS_OK=0;else{WriteOneByte(0xcc);WriteOneByte(0x44);Init_DS18B20();WriteOneByte(0xcc);WriteOneByte(0xbe);Temp_Value[0] = ReadOneByte();Temp_Value[1] = ReadOneByte();DS18B20_IS_OK=1;}}void Display_Temperature(){uchar i;uchar t = 150, ng = 0;if((Temp_Value[1]&0xf8)==0xf8){Temp_Value[1] = ~Temp_Value[1];Temp_Value[0] = ~Temp_Value[0]+1;if(Temp_Value[0]==0x00)Temp_Value[1]++;ng = 1;}Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);Display_Digit[3] = CurrentT/100;Display_Digit[2] = CurrentT%100/10;Display_Digit[1] = CurrentT%10;Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';Current_Temp_Display_Buffer[10] = '.';Current_Temp_Display_Buffer[9] = Display_Digit[1] + '0';Current_Temp_Display_Buffer[8] = Display_Digit[2] + '0';Current_Temp_Display_Buffer[7] = Display_Digit[3] + '0';if(Display_Digit[3] == 0)Current_Temp_Display_Buffer[7] = ' ';if(Display_Digit[2] == 0&&Display_Digit[3]==0)Current_Temp_Display_Buffer[8] = ' ';if(ng){if(Current_Temp_Display_Buffer[8] == ' ')Current_Temp_Display_Buffer[8] = '-';else if(Current_Temp_Display_Buffer[7] == ' ')Current_Temp_Display_Buffer[7] = '-';elseCurrent_Temp_Display_Buffer[6] = '-';}Set_LCD_POS(0x00);for(i=0;i<16;i++){Write_LCD_Data(Temp_Disp_Title[i]);}Set_LCD_POS(0x40);for(i=0;i<16;i++){Write_LCD_Data(Current_Temp_Display_Buffer[i]);}Set_LCD_POS(0x4d);Write_LCD_Data(0x00);Set_LCD_POS(0x4e);Write_LCD_Data('C');}void main(){LCD_Initialise();Read_Temperature();Delay(50000);Delay(50000);while(1){Read_Temperature();if(DS18B20_IS_OK)Display_Temperature();DelayXus(100);}}。

ds18b20详解及程序

ds18b20详解及程序

最近都在学习和写单片机的程序, 今天有空又模仿写了一个与DS18B20基于单总线通信的程序.DS18B20 数字温度传感器(参考:是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。

DS18B20 产品的特点:(1)、只要求一个I/O 口即可实现通信。

(2)、在DS18B20 中的每个器件上都有独一无二的序列号。

(3)、实际应用中不需要外部任何元器件即可实现测温。

(4)、测量温度范围在-55 到+125℃之间; 在-10 ~ +85℃范围内误差为±5℃; (5)、数字温度计的分辨率用户可以从9 位到12 位选择。

将12位的温度值转换为数字量所需时间不超过750ms;(6)、内部有温度上、下限告警设置。

DS18B20引脚分布图DS18B20 详细引脚功能描述:1、GND 地信号;2、DQ数据输入出引脚。

开漏单总线接口引脚。

当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路, 常太下高电平. 通常要求外接一个约5kΩ的上拉电阻.3、VDD可选择的VDD 引脚。

电压范围:3~; 当工作于寄生电源时,此引脚必须接地。

DS18B20存储器结构图暂存储器的头两个字节为测得温度信息的低位和高位字节;第3, 4字节是TH和TL的易失性拷贝, 在每次电复位时都会被刷新;第5字节是配置寄存器的易失性拷贝, 同样在电复位时被刷新;第9字节是前面8个字节的CRC检验值.0 R1 R0 1 1 1 1 1MSB LSBR0和R1是温度值分辨率位, 按下表进行配置.默认出厂设置是R1R0 = 11, 即12位.温度值分辨率配置表R1 R0 分辨率最大转换时间(ms)0 0 9bit (tconv/8)0 1 10bit (tconv/4)1 0 11bit 375(tconv/2)1 1 12bit 750 (tconv)4种分辨率对应的温度分辨率为0.5℃, 0.25℃, 0.125℃, 0.0625℃(即最低一位代表的温度值)12位分辨率时的两个温度字节的具体格式如下:低字节:2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4高字节:其中高字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨, 高字节不变....一些温度与转换后输出的数字参照如下:由上表可看出, 当输出是负温度时, 使用补码表示, 方便计算机运算(若是用C语言, 直接将结果赋值给一个int变量即可).DS18B20 的使用方法:由于DS18B20 采用的是方式,即在一根数据线实现数据的双向传输,而对单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

ds18b20汇编设计报告(附电路图和程序)

ds18b20汇编设计报告(附电路图和程序)

基于AT89C51单片机和DS18B20的数字温度计1课题说明随着现代信息技术的飞速发展和传统工业改造的逐步实现,能够独立工作的温度检测和显示系统应用于诸多领域。

传统的温度检测以热敏电阻为温度敏感元件。

热敏电阻的成本低,但需后续信号处理电路,而且可靠性相对较差,测温准确度低,检测系统也有一定的误差。

这里设计的数字温度计具有读数方便,测温范围广,测温精确,数字显示,适用范围宽等特点。

本设计选用AT89C51型单片机作为主控制器件,DS18B20作为测温传感器,通过LCD1602实现温度显示。

通过DS18B20直接读取被测温度值,进行数据转换,该器件的物理化学性能稳定,线性度较好,在0℃~100℃最大线性偏差小于0.01℃。

该器件可直接向单片机传输数字信号,便于单片机处理及控制。

另外,该温度计还能直接采用测温器件测量温度,从而简化数据传输与处理过程。

2 实现方法采用数字温度芯片DS18B20 测量温度,输出信号全数字化。

采用了单总线的数据传输,由数字温度计DS18B20和AT89C51单片机构成的温度测量装置,它直接输出温度的数字信号,也可直接与计算机连接。

采用AT89C51单片机控制,软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。

该系统利用AT89S51芯片控制温度传感器DS18B20进行实时温度检测并显示,能够实现快速测量环境温度,并可以根据需要设定上下限温度。

该系统扩展性非常强。

该测温系统电路简单、精确度较高、实现方便、软件设计也比较简单。

系统框图如图1所示。

图1 DS18B20温度测温系统框图3 硬件设计3.1 单片机最小系统设计3.1.1 电源电路VCC图2 电源电路3.1.2 振荡电路与复位电路图3 振荡电路图4 复位电路3.2 DS18B20与单片机的接口电路图5 DS18B20与单片机的接口电路3.3 PROTEUS仿真电路图图6 PROTEUS仿真电路图4 软件设计系统程序主要包括主程序、读取温度子程序、数据转换子程序、显示数据子程序等。

DS18B20原理及程序编写

DS18B20原理及程序编写

DS18B20原理及程序编写(一)概述DS18B20为单总线12位(二进制)温度读数。

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

工作电压从3.0~5.5V。

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

最高±0.0625℃分辩率。

其内部结构如下图所示。

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”命令。

DS18B20芯片内部共有8字节的寄存器,其中地址编号0,1为温度寄存器,里面存储着DS18B20温度转换后的AD值,其格式如表1所示。

地址编号2,3为温度报警寄存器,里面为报警设定值,地址编号4为配置寄存器(这三个寄存器在读取之前请使用“重新调入EEPROM”命令将存储在EEPROM里的内容调出,同样,在向温度报警寄存器里写入内容后,也要使用“复制到存储器”命令48H将温度报警寄存器内的内容存入EEPROM当中,以免掉电丢失数据)。

DS18B20内部寄存器映射如下图所示。

配置寄存器的格式如表2和表3所示。

DS18B20内部寄存器映射表1 温度寄存器的格式表2 配置寄存器的格式表3 温度分辨率配置DS18B20使用单总线工作方式,其通信协议以电平的高平时间作为依据,其基本时序有复位时序,写时序、读时序。

//********************************************************************** //** 文件名:DS18B20.c//** 说明:DS18B20驱动程序文件//----------------------------------------------------------------------//** 单位://** 创建人:张雅//** 创建时间:2010-01-20//** 联系方式:QQ:276564402//** 版本:V1.0//----------------------------------------------------------------------//**********************************************************************//----------------------------------------------------------------------//** 芯片:AT89S52//** 时钟:11.0592MHz//** 其它:这个文档为18B20的驱动程序,引用了数码管的驱动。

DS18B20介绍、流程图和程序源代码

DS18B20介绍、流程图和程序源代码

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

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

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

现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性,适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。

DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C,分辨率设定,以及用户设定的报警温度存储在EEPROM中,掉电后依然保存。

DS1822与DS18B20软件兼容,是DS18B20的简化版本。

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

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

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

1、 DS18B20性能特点DS18B20的性能特点:①采用单总线专用技术,既可通过串行口线,也可通过其它I/O口线与微机接口,无须经过其它变换电路,直接输出被测温度值(9位二进制数,含符号位),②测温范围为-55℃-+125℃,测量分辨率为0.0625℃,③内含64位经过激光修正的只读存储器ROM,④适配各种单片机或系统机,⑤用户可分别设定各路温度的上、下限,⑥内含寄生电源。

18b20流程图

18b20流程图

写完8位数据?
数据右移
延时数微秒
结束
函数功能:从ds18b20读数据 函数名date>>=1;:readonechar 返回值:temp
开始
将数据线拉高,延时1微秒
将数据线拉低,延时1微秒
将数据线拉高,延时6微秒
数据右移
如果数据线=1,data和80H或,否则data和00H或
读完8位数据?
延时数微秒 返回读到的数据
将数据线拉高,延时6微秒
将数据线拉低,延时600微秒
Байду номын сангаас
释放数据线(拉高),延时30微秒
主机从数据线采样
延时数毫秒,返回采样值
函数功能:向ds18b20写数据 函数名:writeonechar 形式参数:dat
开始
将数据线拉高,延时1微秒
将数据线拉低(启动写功能)
将数据最低位写入数据线,延时30微秒
释放数据线,延时数微秒
以下是DS18b20的流程图
时序
• 1.首先启动 :打开测温功能(1.初始化2. 命令字) • 2.调用数值 :告诉18b20调温度值(0xbe) • 3.读温度 跳过rom (0xcc) 温度变换 (0x44)
函数功能:18b20的初始化 函数名:init-ds18b20 返回值:falg 开始

18B20详细介绍及程序

18B20详细介绍及程序

1.DS18B20基本知识DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。

1、DS18B20产品的特点(1)、只要求一个端口即可实现通信。

(2)、在DS18B20中的每个器件上都有独一无二的序列号。

(3)、实际应用中不需要外部任何元器件即可实现测温。

(4)、测量温度范围在-55。

C到+125。

C之间。

(5)、数字温度计的分辨率用户可以从9位到12位选择。

(6)、内部有温度上、下限告警设置。

2、DS18B20的引脚介绍TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。

(底视图)图1表1DS18B20详细引脚功能描述3.DS18B20的使用方法由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。

DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。

该协议定义了几种信号的时序:初始化时序、读时序、写时序。

所有时序都是将主机作为主设备,单总线器件作为从设备。

而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。

数据和命令的传输都是低位在先。

DS18B20的复位时序DS18B20的读时序对于DS18B20的读时序分为读0时序和读1时序两个过程。

对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。

DS18B20在完成一个读时序过程,至少需要60us才能完成。

DS18B20温度传感器使用方法以及代码

DS18B20温度传感器使用方法以及代码

第7章DS18B20温度传感器7.1 温度传感器概述温度传感器是各种传感器中最常用的一种,早起使用的是模拟温度传感器,如热敏电阻,随着环境温度的变化,它的阻值也发生线性变化,用处理器采集电阻两端的电压,然后根据某个公式就可以计算出当前环境温度。

随着科技的进步,现代的温度传感器已经走向数字化,外形小,接口简单,广泛应用在生产实践的各个领域,为我们的生活提供便利。

随着现代仪器的发展,微型化、集成化、数字化、正成为传感器发展的一个重要方向。

美国DALLS半导体公司推出的数字化温度传感器DS18B20采用单总线协议,即单片机接口仅需占用一个I/O端口,无需任何外部元件,直接将环境温度转化为数字信号,以数码方式串行输出,从而大大简化了传感器与微处理器的接口。

7.2 DS18B20温度传感器介绍DS18B20是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。

与传统的热敏电阻相比,他能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。

可以分别在93.75 ms和750 ms内完成9位和12位的数字量,并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所挂接的DS18B20供电,而无需额外电源。

因而使用DS18B20可使系统结构更趋简单,可靠性更高。

他在测温精度、转换时间、传输距离、分辨率等方面较DS1820有了很大的改进,给用户带来了更方便的使用和更令人满意的效果。

1.DS18B20温度传感器的特性①独特的单线接口方式:DS18B20与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。

②在使用中不需要任何外围元件。

③可用数据线供电,电压范围:+3.0~ +5.5 V。

④测温范围:-55 ~+125 ℃。

固有测温分辨率为0.5 ℃。

⑤通过编程可实现9~12位的数字读数方式。

DS18B20详解及程序

DS18B20详解及程序

DS18B20 数字温度传感器(参考:智能温度传感器DS18B20的原理与应用)是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。

DS18B20 产品的特点:(1)、只要求一个I/O 口即可实现通信。

(2)、在DS18B20 中的每个器件上都有独一无二的序列号。

(3)、实际应用中不需要外部任何元器件即可实现测温。

(4)、测量温度范围在-55 到+125℃之间; 在-10 ~ +85℃范围内误差为±5℃; (5)、数字温度计的分辨率用户可以从9 位到12 位选择。

将12位的温度值转换为数字量所需时间不超过750ms;(6)、内部有温度上、下限告警设置。

DS18B20引脚分布图DS18B20 详细引脚功能描述:1、GND 地信号;2、DQ数据输入出引脚。

开漏单总线接口引脚。

当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路, 常太下高电平. 通常要求外接一个约5kΩ的上拉电阻.3、VDD可选择的VDD 引脚。

电压范围:3~5.5V; 当工作于寄生电源时,此引脚必须接地。

DS18B20存储器结构图暂存储器的头两个字节为测得温度信息的低位和高位字节;第3, 4字节是TH和TL的易失性拷贝, 在每次电复位时都会被刷新;第5字节是配置寄存器的易失性拷贝, 同样在电复位时被刷新;第9字节是前面8个字节的CRC检验值.配置寄存器的命令内容如下:0 R1 R0 1 1 1 1 1MSB LSBR0和R1是温度值分辨率位, 按下表进行配置.默认出厂设置是R1R0 = 11, 即12位.温度值分辨率配置表R1 R0 分辨率最大转换时间(ms)0 0 9bit 93.75(tconv/8)0 1 10bit 183.50(tconv/4)1 0 11bit 375(tconv/2)1 1 12bit 750 (tconv)4种分辨率对应的温度分辨率为0.5℃, 0.25℃, 0.125℃, 0.0625℃(即最低一位代表的温度值)12位分辨率时的两个温度字节的具体格式如下:低字节:2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4高字节:S S S S S 2^6 2^5 2^4其中高字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨率为10位时, 低字节为:2^3 2^2 2^1 2^0 2^-1 2^-2 0 0, 高字节不变....一些温度与转换后输出的数字参照如下:温度数字输出换成16进制+125℃000001111101000007D0H+85℃00000101010100000550H+25.0625℃00000001100100010191H+10.125℃000000001010001000A2H+0.5℃00000000000010000008H0℃00000000000000000000H-0.5℃1111111111111000FFF8H-10.125℃1111111101011110FFE5H-25.0625℃1111111001101111FF6FH-55℃1111110010010000FC90H由上表可看出, 当输出是负温度时, 使用补码表示, 方便计算机运算(若是用C语言, 直接将结果赋值给一个int变量即可).DS18B20 的使用方法:由于DS18B20 采用的是1-Wire 总线协议方式,即在一根数据线实现数据的双向传输,而对单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

基于ds18b20的温度计设计代码

基于ds18b20的温度计设计代码

基于DS18B20的温度计设计代码一、介绍DS18B20温度计DS18B20是一种数字温度传感器,由美国达拉斯半导体公司生产。

它采用单总线通信协议,并可以通过单总线接口进行多级串联。

DS18B20具有精度高、稳定性好、响应速度快等特点,因此在各种温度测量应用中被广泛使用。

二、DS18B20温度计设计代码在使用DS18B20温度传感器时,我们通常需要编写相应的代码来读取传感器的数据并进行温度计算。

以下是基于Arduino评台的DS18B20温度计设计代码:```c#include <OneWire.h>#include <DallasTemperature.h>#define ONE_WIRE_BUS 2 // 设置DS18B20数据线连接的Arduino 引脚OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup() {Serial.begin(9600);sensors.begin();}void loop() {sensors.requestTemperatures(); // 发送获取温度命令float temperatureC = sensors.getTempCByIndex(0); // 获取温度值(摄氏度)float temperatureF = sensors.toFahrenheit(temperatureC); // 转换为华氏度Serial.print("Temperature: ");Serial.print(temperatureC);Serial.print("°C / ");Serial.print(temperatureF);Serial.println("°F");delay(1000); // 延时1s}```以上代码使用了OneWire库和DallasTemperature库来实现对DS18B20的温度测量。

DS18B20温度传感器流程图

DS18B20温度传感器流程图

Y
发温度转换 开始 命令
1 a1
1 a1
பைடு நூலகம்2 a2
3 a3
4 a4
5 b1
6 b2
7 b3
8 b4
2 b1
2 b1
5 b1
6 b2
7 b3
8 b4
开始
温度零 下?
Y
温度值取补码 置“-”标志
计算小数位温 度BCD码
N 置“+”标志
计算整数位温 度BCD码
结束
DS18B20
主控制器
AT89C2051
显示器 扫描驱动
预置 低温度系数振荡器
发DS18B20复位命令
发跳过ROM命令
CRC校验正确?
Y
发读取温度命令
移入温度暂存器 N
Y
读取操作,CRC校验 N
结束
9字节完?
温度子程序
64位ROM和单线接口 存缓速高
存储器与控制逻辑
温度传感器 温度触发器 TH 低温触发器 TL
配置寄存器 8位CRC发生器
1 a1
2 a2
3 a3
4 a4
1 a1
斜率累加器 减法计数器
计数比较器 预置
高温度系数振荡器
减到0
增加
减法计数器2
温度寄存器
停止
减到0
I/O C
Vdd
64位ROM和单线接口 存缓速高
存储器与控制逻辑
温度传感器 温度触发器 TH 低温触发器 TL
配置寄存器 8位CRC发生器
温度数据移入 显示寄存器
发DS18B20复位命令 发跳过ROM命令
发温度转换开始命令
十位数0?
Y
百位数0?

DS18B20编程

DS18B20编程
*************************/
uint8 read_byte(void)
{
uint8 tem=0;
uint8 i;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();
tem=tem>>1;
DQ=0;
nops();
DQ=1;
nops();
if(DQ)
tem|=0x80;
delay_us(6);
write_byte(0x44); //发转换命令
}
/****************************
*读温度*
*****************************/
uint16 read_temp(void)
{
uint8 temp_data[2];
uint16 temp;
DS18B20_reset();
{
uint8 i;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();
DQ=0;
nops();
DQ=byte & 0x01;
delay_us(6);//nops();
byte=byte>>1;
}
DQ=1;
delay_us(1);
}
/**********************
对DS18B20读1字节
ans=read_temp();
a=ans/10%10;
b=ans%10;
refresh_led();
}
{
DQ = 1;
delay_us(1);
DQ = 0;

数字温度传感器DS18B20(含程序)

数字温度传感器DS18B20(含程序)

数字温度传感器DS18B20摘要DS-18B20 数字温度传感器具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

应用范围广泛,适用于冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温和控制领域,轴瓦,缸体,纺机,空调,等狭小空间工业设备测温和控制和汽车空调、冰箱、冷柜、以及中低温干燥箱等。

一、引脚图DS18B20引脚定义:(1)DQ为数字信号输入/输出端;(2)GND为电源地;(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)二、DS18B20的主要特性1.1、电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电1.2、DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯1.3、多个DS18B20可以并联在唯一的三线上,实现组网多点测温1.4、DS18B20在使用中不需要任何外围元件1.5、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃1.6、可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温1.7、在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快1.8、测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力1.9、负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。

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

DS18B20内部结构图四、DS18B20工作原理DS18B20的温度转换时的延时时间由2s 减为750ms。

DS18B20测温原理如图3所示。

18B20详细介绍及程序

18B20详细介绍及程序

1.DS18B20基本知识DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。

1、DS18B20产品的特点(1)、只要求一个端口即可实现通信。

(2)、在DS18B20中的每个器件上都有独一无二的序列号。

(3)、实际应用中不需要外部任何元器件即可实现测温。

(4)、测量温度范围在-55。

C到+125。

C之间。

(5)、数字温度计的分辨率用户可以从9位到12位选择。

(6)、内部有温度上、下限告警设置。

2、DS18B20的引脚介绍TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。

(底视图)图1表1DS18B20详细引脚功能描述3.DS18B20的使用方法由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。

DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。

该协议定义了几种信号的时序:初始化时序、读时序、写时序。

所有时序都是将主机作为主设备,单总线器件作为从设备。

而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。

数据和命令的传输都是低位在先。

DS18B20的复位时序DS18B20的读时序对于DS18B20的读时序分为读0时序和读1时序两个过程。

对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。

DS18B20在完成一个读时序过程,至少需要60us才能完成。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

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

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

现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性,适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。

DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C,分辨率设定,以及用户设定的报警温度存储在EEPROM中,掉电后依然保存。

DS1822与DS18B20软件兼容,是DS18B20的简化版本。

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

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

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

1、 DS18B20性能特点DS18B20的性能特点:①采用单总线专用技术,既可通过串行口线,也可通过其它I/O口线与微机接口,无须经过其它变换电路,直接输出被测温度值(9位二进制数,含符号位),②测温范围为-55℃-+125℃,测量分辨率为0.0625℃,③内含64位经过激光修正的只读存储器ROM,④适配各种单片机或系统机,⑤用户可分别设定各路温度的上、下限,⑥内含寄生电源。

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

DS18B20的管脚排列如图1所示。

64位光刻ROM是出厂前被光刻好的,它可以看作是该DS18B20的地址序列号,不同的器件地址序列号不同。

8位产品系列号48位产品序号8位CRC编码DS18B20高速暂存器共9个存储单元,如表所示:序号寄存器名称作用序号寄存器名称作用0 温度低字节以16位补码形式存放4、5 保留字节1、21 温度高字节 6 计数器余值2 TH/用户字节1 存放温度上限7 计数器/℃3 HL/用户字节2 存放温度下限8 CRC CRC校验图1 DS18B20引脚分布图以12位转化为例说明温度高低字节存放形式及计算:12位转化后得到的12位数据,存储在18B20的两个高低两个8位的RAM中,二进制中的前面5位是符号位。

如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度(等价说明:高8位字节的低3位和低8位字节的高4位组成温度整数值的二进制数;或者说:12位测量时,所测数值乘以0.0625(=1/16),即右移4位后去掉了二进制数的小数部分);如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625才能得到实际温度(等价说明:当温度小于0时,整数部分就是各位取反,小数部分则是各位取反后加1)。

9位测量分辨率0.5℃;10位测量分辨率0.25℃;11位测量分辨率0.125℃;12位测量分辨率0.0625℃;9~12位的测量,无论采用哪种分辨率,温度整数的有效位均是表中26~20;1、DS18B20控制方法在硬件上,DS18B20与单片机的连接有两种方法,一种是VCC接外部电源,GND接地,I/O与单片机的I/O线相连;另一种是用寄生电源供电,此时U DD、GND接地,I/O接单片机I/O。

无论是内部寄生电源还是外部供电,I/O口线要接5kΩ左右的上拉电阻。

DS18B20有六条控制命令,如下表所示:CPU对DS18B20的访问流程是:先对DS18B20初始化,再进行ROM操作命令,最后才能对存储器操作,数据操作。

DS18B20每一步操作都要遵循严格的工作时序和通信协议。

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

Initialization procedure “reset and presence pulses ”开始 发一个DS18B20序列号执行期间匹配命令 延时1s 启动在线DS18B20温度AD 转换 发跳过ROM 命令、发转换命令初始化DS18B20读在线DS18B20序号发出搜索ROM 命令DS18B20复位 所有在线DS18B20访问完? 存在一个DS18B20?初始化DS18B20 发读暂存RAM 指令 读匹配的DS18B20温度YYNN多点温度检测软件流程图YN读DS18B20温度的流程图DS18B20是否存在?(读DS18B20测量温度子程序)GET-TEMPA TURE 开始YN数据端置位 读温度值返回复位DS18B20(调用RESETDS18B20)写温度转换命令44H (调用WRITE18B20)写跳过ROM 匹配命令0CCH (调用WRITE18B20) 延时750μs ?(读温度前)复位DS18B20 (调用RESETDS18B20) 写跳过POM 匹配命令0CCH(调用WRITE18B20) 写读温度字节命令0BEH(调用WRITE18B20)读温度(调用READ18B20)NOPCLR P2.2;主机发出延时537微秒的复位低脉冲MOV R1, #3TSR1: MOV R0, #107DJNZ R0, $DJNZ R1, TSR1SETB P2.2 ;然后拉高数据线NOPNOPNOPMOV R0, #25HTSR2: JNB P2.2, TSR3 ;等待DS18B20DJNZ R0, TSR2LJMP TSR4 ; 延时TSR3: SETB FLAG1 ; 置标志位,表示CLR P1.7 ; 检查到DS18B20就点亮P1.7LEDLJMP TSR5TSR4: CLR FLAG1 ; 清标志位,表示DS1820不存在CLR P1.1LJMP TSR7TSR5: MOV R0, #117TSR6: DJNZ R0, TSR6 ; 时序要求延时一段时间TSR7: SETB P2.2RET循环右移一次 写DS18B20(子程序)开始进位标志位清零延时30μs数据端清零指令字节写完?YN进位标志位值送数据端延时(15μs)数据端置位(拉高数据线)DS18B20写返回 写DS18B20指令字节的流程图存低位字节数据一个字节是否读完?布尔累加器C 清零YN读DS18B20两个温度字节的流程图是低位字节数据?(读DS18B20的温度字节子程序)READ18B20开始 读数据端(数据) 数据端清零 YN延时(10μs) 数据端置位 DS18B20读返回延时(2μs) 数据端置位 延时(3μs) 延时(25μs)保存所读一位数据存高位字节数据C51程序#include <AT89X52.H>#include <INTRINS.h>unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f};unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};unsigned char code dotcode[32]={0,3,6,9,12,16,19,22, 25,28,31,34,38,41,44,48, 50,53,56,59,63,66,69,72,75,78,81,84,88,91,94,97};unsigned char displaycount;unsigned char displaybuf[8]={16,16,16,16,16,16,16,16};unsigned char timecount;unsigned char readdata[8];sbit DQ=P3^7;bit sflag;bit resetpulse( void){unsigned char i ;DQ=0;for(i=255;i>0;i--) ;DQ=1;for(i=60;i>0;i--);return(DQ);for(i=200;i>0;i--);}Void write command to ds18b20 (unsigned char command){unsigned char i;unsigned char j;for(i=0;i<8;i++) {if((command & 0x01)==0){ DQ=0;for(j=35;j>0;j--);DQ=1; }Else{ DQ=0;for(j=2;j>0;j--);DQ=1;for(j=33;j>0;j--); }command=_cror_(command,1); }}unsigned char readdatafromds18b20(void){ unsigned char i;unsigned char j;unsigned char temp;temp=0;for(i=0;i<8;i++){ temp=_cror_(temp,1);DQ=0;_nop_();_nop_();DQ=1;for(j=10;j>0;j--);if(DQ==1){ temp=temp | 0x80; }else{ temp=temp | 0x00; }for(j=200;j>0;j--);}return(temp);}void main(void){ TMOD=0x01;TH0=(65536-4000)/256;TL0=(65536-4000)%256;ET0=1;EA=1;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);TR0=1;while(1) { ; }}void t0(void) interrupt 1 using 0{ unsigned char x;unsigned int result;TH0=(65536-4000)/256;TL0=(65536-4000)%256;if(displaycount==2){ P0=displaycode[displaybuf[displaycount]] | 0x80; } else{ P0=displaycode[displaybuf[displaycount]]; } P2=displaybit[displaycount];displaycount++;if(displaycount==8){ displaycount=0; }timecount++;if(timecount==150){ timecount=0;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0xbe);readdata[0]=readdatafromds18b20();readdata[1]=readdatafromds18b20();for(x=0;x<8;x++){ displaybuf[x]=16; }sflag=0;if((readdata[1] & 0xf8)!=0x00){ sflag=1;readdata[1]=~readdata[1];readdata[0]=~readdata[0];result=readdata[0]+1;readdata[0]=result;if(result>255){ readdata[1]++; } } readdata[1]=readdata[1]<<4;readdata[1]=readdata[1] & 0x70;x=readdata[0];x=x>>4;x=x & 0x0f;readdata[1]=readdata[1] | x;x=2;result=readdata[1];while(result/10){ displaybuf[x]=result%10;result=result/10;x++; }displaybuf[x]=result;if(sflag==1){ displaybuf[x+1]=17; }x=readdata[0] & 0x0f;x=x<<1;displaybuf[0]=(dotcode[x])%10;displaybuf[1]=(dotcode[x])/10;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);}};这是关于DS18B20的读写程序,数据脚P2.2,晶振11.0592MHz;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒;可以将检测到的温度直接显示到AT89C51的两个数码管上;显示温度00到99度,很准确无需校正!ORG 0000H;单片机内存分配申明!TEMPER_L EQU 29H ;用于保存读出温度的低8位TEMPER_H EQU 28H ;用于保存读出温度的高8位FLAG1 EQU 38H ;是否检测到DS18B20标志位a_bit equ 20h ;数码管个位数存放内存位置b_bit equ 21h ;数码管十位数存放内存位置MAIN: LCALL GET_TEMPER ;调用读温度子程序;进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度;显示范围00到99度,显示精度为1度;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度;这个转化温度的方法可是我想出来的哦~~非常简洁无需乘于0.0625系数MOV A,29HMOV C,40H ;将28H中的最低位移入CRRC AMOV C,41HRRC AMOV C,42HRRC AMOV C,43HRRC AMOV 29H,ALCALL DISPLAY ;调用数码管显示子程序CPL P1.0AJMP MAIN; 这是DS18B20复位初始化子程序INIT_1820: SETB P2.2 ; 数据脚NOPCLR P2.2 ;主机发出延时537微秒的复位低脉冲MOV R1, #3TSR1: MOV R0, #107DJNZ R0, $DJNZ R1, TSR1SETB P2.2 ;然后拉高数据线NOPNOPNOPMOV R0, #25HTSR2: JNB P2.2, TSR3 ;等待DS18B20回应DJNZ R0, TSR2LJMP TSR4 ; 延时TSR3: SETB FLAG1 ; 置标志位,表示DS1820存在CLR P1.7 ; 检查到DS18B20就点亮P1.7LEDLJMP TSR5TSR4: CLR FLAG1 ; 清标志位,表示DS1820不存在CLR P1.1LJMP TSR7TSR5: MOV R0, #117TSR6: DJNZ R0, TSR6 ; 时序要求延时一段时间TSR7: SETB P2.2RET; 读出转换后的温度值GET_TEMPER: SETB P2.2LCALL INIT_1820 ;先复位DS18B20JB FLAG1, TSS2CLR P1.2RET ; 判断DS1820是否存在?若DS18B20不存在则返回TSS2: CLR P1.3 ;DS18B20已经被检测到!!!!!!!!!!!!!!!!!!MOV A, #0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A, #44H ; 发出温度转换命令LCALL WRITE_1820;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒LCALL DISPLAYLCALL INIT_1820 ;准备读温度前先复位MOV A, #0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A, #0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200; 将读出的温度数据保存到35H/36HCLR P1.4RET;写DS18B20的子程序(有具体的时序要求)WRITE_1820: MOV R2, #8 ;一共8位数据CLR CWR1: CLR P2.2MOV R3, #5DJNZ R3, $RRC AMOV P2.2, CMOV R3, #21DJNZ R3, $SETB P2.2NOPDJNZ R2, WR1SETB P2.2RET; 读DS18B20的程序, 从DS18B20中读出两个字节的温度数据READ_18200: MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00: MOV R2,#8 ; 数据一共有8位RE01: CLR CSETB P2.2NOPNOPCLR P2.2NOPNOPNOPSETB P2.2MOV R3,#8RE10: DJNZ R3,RE10MOV C,P2.2MOV R3,#21RE20: DJNZ R3,RE20RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;显示子程序display: MOV A,29H ;将29H中的十六进制数转换成10进制MOV B,#10 ;10进制/10=10进制DIV A BMOV b_bit ,A ;十位在aMOV a_bit ,B ;个位在bMOV DPTR, #numtab ;指定查表启始地址MOV R0,#4dpl1: MOV R1,#250 ;显示1000次dplop:MOV A, a_bit ;取个位数MOVC A,@A+DPTR ;查个位数的7段代码MOV P0,A ;送出个位的7段代码CLR P2.7 ;开个位显示ACALL d1ms ;显示1msSETB P2.7MOV A, b_bit ;取十位数MOVC A,@A+DPTR ;查十位数的7段代码MOV P0,A ;送出十位的7段代码CLR P2.6 ;开十位显示ACALL d1ms ;显示1msSETB P2.6DJNZ R1,dplop ;100次没完循环DJNZ R0,dpl1 ; 4个100次没完循环RET;1MS延时d1ms: MOV R7,#80DJNZ R7,$RET;实验板上的7段数码管0~9数字的共阴显示代码numtab: DB 0CFH,03H,5DH,5BH,93H,0DAH,0DEH,43H,0DFH,0DBH END#include "reg51.h"#include "INTRINS.H"#include "LCD.h"#define CLR_RI (RI=0)#define CLR_TI (TI=0)unsigned char code ID[2][8]={ 0x28,0x1D,0x25,0x1D,0x00,0x00,0x00,0x80,0x28,0x0e,0x9e,0x1c,0x00,0x00,0x00,0x32};unsigned char currSensorNo=0;sbit TMDAT = P1^7;sbit RUN_LED = P1^6;/*------------------------------------------------------------------------------------------------*/void serial_initial(){TMOD=0X20;SCON=0X50;PCON=0X00;TL1=TH1=0XE8;TR1=1;}/*------------------------------------------------------------------------------------------------*/void send(unsigned char count,unsigned char SEND_Buf[]){ unsigned char i;for(i=0;i<count;i++){ SBUF=SEND_Buf[i];while(!TI);CLR_TI; }}/*--------------------------------- delay N ms---------------------------------------------------*/void Delay_ms (unsigned int Nms ){ unsigned char i;while(Nms--)for(i=0; i<125; i++) ;}/*----------------------------------------- delay N count----------------------------------------------*/void Delay_Count (unsigned char Count ){ while(Count>0) Count--; }/*---------------------------------------------- start Reset Pulse----------------------------------------------*/void tmreset(void){ TMDAT=0;Delay_Count(103);TMDAT=1;Delay_Count(4);}/*---------------------------------------- ACK--------------------------------------------------*/void tmpre(void){ while(TMDAT);while(~TMDAT);Delay_Count(4);}/*------------------------------------Read a bit from 1820---------------------------------------------*/bit tmrbit(void){ int i=0;bit dat;TMDAT=0;i++;TMDAT=1;i++;i++;dat = TMDAT;Delay_Count(8);return dat;}/*-------------------------------- Read a byte from 1820-----------------------------------------------*/unsigned char tmrbyte(void){ unsigned char i,j,dat=0;for(i=1;i<=8;i++){ j=tmrbit();dat=(j<<7)|(dat>>1); }return dat;}/*-------------------------------- Read a byte from 1820------------------------------------------------*/void tmwbyte(unsigned char dat){ signed char i=0;unsigned char j;bit testb;for(j=1;j<=8;j++){ testb=dat & 0x01;dat = dat>>1;if(testb){ TMDAT=0;i++;i++;TMDAT=1;Delay_Count(8); }else{ TMDAT=0;Delay_Count(8);TMDAT=1;i++;i++; }}}/*------------------------------------- send convert command to 1820----------------------------------------------*/void tmstart(void){ unsigned char i;tmreset();tmpre();Delay_ms(1);/* tmwbyte(0xcc);*/tmwbyte(0x55);for(i=0;i<8;i++)tmwbyte(ID[currSensorNo][i]);tmwbyte(0x44);}/*------------------------------------- Read tempreature from 1820--------------------------------------*/unsigned int tmrtemp_all(void){ unsigned char a,b;unsigned int y3;unsigned char i;tmreset();tmpre();Delay_ms(1);/*tmwbyte(0xcc);*/tmwbyte(0x55);for(i=0;i<8;i++)tmwbyte(ID[currSensorNo][i]);tmwbyte(0xbe);a = tmrbyte();b = tmrbyte();y3 = ((unsigned int)b) << 8;return ((y3+a) & 0x7ff) ;}/*---------------------------------Start Test tempreature, All--------------------------------------------*/void Display_AllTemp(void ){unsigned int last;unsigned char i,Dot;RUN_LED=0;Part=0;LED_DISPLAY();Delay_ms(1);tmstart();Delay_ms(800);last=tmrtemp_all();RUN_LED=1;Dot= (last & 0x0f)*6.25 ;Digit[0]= Dot%10;Digit[1]=Dot/10;last=(last>>4) & 0x7f ;if( (last == 0x7f) ) // erro{ for(i=0;i<5;i++) Digit[i]=16; }else{ for(i=2;i<5;i++){ Digit[i] = last %10;last = last/10; }if(Digit[4]==0)Digit[4]=17;Part=1;}Digit[5]=currSensorNo;LED_DISPLAY();}/*------------------------------------------------------------------------------------*//* void Read_Id(){ unsigned char i,id[8];tmreset();tmpre();Delay_ms(1);tmwbyte(0x33);for(i=0;i<8;i++)id[i]=tmrbyte();send(8,id);} *//*---------------------------------------- Main------------------------------------------------*/void main(void){ unsigned char id[8]={1,2,3,4,5,6,7,8};serial_initial();send(8,id);for(;;){ RUN_LED=!R UN_LED;/* Read_Id();*/TX_C =!TX_C ;currSensorNo=(currSensorNo==1)?0:1;Display_AllTemp();/*Change();*/send(6,Digit);Delay_ms(1000);_nop_();}}。

相关文档
最新文档