DS18B20温度传感器的使用方法有哪些?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DS18B20温度传感器的使用方法有哪些?相关的知识,希望对你有一定的参考价值。
我用的是MCS-51的系统,8051的芯片,做温度显示,要求设定温度上下限,最好有汇编语言的源程序,谢谢了。
;这是关于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,29H
MOV C,40H;将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
LCALL DISPLAY;调用数码管显示子程序
CPL P1.0
AJMP MAIN
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB P2.2
NOP
CLR P2.2
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P2.2;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P2.2,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
CLR P1.7;检查到DS18B20就点亮P1.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
CLR P1.1
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:
SETB P2.2
RET
; 读出转换后的温度值
GET_TEMPER:
SETB P2.2
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
CLR P1.2
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
CLR P1.3;DS18B20已经被检测到!!!!!!!!!!!!!!!!!!
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL DISPLAY
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200; 将读出的温度数据保存到35H/36H
CLR P1.4
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR P2.2
MOV R3,#5
DJNZ R3,$
RRC A
MOV P2.2,C
MOV R3,#21
DJNZ R3,$
SETB P2.2
NOP
DJNZ R2,WR1
SETB P2.2
RET
READ_18200: ; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB P2.2
NOP
NOP
CLR P2.2
NOPNOP
NOP
SETB P2.2
MOV R3,#8
RE10:
DJNZ R3,RE10
MOV C,P2.2
MOV R3,#21
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;显示子程序
display: mov a,29H;将29H中的十六进制数转换成10进制
mov b,#10 ;10进制/10=10进制
div ab
mov b_bit,a ;十位在a
mov a_bit,b ;个位在b
mov dptr,#numtab ;指定查表启始地址
mov r0,#4
dpl1: mov r1,#250 ;显示1000次
dplop: mov a,a_bit ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
mov p0,a ;送出个位的7段代码
clr p2.7 ;开个位显示
acall d1ms ;显示1ms
setb p2.7
mov a,b_bit ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
mov p0,a ;送出十位的7段代码
clr p2.6 ;开十位显示
acall d1ms ;显示1ms
setb p2.6
djnz r1,dplop ;100次没完循环
djnz r0,dpl1 ;4个100次没完循环
ret
;1MS延时
D1MS: MOV R7,#80
DJNZ R7,$
RET
;实验板上的7段数码管0~9数字的共阴显示代码
numtab: DB 0CFH,03H,5DH,5BH,93H,0DAH,0DEH,43H,0DFH,0DBH
END 参考技术A 哈哈,还是去学校问老师吧。现在的学生真有意思,都把百度当成免费的答案索取地了。 参考技术B 我不知道.....
温度传感器DS18B20
用AVR怎么读和写?
最好有示例的程序
lnlh21 - 试用期 一级 :你说那个网站资料太少,找不到我要的
我的单片机频率是8M,如果你的频率不同,请自己计算后把延时参数修改一下就可以了。
DS1820温度传感器单线总线读时间片
read: push r24
in r24,SREG
push r24
ldi r22,$FF
clr r23
out PORTB,r22 ;升高单线总线
out DDRB,r22 ;B口为输出口
out PORTB,r23 ;拉低单线总线
ldi r24,$05
read1: dec r24
brne read1 ;延迟10个时钟周期(大约1.25微秒)
out DDRB,r23 ;B口为输入口
ldi r24,$30
read2: dec r24
brne read2 ;延迟96个时钟周期(大约12微秒)
in r21,PINB ;读单线总线
ldi r24,$C8
read3: dec r24
brne read3 ;延迟400个时钟周期(大约50微秒)
pop r24
out SREG,r24
pop r24
ret
DS1820温度传感器单线总线写0时间片
write0: push r24
in r24,SREG
push r24
ldi r22,$FF
clr r23
out PORTB,r22 ;升高单线总线
out DDRB,r22 ;B口为输出口
out PORTB,r23 ;拉低单线总线
clr r24
wr0j1: dec r24
dec r24
nop
nop
brne wr0j1 ;延迟640个时钟周期(大约80微秒)
out PORTB,r22 ;升高单线总线
ldi r24,$07
wr0j2: dec r24
brne wr0j2 ;延迟14个时钟周期(大约1.75微秒)
out DDRB,r23 ;B口为输入口
pop r24
out SREG,r24
pop r24
ret
DS1820温度传感器单线总线写1时间片
write1: push r24
in r24,SREG
push r24
ldi r22,$FF
clr r23
out PORTB,r22 ;升高单线总线
out DDRB,r22 ;B口为输出口
out PORTB,r23 ;拉低单线总线
ldi r24,$07
wr1j1: dec r24
brne wr1j1 ;延迟14个时钟周期(大约1.75微秒)
out PORTB,r22 ;升高单线总线
clr r24
wr1j2: dec r24
dec r24
nop
nop
brne wr1j2 ;延迟640个时钟周期(大约80微秒)
out DDRB,r23 ;B口为输入口
pop r24
out SREG,r24
pop r24
ret本回答被提问者采纳 参考技术B 我使用的是Code Vision AVR C V2.03.4,其中带了一个DS18B20网络的读写控制程序,只要把DS18B20并联在这个网络中,就可以使用程序读写了。其全部代码如下:
/* Multipoint thermometer with LCD display
using the Maxim DS18B20
1 Wire bus temperature sensors
CodeVisionAVR C Compiler
(C) 2000-2005 HP InfoTech S.R.L.
www.hpinfotech.ro
Chip: ATmega8515
Memory Model: SMALL
Data Stack Size: 128 bytes
PLEASE MAKE SURE THAT THE CKSEL0..3 FUSE
BITS ARE PROGRAMMED TO USE THE EXTERNAL
3.6864MHz CLOCK SOURCE OF THE STK500 AND NOT
THE INTERNAL 1MHz OSCILLATOR.
The ATmega8515 chip comes from the factory
with CKSEL0..3 fuse bits set to use the
internal 1 MHz oscillator.
The DS18B20 sensors are connected to
bit 6 of PORTA of the ATmega8515 as follows:
[DS18B20] [STK500 PORTA HEADER]
1 GND - 9 GND
2 DQ - 7 PA6
3 VDD - 10 +5V
All the temperature sensors must be connected
in parallel
AN 4.7k PULLUP RESISTOR MUST BE CONNECTED
BETWEEN DQ (PA6) AND +5V !
*/
#asm
.equ __w1_port=0x1b
.equ __w1_bit=6
#endasm
/* Use an 2x16 alphanumeric LCD connected
to PORTC as follows:
[LCD] [STK500 PORTC HEADER]
1 GND- 9 GND
2 +5V- 10 VCC
3 VLC- LCD contrast control voltage 0..1V
4 RS - 1 PC0
5 RD - 2 PC1
6 EN - 3 PC2
11 D4 - 5 PC4
12 D5 - 6 PC5
13 D6 - 7 PC6
14 D7 - 8 PC7
*/
#asm
.equ __lcd_port=0x15
#endasm
#include <lcd.h> // LCD driver routines
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>
char lcd_buffer[33];
/* maximum number of DS18B20 connected to the 1 Wire bus */
#define MAX_DEVICES 8
/* DS18B20 devices ROM code storage area */
unsigned char rom_code[MAX_DEVICES][9];
main()
unsigned char i,j,devices;
lcd_init(16);
lcd_putsf("CodeVisionAVR\n1 Wire Bus Demo");
delay_ms(2000);
lcd_clear();
/* detect how many DS18B20 devices
are connected to the 1 Wire bus */
devices=w1_search(0xf0,rom_code);
sprintf(lcd_buffer,"%u DS18B20\nDevice detected",devices);
lcd_puts(lcd_buffer);
delay_ms(2000);
/* display the ROM codes for each device */
if (devices)
for (i=0;i<devices;i++)
sprintf(lcd_buffer,"Device #%u ROM\nCode is:",i+1);
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(2000);
lcd_clear();
for (j=0;j<8;j++)
sprintf(lcd_buffer,"%02X ",rom_code[i][j]);
lcd_puts(lcd_buffer);
if (j==3) lcd_gotoxy(0,1);
;
delay_ms(5000);
;
else
while (1); /* stop here if no devices were found */
/* configure each DS18B20 device for 12 bit temperature
measurement resolution */
for (i=0;i<devices;)
if (!ds18b20_init(&rom_code[i++][0],20,30,DS18B20_12BIT_RES))
sprintf(lcd_buffer,"Init error for\ndevice #%u",i);
lcd_clear();
lcd_puts(lcd_buffer);
while (1); /* stop here if init error */
;
/* measure and display the temperature(s) */
while (1)
j=1;
for (i=0;i<devices;i++)
sprintf(lcd_buffer,"t%u=%+.3f\xdfC",j++,ds18b20_temperature(&rom_code[i][0]));
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(500);
;
;
程序很简洁,它这里使用的是Mega8515芯片,使用外部3.6864MHz晶振;DS18B20的DQ接在端口A的第6个端口位上,要接4.7K的上拉电阻;液晶显示器接在端口C上,使用4位数据总线方式。程序自动检测DS18B20的个数,并且设置DS18B20的工作方式,再显示各自测量的温度。
在实际使用时根据需要修改程序,比如更改DS18B20的接线位置和LCD使用的端口。 参考技术C 我来回答:基本上是这样的,可以用仿真器读取每一个18B20的序列号.也可以单独找一块有数码管或液晶显示的板子,专门烧个片子读序列号,然后显示出来,玩单片机的人这种板子肯定会有吧,没有的话焊一块出来也很快.
如果有兴趣的话还可以把读序列号的子程序融合到你测量温度的主程序中.条件:单片机内含有或板上有EEPROM.方法:设一个I/O口跳线,可临时将I/O口置高电平或低电平(实际上接个按钮也行),主程序一开始就读这个I/O口,低电平就读序列号,并将序列号写入EEPROM(当然18B20每次只能接一个读取,多个18B20可分次读取,存入EEPROM不同的地址),如果高电平就执行测量温度的程序,序列号从EEPROM中获取.这种方法比较麻烦,但可提高系统的可维护性,做好了就一劳永逸,否则一旦某个18B20损坏更换,就必须依赖仿真器读序列号,还要到主程中修改,再用编程器重新烧片子. 6432希望对你有用!
参考资料:. xpwmjmr
参考技术D 最简单的方法是,去www.ouravr.com下个别人的例子,把18B20的那部分复制下来就行!我就是这么干的,有别人的用,自己就没去写了~!
以上是关于DS18B20温度传感器的使用方法有哪些?的主要内容,如果未能解决你的问题,请参考以下文章
DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号