ds18b20的子程序
- 格式:doc
- 大小:40.00 KB
- 文档页数:5
DS18B20各程序功能(急求!)2009-09-29 10:46 ke1783|分类:其他编程语言|浏览2045次我想知道,常规情况下,DS18B20各程序段的功能(1)主程序(2)显示子程序(3)中断子程序(4)延时子程序(5)DS18B20初始化子程序(6)读/写一个字节子程序(7)读出温度子程序(8)键盘扫描子程序keyscan在线等。
解释最好详细一点,好的再加50分。
扫描二维码下载下载知道APP10分钟有问必答!建议:可使用微信的“扫一扫”功能扫描下载分享到:2009-09-30 12:42 提问者采纳(1)主程序:程序的执行从主程序开始,首先调用初始化子程序,用于对中断配置等必要的初始赋值,然后进入主循环,不断重复的执行或调用主循环中的程序,实现数码管的动态扫描、按键的识别和键值处理、温度转换等功能。
(2)显示子程序:显示若用数码管,要显示完整的温度值,一般会选用4位一体数码管,在显示子程序中,对数码管的段、位以动态扫描的方式根据当前需要显示的内容不断对其进行更新和配置,利用人眼的惰性效应达到动态显示的目的。
(3)中断子程序:一般温度不需要实时测量,因为温度是不会突变的,没有必要实时,另一方面实时太占用系统资源,所以可以隔一段时间测量一次,用定时器中断来定时使能测温标志,供温度转换程序在主程序中查询。
(4)延时子程序:单总线时序是建立在延时操做基础上的。
(5)DS18B20初始化子程序:相当于给18B20数据头的作用,18B20检测到初使化电平,准备开始接收或发送数据,另一方面,可根据DS18B20是否作出应答来检测它是否在总线上。
(6)读/写一个字节子程序:在单总线上按照标准单总线的读/写时序,产生一个读/写单字节数据的操作事件,什么时候读/写,读/写些什么,由18B20这个单总线器件内部的数据协议和数据结构来决定(单总线的器件有很多种,操作协议和数据结构不尽相同,但读写时序都是一样的)。
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、配置寄存器。
ORG 0000HAJMP MAINORG 0030HMAIN: MOV R5,#0FFHMAIN1:MOV P0,#00H ;系统自检。
自高位向低位带小数点显示8扫描256次CLR P2.4LCALL DELAYSETB P2.4CLR P2.5LCALL DELAYSETB P2.5CLR P2.6LCALL DELAYSETB P2.6CLR P2.7LCALL DELAYSETB P2.7DJNZ R5,MAIN1SETB P2.4 ;关显示SETB P2.5SETB P2.6SETB P2.7SJMP MAIN2DELAY:MOV R7 ,#05H //;延时LP8: MOV R6,#19HLP7:DJNZ R6,LP7DJNZ R7,LP8RET; DS18B20初始化汇编程序;*****************************************//MAIN2:LCALL DISP //;主程序SETB P3.2 // ;18B20DQ置1拉高LCALL INIT // ;调初始化MOV A,#0CCH //;跳过ROM匹配------0CCLCALL WRITE // ;调写DS18B20的程序MOV A,#44H // ;发出温度转换命令LCALL WRITE // ;调写DS18B20的程序MOV R6,#34H //;延时136微秒转换时间,写一个字约需70微秒。
DJNZ R6,$LCALL DISPLCALL INITMOV A,#0CCHLCALL WRITEMOV A,#0BEH // ;发出读温度命令LCALL WRITELCALL READCLR CLCALL CONVTEMPLCALL DISPBCDLCALL DISPSJMP MAIN2WRITE:MOV R0,#8 // ;写子程序CLR CWR1: CLR P3.2MOV 20H,#3 // ;延时17微秒DJNZ 20H,$RRC AMOV P3.2,CMOV 21H,#10 // ;发送后延时45微秒DJNZ 21H,$SETB P3.2NOPDJNZ R0,WR1 // ;8位未发送完转SETB P3.2RETREAD: MOV R6,#2 // ;读子程序CLR PSW.5 // ;清清标志F0RE0:MOV R2,#8RE1:CLR CSETB P3.2 // ;拉高DQNOP // ;延时2微秒CLR P3.2 // ;拉低DQSETB P3.2MOV 22H,#3RE2:DJNZ 22H,RE2MOV C,P3.2MOV 23H,#10RE3:DJNZ 23H,RE3RRC ADJNZ R2,RE1 //;8位未读完继续读CPL PSW.5JNB PSW.5,RE4 // ;高8位保存至28HMOV 29H,A // ;低8位及小数保存至29HRE4:MOV 28H,ADJNZ R6,RE0 //;高8位未读继续RETINIT:SETB P3.2 // ;初始化开始DQ置1(整个时隙和理论值不是很准确)NOP //;延时L0:CLR P3.2 // ;DQ拉低MOV 24H,#100 // ;延时400微秒DJNZ 24H,$SETB P3.2 // ;DQ拉高MOV 25H,#10 // ;置40微秒延时常数L01:JNB P3.2,L2 // ;有18B20响应转L2DJNZ 25H,L01 // ;无18B20响应等待40微秒SJMP L0 // ;无18B20重新初始化L2:MOV R7,#60 // ,延时240微秒L3:DJNZ R7,L3SETB P3.2 //;DQ拉高、退出RETCONVTEMP:MOV A,28H //;温度转换ANL A,#80H //;温度正负判别JZ TEMPC1 //;温度为正转CLR C // ;温度为负调整MOV A,29HCPL AADD A,#01HMOV 29H,AMOV A,28HCPL AADDC A,#00HMOV 28H,AMOV 26H,#0BH // ;温度为负26H内送#0BHSJMP TEMPC11TEMPC1:MOV 26H,#0AH //;温度为正26H内送#0AHTEMPC11:MOV A,26HSWAP AMOV 26H,A // ;26H高4位为温度符号MOV A,29H // ;取温度小数部分ANL A,#0FH ;去整数个位MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV 27H,A // ;查表得小数值,并保存至27H单元MOV A,29H // ;温度整数部分拼装后暂时存入AANL A,#0F0H // ;留下整数个位SWAP AMOV 29H,AMOV A,28HANL A,#0FHSWAP AHEX2BCD1:MOV B,#64H // ;温度整数部分除100得整数百位,并存入R7中DIV ABMOV R7,A // ;R7中为百位,B中为十位和个位MOV A,#0AH // ;温度整数部分除10得整数十位和个位XCH A,B // ;除数与被除数交换DIV ABSWAP AORL A,BTEMPC10:MOV 29H,A // ;温度十位和个位存入29H单元中,十位在高4位,个位在低4位ANL A,#0F0H // ;取温度十位SWAP AORL A,26H //;十位加温度符号存入26H单元;高4位为符号MOV 26H,AMOV A,29HANL A,#0FH // ;取温度个位SWAP AORL A,27HMOV 27H,A // ;27H单元中高4位为个位,低4位为小数MOV A,R7JZ TEMPC12 // ;百位为0退出ANL A,#0FH // ;百位不为0即温度为正和十位重新拼装后存入26H,高4位为百位SWAP A // ;MOV R7,AMOV A,26HANL A,#0FH ; // ;去除26H单元的符号ORL A,R7 //;百位和十位拼装,放入26H单元高4位为百位MOV 26H,A // ;低4位为十位TEMPC12:RETDOTTAB:DB 00H,01H,01H,02H,03HDB 03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09HDISPBCD:MOV A,27H // ;BCD码转换ANL A,#0FHMOV 70H,A // ;取小数,并保存在70H中SWAP AANL A,#0FHMOV 71H,A // ;取整数个位,并保存在71H中MOV A,26HANL A,#0FHMOV 72H,A //;取整数十位,并保存在72H中MOV A,26HSWAP AANL A,#0FHMOV 73H,A // ;取整数百位,并保存在73H中MOV A,72H //;取整数十位ANL A,#0F0HCJNE A,#00H,DISPBCD2SJMP DISPBCD2DISPBCD0:MOV A,26H // ;取整数百位ANL A,#0F0HCJNE A,#00H,DISPBCD2 //;百位不等于0退出MOV A,26HSW AP AANL A,#0FH //;十位保留符号MOV 73H,#0AHMOV 72H,ADISPBCD2:RETDISP:MOV R1,#70H // ;显示子程序MOV R5,#11101111B // ;送Y4位码PLAY:MOV P0,#0FFH // ;关段码MOV A,R5 // ;取Yn位码MOV P2,A // ;送位码MOV A,@R1 //;取段码MOV DPTR,#TABMOVC A,@A+DPTRMOV P0,A // ;送段码MOV A,R5JB ACC.5,LOOP1 // ;位码未指向Y2(整数个位)转CLR P0.7 ;;开小数点LOOP1:LCALL DL1MS //;调显示延时INC R1 // ;指向下一位显示段码MOV A,R5 ;取显示位码JNB ACC.7,ENDOUTRL A // ;向下一位位码MOV R5,AAJMP PLAYENDOUT:MOV P0,#0FFHMOV P3,#0FFHRETTAB: DB 0C0H,0F9H,0A4H,0B0HDB 99H,92H,82H,0F8HDB 80H,90H,0FFH,0BFHDL1MS:MOV R6,#14H // ;延时1mS DL1: MOV R7,#19HDL2: DJNZ R7,DL2DJNZ R6,DL1RETEND。
ds18b20的C语言完整程序(c51)(可组网数字式温度传感器)发布日期:[2005-05-10]作者:(sparkstar)//DS1820 C51 子程序//这里以11.0592M晶体为例,不同的晶体速度可能需要调整延时的时间//sbit DQ =P2^1;//根据实际情况定义端口typedef unsigned char byte;typedef unsigned int word;//延时void delay(word useconds){for(;useconds>0;useconds--);}//复位byte ow_reset(void){byte presence;DQ = 0; //pull DQ line lowdelay(29); // leave it low for 480usDQ = 1; // allow line to return highdelay(3); // wait for presencepresence = DQ; // get presence signaldelay(25); // wait for end of timeslotreturn(presence); // presence signal returned} // 0=presence, 1 = no part//从 1-wire 总线上读取一个字节byte read_byte(void){byte i;byte value = 0;for (i=8;i>0;i--){value>>=1;DQ = 0; // pull DQ low to start timeslotDQ = 1; // then return highdelay(1); //for (i=0; i<3; i++);if(DQ)value|=0x80;delay(6); // wait for rest of timeslot}return(value);}//向 1-WIRE 总线上写一个字节void write_byte(char val){byte i;for (i=8; i>0; i--) // writes byte, one bit at a time {DQ = 0; // pull DQ low to start timeslotDQ = val&0x01;delay(5); // hold value for remainder of timeslotDQ = 1;val=val/2;}delay(5);}//读取温度char Read_Temperature(void){union{byte c[2];int x;}temp;ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0xBE); // Read Scratch Padtemp.c[1]=read_byte();temp.c[0]=read_byte();ow_reset();write_byte(0xCC); //Skip ROMwrite_byte(0x44); // Start Conversionreturn temp.x/2;}。
ds18b20程序设计傻瓜式讲解
DS18B20 是一款数字温度传感器,可以直接读出被测温度,并采用 9 位数字量串行输出。
下面是一个简单的 DS18B20 程序设计讲解:
1. 初始化
在 DS18B20 通信过程中,首先需要初始化数据线,即将其置为高电平。
在初始化时,需要持续至少 480 微秒的高电平。
2. 跳过 ROM
在 DS18B20 中,每个传感器都有一个唯一的 ROM 序列号,可以通过跳过ROM 操作来避免对 ROM 进行操作。
具体操作是先发出一个低电平,然后持续至少 60 微秒的高电平。
3. 发送命令
在跳过 ROM 后,需要向传感器发送命令。
常用的命令有温度转换命令和读取温度命令。
温度转换命令是 0x44,读取温度命令是 0xBE。
4. 读取数据
在发送命令后,需要等待传感器响应。
传感器响应的标志是数据线上的低电平。
在低电平持续约 60-240 微秒后,数据线将变为高电平,此时可以开始读取数据。
每次读取一位数据后,需要将数据线置为低电平,等待传感器响应。
5. 数据解析
DS18B20 的数据由 9 位数字量组成,其中最高位是符号位。
如果最高位为0,则表示温度为正数;如果最高位为 1,则表示温度为负数。
其余 8 位为温度值,可以通过一定的计算公式将其转换为实际温度值。
以上就是 DS18B20 的程序设计流程。
需要注意的是,在实际应用中,还需要考虑数据传输的校验、错误处理等问题。
水温控制系统摘要:该水温控制系统采用单片机进行温度实时采集与控制。
温度信号由“一线总线”数字化温度传感器DS18B20提供,DS18B20在-10~+85°C范围内,固有测温分辨率为0.5 ℃。
水温实时控制采用继电器控制电热丝和风扇进行升温、降温控制.系统具备较高的测量精度和控制精度,能完成升温和降温控制。
关键字:AT89C51 DS18B20 水温控制Abstract: This water temperature control system uses the Single Chip Microcomputer to carry on temperature real-time gathering and controling。
DS18B20,digitized temperature sensor, provides the temperature signal by "a main line”. In -10~+85℃the scope,DS18B20’s inherent measuring accuracy is 0.5 ℃. The water temperature real-time control system uses the electricity nichrome wire carring on temperature increiseament and operates the electric fan to realize the temperature decrease control。
The system has the higher measuring accuracy and the control precision,it also can complete the elevation of temperature and the temperature decrease control. Key Words:AT89C51 DS18B20 Water temperature control目录1.系统方案选择和论证 (2)1。
DS18B20汇编程序(完整版)DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSC CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
基于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单线数字温度传感器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,④适配各种单片机或系统机,⑤用户可分别设定各路温度的上、下限,⑥内含寄生电源。
主程序流程图:
DS18B20程序流程图:
程序按数据手册的时序图编写子函数模块:
1、DS18B20复位函数:resetDS18B20(void)
2、写一位的函数:WriteBit (unsigned char wb)
3、读一位的函数:unsigned char ReadBit (void)
4、读一个字节的函数:unsigned char readByteDS18B20(void)
即将位读取的时序循环8次。
5、写一个字节的函数:void writeByteDS18B20(unsigned char Data)。
即将位写入的时序循环8次。
6、first和next函数流程图:
1、端口初始化子函数;
2、串口初始化;
3、串口发送一个字符函数:void USART_Putchar(unsigned char
send_char)
4、串口发送数组函数:void UsartTransmit(unsigned char *data,
unsigned char len)
5、串口发送字符串函数:void USART1_Putstr(char *s)
即通过字符串长度控制USART_Putchar函数的循环次数。
6、串口发送字符串子程序(带有换行符):
void USART1_Puts(char *s)
7、串口接收字符串函数:unsigned char getchar1(void)
8、串口接收中断子程序:void USART_RXT(void)流程图
1、 数据打包子函数:void Packet_Data(void)
2、。
数字温度传感器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所示。
/*******************************************DS18B20子程序********************************************/#include<reg52.h>#include<intrins.h>#include<absacc.h>sbit DS18B20=P3^5;unsigned char n;void Delay15(n){ //延时参数do{_nop_ ();_nop_ ();_nop_ ();n--;}while(n);}// 功能: 初始化DS18B20,读存在脉冲,无存在脉冲则置位错误标志// 输入: 无// 返回: 无void RST18B20(void){DS18B20=0; //复位脉冲Delay15(36); // 延时540 μsDS18B20=1; //恢复Delay15(6); // 延时90usError_DS18B20=DS18B20; //读存在脉冲Delay15(18); // 延时270 μ}// 功能:写DS18B20//输入:待写字节// 返回:无voidWR18B20(d)unsigned char d; //待写的1 字节数据{ unsigned char i; //循环变量ACC=d;for(i=8;i>0;i--){DS18B20=0; //起始Delay15(1); //延时ACC=ACC>>1; // 将第i 位待发数据送入CYDS18B20=CY; //送出数据Delay15(1); //延时DS18B20=1; //停止}}// 功能: 读DS18B20// 输入: 无// 返回: 读出的1 字节数据unsigned char RD18B20(void){unsigned char i; //循环变量ACC=0; // 清ACCfor(i=8;i>0;i--) {ACC=ACC>>1; //右移位DS18B20=0; //起始_nop_ (); //延时DS18B20=1; //恢复Delay15(1); //延时BIT7=DS18B20; //读第i 位}return(ACC); //返回1 字节数据}// 功能: 启动DS18B20 的1 次温度转换// 输入: 无// 返回: 无void ConvertT(void){RST18B20(); //初始化WR18B20(0xcc); //Skip R O M ,跳过多传感器识别WR18B20(0x44); //C onvert T ,启动温度转换}// 功能: 读取DS18B20 并返回温度值// 输入: 无// 返回: DPTR -温度值,2 字节int ReadT(void){RST18B20(); //初始化WR18B20(0xcc); //skip R O M ,跳过多传感器识别WR18B20(0xbe); //read scratchpad,读DS18B20暂存器}。
下面是DS18B20的子程序,#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar a;sbit DQ=P2^0;void reset(); //DS18B20复位函数void write_byte(uchar val); //DS18B20写命令函数uchar read_byte(void); //DS18B20读1字节函数void read_temp(); //温度读取函数void work_temp(); //温度数据处理函数uchar data temp_data[2]={0x00,0x00};uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //对于温度显示值值uchar codeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//温度小数部分查表main(){while(1){reset();write_byte(a);read_byte();read_temp();work_temp();}}void delay1(uint t) {for(;t>0;t--);}///////温度控制子函数void reset(){uchar presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_(); DQ=0; delay1(50);DQ=1;delay1(6);presence=DQ;}delay1(45);presence=~DQ;}DQ=1;}void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); DQ=val&0x01; delay1(6);val=val/2;}DQ=1;_nop_();}uchar read_byte(void){uchar i;uchar value=0;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_(); if(DQ)value|=0x80; delay1(6);}DQ=1;return(value);}void read_temp(){reset();write_byte(0xcc);write_byte(0xbe);temp_data[0]=read_byte();temp_data[1]=read_byte();reset();write_byte(0xcc);write_byte(0x44);}void work_temp(){if(temp_data[1]>127){temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);}display[4]=temp_data[0]&0x0f; //低位的低4位display[0]=ditab[display[4]]; //小数点后的数值display[4]=((temp_data[0]&0xf0) >>4)|((temp_data[1]&0x0f)<<4); //小数点前的数值display[3]=display[4] / 100;display[1]=display[4] % 100;display[2]=display[1] / 10;display[1]=display[1] % 10;}。
1.单DS18B20温度读取#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^4; //数据线端口void delayms(uint x) //延时函数{uchar j;while(x--){for(j=0;j<123;j++){;}}}//ROM操作命令#define READ_ROM 0x33 //读ROM#define SKIP_ROM 0xCC //跳过ROM#define MATCH_ROM 0x55 //匹配ROM#define SEARCH_ROM 0xF0 //搜索ROM#define ALARM_SEARCH 0xEC //告警搜索//存储器操作命令#define ANEW_MOVE 0xB8 //重新调出E^2数据#define READ_POWER 0xB4 //读电源#define TEMP_SWITCH 0x44 //启动温度变换#define READ_MEMORY 0xBE //读暂存存储器#define COPY_MEMORY 0x48 //复制暂存存储器#define WRITE_MEMORY 0x4E //写暂存存储器//数据存储结构typedef struct tagTempData{unsigned char btThird; //百位数据unsigned char btSecond; //十位数据unsigned char btFirst; //个位数据unsigned char btDecimal; //小数点后一位数据unsigned char btNegative; //是否为负数}TEMPDATA;void Delay16us() //延时16us子函数{unsigned char a;for (a = 0; a < 4; a++);}void Delay60us() //延时60us子函数{unsigned char a;for (a = 0; a < 18; a++);}void Delay480us() //延时480us子函数{unsigned char a;for (a = 0; a < 158; a++);}void Delay240us() //延时240us子函数{unsigned char a;for (a = 0; a < 78; a++);}void Initialization() //芯片初始化{while(1) //无限循环知道收到了存在脉冲(即DS18B20的应答脉冲){DQ = 0;Delay480us(); //延时480us 复位单总线至少480us的低电平信号DQ = 1;Delay60us(); //延时60us 在复位电平结束后将数据总线拉高,以便在15~60us后接收存在脉冲if(~DQ) //收到ds18b20的应答信号{DQ = 1;Delay240us(); //延时240us 存在脉冲为一个60~240us的低电平信号break;}}}void WriteByte(unsigned char btData) //写ROM(从低位开始写) {unsigned char i, btBuffer;for (i = 0; i < 8; i++){btBuffer = btData >> i; //最低位移出if (btBuffer & 1){DQ = 0;_nop_(); //延时1个机器周期_nop_();DQ = 1;Delay60us(); //延时60us}else{DQ = 0;Delay60us();DQ = 1;}}}unsigned char ReadByte() //读ROM(从低位开始读) {unsigned char i, btDest;for (i = 0; i < 8; i++){btDest >>= 1;DQ = 0;_nop_();_nop_();DQ = 1;Delay16us();if (DQ) btDest |= 0x80;Delay60us();}return btDest;}//读取温度值TEMPDATA ReadTemperature(){TEMPDATA TempData; //定义储存结构用于存储温度的值unsigned int iTempDataH;unsigned char btDot, iTempDataL;TempData.btNegative = 0; //为0温度为正Initialization();WriteByte(SKIP_ROM); //跳过ROM匹配WriteByte(TEMP_SWITCH); //启动温度转换delayms(1); //温度转换需要时间500usInitialization();WriteByte(SKIP_ROM); //跳过ROM匹配(单个芯片时用这句换掉上面的switch)WriteByte(READ_MEMORY); //读暂存储存数据iTempDataL = ReadByte(); //读取温度的低8位iTempDataH = ReadByte(); //读取温度的高8位iTempDataH <<= 8;iTempDataH |= iTempDataL;if (iTempDataH & 0x8000) //判断温度的值是否为负数{TempData.btNegative = 1; //负数标志iTempDataH = ~iTempDataH + 1; //负数求补}btDot = (unsigned char)(iTempDataH & 0x000F); //得到小数部分iTempDataH >>= 4; //得到整数部分btDot *= 5; //btDot*10/16得到转换后的小数数据btDot >>= 3;//数据处理TempData.btThird = (unsigned char)iTempDataH /100; //整数部分的百位TempData.btSecond = (unsigned char)iTempDataH % 100/10;//整数部分的十位TempData.btFirst = (unsigned char)iTempDataH % 10; //整数部分的个位TempData.btDecimal = btDot; //小数点后的一位return TempData; //函数返回温度值的存储结构体}2.多个DS18B20单总线温度读取#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P2^7; //数据线端口unsigned char channel,n=0;void delayms(uint x) //延时函数{uchar j;while(x--){for(j=0;j<123;j++){;}}}//ROM操作命令#define READ_ROM 0x33 //读ROM#define SKIP_ROM 0xCC //跳过ROM #define MATCH_ROM 0x55 //匹配ROM #define SEARCH_ROM 0xF0 //搜索ROM//存储器操作命令#define ANEW_MOVE 0xB8//重新调出E^2数据#define READ_POWER 0xB4 //读电源#define TEMP_SWITCH 0x44 //启动温度变换#define READ_MEMORY 0xBE //读暂存存储器#define COPY_MEMORY 0x48 //复制暂存存储器#define WRITE_MEMORY 0x4E //写暂存存储器//数据存储结构typedef struct tagTempData{unsigned char btThird; //百位数据unsigned char btSecond; //十位数据unsigned char btFirst; //个位数据unsigned char btDecimal; //小数点后一位数据unsigned char btNegative; //是否为负数}TEMPDATA;//DS18B20序列号const unsigned char code ROMData1[8] = {0x28, 0x33, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xD7}; //U1const unsigned char code ROMData2[8] = {0x28, 0x30, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x8E}; //U2const unsigned char code ROMData3[8] = {0x28, 0x31, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xB9}; //U3const unsigned char code ROMData4[8] = {0x28, 0x32, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xE0}; //U4const unsigned char code ROMData5[8] = {0x28, 0x34, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x52}; //U5const unsigned char code ROMData6[8] = {0x28, 0x35, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x65}; //U6const unsigned char code ROMData7[8] = {0x28, 0x36, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x3C}; //U7const unsigned char code ROMData8[8] = {0x28, 0x37, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x0B}; //U8void Delay16us() //延时16us子函数{unsigned char a;for (a = 0; a < 4; a++);}void Delay60us() //延时60us子函数{unsigned char a;for (a = 0; a < 18; a++);}void Delay480us() //延时480us子函数{unsigned char a;for (a = 0; a < 158; a++);}void Delay240us() //延时240us子函数{unsigned char a;for (a = 0; a < 78; a++);}void Initialization() //芯片初始化{while(1) //无限循环知道收到了存在脉冲(即DS18B20的应答脉冲){DQ = 0;Delay480us(); //延时480us 复位单总线至少480us的低电平信号DQ = 1;Delay60us(); //延时60us 在复位电平结束后将数据总线拉高,以便在15~60us后接收存在脉冲if(!DQ) //收到ds18b20的应答信号{DQ = 1;Delay240us(); //延时240us 存在脉冲为一个60~240us的低电平信号break;}}}void WriteByte(unsigned char btData) //写ROM(从低位开始写) {unsigned char i, btBuffer;for (i = 0; i < 8; i++){btBuffer = btData >> i; //最低位移出if (btBuffer & 1){_nop_(); //延时1个机器周期_nop_();DQ = 1;Delay60us(); //延时60us}else{DQ = 0;Delay60us();DQ = 1;}}}unsigned char ReadByte() //读ROM(从低位开始读) {unsigned char i, btDest;for (i = 0; i < 8; i++){DQ = 0;_nop_();_nop_();DQ = 1;Delay16us();if (DQ) btDest |= 0x80;Delay60us();}return btDest;}//序列号匹配void MatchROM(const unsigned char *pMatchData) {unsigned char i;Initialization(); //芯片初始化WriteByte(MATCH_ROM); //写入匹配ROM指令for (i = 0; i < 8; i++) WriteByte(*(pMatchData + i)); }//读取温度值TEMPDATA ReadTemperature(){TEMPDATA TempData; //定义储存结构用于存储温度的值unsigned int iTempDataH;unsigned char btDot, iTempDataL;static unsigned char i = 0;TempData.btNegative = 0; //为0温度为正i++;if (i == 9) i = 1;channel=i;Initialization();WriteByte(SKIP_ROM); //跳过ROM匹配WriteByte(TEMP_SWITCH); //启动温度转换if(n==0)delayms(1000); //温度转换需要时间500msn++;if(n==8)n=1;delayms(1);Initialization();//多个芯片的时候用MatchROM(ROMData)换掉WriteByte(SKIP_ROM)switch (i){case 1 : MatchROM(ROMData1); break; //匹配1case 2 : MatchROM(ROMData2); break; //匹配2case 3 : MatchROM(ROMData3); break; //匹配3case 4 : MatchROM(ROMData4); break; //匹配4case 5 : MatchROM(ROMData5); break; //匹配5case 6 : MatchROM(ROMData6); break; //匹配6case 7 : MatchROM(ROMData7); break; //匹配7case 8 : MatchROM(ROMData8); break; //匹配8 }//WriteByte(SKIP_ROM); //跳过ROM匹配(单个芯片时用这句换掉上面的switch)WriteByte(READ_MEMORY); //读暂存储存数据iTempDataL = ReadByte(); //读取温度的低8位iTempDataH = ReadByte(); //读取温度的高8位iTempDataH <<= 8;iTempDataH |= iTempDataL;if (iTempDataH & 0x8000) //判断温度的值是否为负数{TempData.btNegative = 1; //负数标志iTempDataH = ~iTempDataH + 1; //负数求补}btDot = (unsigned char)(iTempDataH & 0x000F); //得到小数部分iTempDataH >>= 4; //得到整数部分btDot *= 5; //btDot*10/16得到转换后的小数数据btDot >>= 3;//数据处理TempData.btThird = (unsigned char)iTempDataH / 100;//整数部分的百位TempData.btSecond = (unsigned char)iTempDataH % 100 / 10;//整数部分的十位TempData.btFirst = (unsigned char)iTempDataH % 10;//整数部分的个位TempData.btDecimal = btDot; //小数点后的一位return TempData; //函数返回温度值的存储结构体}3. DS18B20的序列号读取程序<用LCD1602显示序列号>#include<reg52.h>#include<LCD1602.h>#include<string.h>#define uchar unsigned char#define uint unsigned intuchar sn[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10};uchar t;uchart01,t02,t11,t12,t21,t22,t31,t32,t41,t42,t51,t52,t61,t62,t71,t72;sbit DQ=P2^7;//ds18b20与单片机连接口void delay1ms(unsigned int ms)// 延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void delay_18B20(unsigned int i)// 延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}////////////////////////读取器件序列号子程序////////////////////////////void rom(void){ds1820rst(); //复位//delay1ms(1); //延时//ds1820wr(0x33); //发送读序列号子程序//sn[0]=ds1820rd(); //连续读出64位ROM t01=sn[0]/16;t02=sn[0]%16; //转为16进制sn[1]=ds1820rd(); //t11=sn[1]/16;t12=sn[1]%16; //转为16进制sn[2]=ds1820rd(); //t21=sn[2]/16;t22=sn[2]%16; //转为16进制sn[3]=ds1820rd(); //t31=sn[3]/16;t32=sn[3]%16; //转为16进制sn[4]=ds1820rd(); //t41=sn[4]/16;t42=sn[4]%16; //转为16进制sn[5]=ds1820rd(); //t51=sn[5]/16;t52=sn[5]%16; //转为16进制sn[6]=ds1820rd(); //t61=sn[6]/16;t62=sn[6]%16; //转为16进制sn[7]=ds1820rd(); //t71=sn[7]/16;t72=sn[7]%16; //转为16进制}void chuan(uchar i,uchar j,uchar x) {if(x<10)DisplayOne(i,j,x,1);if(x==10)DisplayOne(i,j,'A',0);if(x==11)DisplayOne(i,j,'B',0);if(x==12)DisplayOne(i,j,'C',0);if(x==13)DisplayOne(i,j,'D',0);if(x==14)DisplayOne(i,j,'E',0);if(x==15)DisplayOne(i,j,'F',0);}void Displaychar(){chuan(0,0,t01);chuan(0,1,t02);chuan(0,4,t11);chuan(0,5,t12);chuan(0,8,t21);chuan(0,9,t22);chuan(0,12,t31);chuan(0,13,t32);chuan(1,0,t41);chuan(1,1,t42);chuan(1,4,t51);chuan(1,5,t52);chuan(1,8,t61);chuan(1,9,t62);chuan(1,12,t71);chuan(1,13,t72);}/********************主程序***********************************/void main(){Clear();Init();while(1){rom(); //调用读序列号子程序//Displaychar();}}。
DS18B20的编程应用举例几个重要子程序如下:; -------------DS18B20初始化程序;在只有一个DS18B20时适用;先复位脉冲(低电平)500US,释放总线(高电平);再等待100μs,;若有低电平,说明器件存在,置标志位FLAG1为1;否则置0INIT_1820:SETB DQNOPCLR DQ ;低电平,复位脉冲开始MOV R3,#07FH ;要求复位脉冲最少480最大960μsTSR1: DJNZ R3,TSR1 ;改后延时510μsSETB DQ ;高电平,复位脉冲结束,还要等待16~60μsMOV R3,#10H ;10H=64μs。
存在脉冲长60~240μsTSR2: DJNZ R3,TSR2 ;延时64μs,等待18B20发回来的存在脉冲--低电平 JNB DQ,TSR3 ;判断,有低电平表示18B20存在LJMP TSR4 ;没有低电平表示18B20不存在TSR3: SETB FLAG1 ;置标志位,表示DS1820存在LJMP TSR5TSR4: CLR FLAG1 ;清标志位,表示DS1820不存在LJMP TSR7TSR5: MOV R3,#032H ;200μsTSR6: DJNZ R3,TSR6 ;延时TSR7: SETB DQ ;数据线高电平RET;================================================================; -------------写DS18B20的程序;要写入的一个字节数据,此前存储在累加器A中WRITE_1820:MOV R2,#8 ;8位数据CLR CWR1: CLR DQ ;低电平MOV R3,#3 ;13μsDJNZ R3,$RRC A ;A中最低位进入CyMOV DQ,C ;Cy送到数据线MOV R3,#11 ;46μsDJNZ R3,$SETB DQNOPDJNZ R2,WR1 ;循环8次SETB DQ ;发完,进入空闲状态RET;================================================================;读DS18B20的程序,从DS18B20中读出一个字节的数据; -------------读出的数据存放在ACCREAD_1820:MOV R2,#8 ;8位2进制数RE1: CLR CSETB DQ ;总线拉高,可能已经是高,没关系NOPNOPCLR DQ ;总线拉低,读时序开始,15μs之内释放NOPNOPNOPSETB DQ ;释放总线,等待器件传出数据MOV R3,#3 ;等待13μsDJNZ R3,$MOV C,DQ ;读取总线上器件传出来的数据MOV R3,#11 ;等待46μsDJNZ R3,$RRC A ;数据进入累加器DJNZ R2,RE1 ;进行下一位数据接收,共8位RET;================================================================;-------------读DS18B20的温度值程序;从DS18B20中读出两个字节的温度数据;读出结果存放在TEMPER_L和TEMPER_H两个单元READ_18202:MOV R4,#2 ;将温度高位和低位从DS18B20中读出MOV R1,#TEMPER_L ;低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE20: LCALL READ_1820 ;读1820一个字节,在ACCMOV @R1,A ;保存接收的字节INC R1 ;下一个字节的地址DJNZ R4,RE20 ;需要接收2个字节,循环2次RET;================================================================。
DS18B20温度传感器数字温度传感器DS18B20是由Dallas半导体公司生产的,它具有耐磨耐碰,体积小,使用方便,封装形式多样(如图1.1.1),适用于各种狭小空间设备数字测温和控制领域。
图1.1.1引脚说明:GND为接地引脚;DQ为数据输入输出脚。
用于单线操作,漏极开路;VCC接电源正;单总线通常要求接一个约4.7K左右的上拉电阻,这样,当总线空闲时,其状态为高电平。
如图1.1.2是温度传感器DS18B20的接线图图1.1.2温度传感器DS18B20的参数:●适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电●温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃●可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温●在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快●被测温度用符号扩展的16位数字量方式串行输出●有两种供电方式既可以直接加 3.0~5.5V的电源,也可以采用寄生电源方式由数据线供电DS18B20内部结构及功能:DS18B20的内部结构如图1.1.3所示。
主要包括:寄生电源,温度传感器,64位ROM和单总线接口,存放中间数据的高速暂存器RAM,用于存储用户设定温度上下限值的TH和TL触发器,存储与控制逻辑,8位循环冗余校验码(CRC)发生器等7部分。
开始8位是产品类型的编号,接着共有48 位是DS18B20 唯一的序列号。
最后8位是前面56 位的CRC 检验码,这也是多个DS18B20 可以采用一线进行通信的原因。
高速暂存存储器:高速暂存存储器由9个字节组成,其分配如图所示。
高速暂存存储器字节0~1 温度寄存器当DS18B20接收到温度转换命令后,开始启动转换。
转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的第1,2字节。
DS18B20的主要特性1.1、适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电1.2、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯1.3、DS18B20支持多点组网功能,多个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、负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。
2、DS18B20的外形和内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DS18B20的外形及管脚排列如下图1:DS18B20引脚定义:(1)DQ为数字信号输入/输出端;(2)GND为电源地;(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)。
图2:DS18B20内部结构图3、DS18B20工作原理DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。
DS18B20测温原理如图3所示。
图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。
高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。
计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
图3:DS18B20测温原理框图DS18B20有4个主要的数据部件:(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。
64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。
光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
(2)DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB 形式表达,其中S为符号位。
表1: DS18B20温度值格式表这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H。
表2: DS18B20温度数据表(3)DS18B20温度传感器的存储器DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EEPRAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。
(4)配置寄存器该字节各位的意义如下:表3:配置寄存器结构TM R1 R0 1 1 1 1 1低五位一直都是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。
在DS18B20出厂时该位被设置为0,用户不要去改动。
R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)表4:温度分辨率设置表R1 R0 分辨率温度最大转换时间0 0 9位93.75ms0 1 10位187.5ms1 0 11位375ms1 1 12位750ms4、高速暂存存储器高速暂存存储器由9个字节组成,其分配如表5所示。
当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。
单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如表1所示。
对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S =1时,先将补码变为原码,再计算十进制值。
表2是对应的一部分温度值。
第九个字节是冗余检验字节。
表5:DS18B20暂存寄存器分布寄存器内容字节地址温度值低位(LS Byte)0温度值高位(MS Byte) 1高温限值(TH)2低温限值(TL) 3配置寄存器4保留5保留6保留7CRC校验值8根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。
复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
表6:ROM指令表指令约定代码功能读ROM 33H 读DS1820温度传感器ROM中的编码(即64位地址)符合ROM 55H 发出此命令之后,接着发出64 位ROM 编码,访问单总线上与该编码相对应的DS1820 使之作出响应,为下一步对该DS1820 的读写作准备。
搜索ROM 0FOH 用于确定挂接在同一总线上DS1820 的个数和识别64 位ROM 地址。
为操作各器件作好准备。
跳过ROM 0CCH忽略64 位ROM 地址,直接向DS1820 发温度变换命令。
适用于单片工作。
告警搜索命令0ECH执行后只有温度超过设定值上限或下限的片子才做出响应。
表6:RAM指令表指令约定代码功能温度变换44H 启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75ms)。
结果存入内部9字节RAM中。
读暂存器0BEH 读内部RAM中9字节的内容写暂存器4EH 发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据。
复制暂存器48H将RAM中第3 、4字节的内容复制到EEPROM中。
重调EEPROM0B8H将EEPROM中内容恢复到RAM中的第3 、4字节。
读供电方式0B4H读DS1820的供电模式。
寄生供电时DS1820发送“ 0 ”,外接电源供电DS1820发送寄生电源:从电源的框图中可以看出,电路从DQ和VDD为高电平时“偷取”能量,当特定的时间和电压适合时,DQ可以给电路提供充足的能量。
寄生电源的优势有二:无需提供遥远的电源;在缺少正常供电时,可以读取ROM.为了使芯片能够精确的对温度进行转换,当转换温度时确保供电充足。
值得重视的是,如果运行电流到达1.5mA,由于5K的上拉电阻,DQ不能得到足够的能量,这对单总线上连接多个芯片同时进行转换是很不利的。
这里有两种方法确保温度转换时有足够的能量,第一种方法是无论什么时候转换温度或者从EEPROM拷贝数据给DQ提供一个强上拉电阻,这种方法可以通过使用一个场效应管上拉DQ线直接提供能量,如下图所示:在这里值得注意的是DQ线必须在发出命令10us内完成上拉操作,当使用这种模式的时候,确保VDD接地。
另外一种提供电流的方式是通过使用VDD引脚连接一个外部电源,如下图所示,这样连接的优势是DQ上不需要连接一个强上拉,并且总线控制主机不需要在温度转换的时候总保持高电平,这样使得在转换的时间内单线上可以有其他的数据通过。
此外,任何DS18B20的序列都可以挂在单线上,如果都需要使用外部电源,可以同时通过执行“跳过ROM”和执行温度转换命令来进行温度转换,注意当外部电源激活时,GND必须接地。
在温度达到100度时,寄生电源的方式不推荐使用,因为提供过高的漏电电流使得正常通信不能维持。
应用这种高温时强烈推荐VDD连接DS18B20。
环境有时候不知道控制主机知道哪里DS18B20芯片使用了寄生电源或者使用外部的VDD,这里可以通过电源信号来实现,也是就总线控制主机通过发送“跳过ROM”命令,然后发送读取的命令,然后读取时间点,此时如果芯片发送“0”回总线表示使用的是寄生电源方式,发送“1”表示通过VDD提供能量,如果主机收到“0”就知道必须在转换温度时给DQ 提供强上拉,其他的存储器控制命令可以参看命令协议中详情。
操作:温度测量DS18B20的核心功能是指示数字的温度传感器,其方案可以由用户设置(9,10,11,12位),默认情况使用12位。
这相当于现实不同的精度。
通过温度转换命令执行操作后温度数据被保存在16位高速缓存中,信号分为两种不同的格式保存,通过执行读缓存的命令返回采集到的温度。
传送时最低有效位LSB优先,最高加权位包含了标识温度正负的“s”位。
左边的图描述了输出数据的格式,在这里使用12bit,如果想设置为更低位解决方案,可以在空位处补零。
如果采用华氏温度显示,则需要查找表或者是查找路径。
操作:警示信号温度转换完成后,温度将和TH与TL进行比较,如果不在这个范围之内则会返回一个警示标志。
允许多芯片同时并行惊醒温度测量,如果某处芯片超出了此范围,此芯片可以被辨别出并立即读取没有别警示的芯片。
64位激光ROM:每一片芯片提供了一个特定的系列号,前8位为DS18B20的家族系列,后面48位表征不同的芯片系列。
在通过单线对芯片进行配置后,放可以执行下面的操作。
READ: MOV R4,#2MOV R1,#TEMLRE0: MOV R2,#8RE1: CLR CCLR DQNOPNOPSETB DQNOPNOPNOPNOPMOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE0MOV @R1,AINC R1DJNZ R4,RE0RET。