单片机课程设计已完成,现供以参考。
DS18B20单总线的工作方式
数据手册说明1:
DS18B20数字温度传感器提供9-Bit到12-Bit的摄氏温度测量精度和一个用户可编程的非易失性且具有过温和低温触发报警的报警功能。DS18B20采用的1-Wire通信即仅采用一个数据线(以及地)与微控制器进行通信。该传感器的温度检测范围为-55℃至+125℃,并且在温度范围超过-10℃至85℃之外时还具有±0.5℃的精度。此外,DS18B20可以直接由数据线供电而不需要外部电源供电。
每片DS18B20都有一个独一无二的64位序列号,所以一个1-Wire总线上可连接多个DS18B20设备。因此,在一个分布式的大环境里用一个微控制器控制多个DS18B20是非常简单的。这些特征使得其在HVAC环境控制,在建筑、设备及机械的温度监控系统,以及温度过程控制系统中有着很大的优势。
特性
· 独特的1-Wire总线接口仅需要一个管脚来通信。
· 每个设备的内部ROM上都烧写了一个独一无二的64位序列号。
· 多路采集能力使得分布式温度采集应用更加简单。
· 无需外围元件。
· 能够采用数据线供电;供电范围为3.0V至5.5V。
· 温度可测量范围为:-55℃至+125℃(-67℉至+257℉)。
· 温度范围超过-10℃至85℃之外时具有±0.5℃的精度。
· 内部温度采集精度可以由用户自定义为9-Bits至12-Bits。
DS18B20 分辨率可编程
1-Wire(单总线)数字温度传感器
· 温度转换时间在转换精度为12-Bits时达到最大值750ms。
· 用户自定义非易失性的的温度报警设置。
· 定义了温度报警搜索命令和当温度超过用户自定义的设定值时。
· 可选择的8-Pin SO (150 mils), 8-PinμSOP,及3-Pin TO-92封装。
· 与DS1822程序兼容。
· 应用于温度控制系统,工业系统,民用产品,温度传感器,或者任何温度检测系统中。
1. 初始化:
主机视角理解:主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现一直都是高电平说明总线上无器件应答。
从机视角理解:为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。
2. 写时序与读时序
写时序:
主机发出各种操作命令都是向DS18B20写0和写1组成的命令字节,接收数据时也是从DS18B20读取0或1的过程。因此首先要搞清主机是如何进行写0、写1、读0和读1的。
写周期最少为60微秒,最长不超过120微秒。
写周期一开始做为主机先把总线拉低1微秒表示写周期开始。
随后若主机想写0,则将总线置为低电平,若主机想写1,则将总线置为高电平,持续时间最少60微秒直至写周期结束,然后释放总线为高电平至少1微秒给总线恢复 。
而DS18B20则在检测到总线被拉底后等待15微秒然后从15微秒到45微秒开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为0。
读时序:
对于读数据操作时序也分为读0时序和读1时序两个过程。
读周期是从主机把单总线拉低1微秒之后就得释放单总线为高电平,以让DS18B20把数据传输到单总线上。
作为从机DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。主机在一开始拉低总线1微秒后释放总线,然后在包括前面的拉低总线电平1微秒在内的15微秒时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为1。完成一个读时序过程,至少需要60微秒才能完成。
DS18B20初始化复位函数,每次执行指令之前,必须初始化。
DS18B20_Reset:
CLR EA ;由于DS18B20对时序要求较严格,所以采样期间关中断
CLR DQ ;复位
MOV R7,#48 ;调用延时函数
CALL DelayX0us ;延时至少480us
SETB DQ ;释放数据线
MOV R7,#6 ;等待60us
CALL DelayX0us
MOV C,DQ ;检测存在脉冲
MOV R7,#42 ;等待设备释放数据线
CALL DelayX0us
JC DS18B20_Reset ;如果设备不存在,则继续等待
;SETB DQ ;释放总线
;NOP ;等待1个机器周期
SETB EA ;初始化完毕,可以允许中断
RET
访问DS18B20的事件序列如下所示:
第一步:初始化
第二步:ROM命令(紧跟任何数据交换请求)
第三步:DS18B20功能命令(紧跟任何数据交换请求)
每次对DS18B20的访问都必须遵循这样的步骤来进行,如果这些步骤中的任何一个丢失或者没有执行,则DS18B20将不会响应。除了ROM搜索命令[F0h]和报警搜索命令[ECh]之外。当执行完这些ROM命令之后,主设备必须回到上述步骤中的第一步。
数据手册说明2:
初始化
1-Wire总线上的所有事件都必须以初始化为开始。初始化序列由总线上的主设备发出的复位脉冲以及紧跟着从设备回应的存在脉冲构成。该回应脉冲让总线上的主设备知道在该总线上有从设备(例如DS18B20),并且已经准备好进行操作。复位及存在脉冲时序见上述。
ROM命令
当总线上的主设备检测到了存在脉冲后,就可以执行ROM命令。这些命令是对每个设备独一无二的64位ROM编码进行操作的,当总线上连接有多个设备时,可以通过这些命令识别各个设备。这些命令同时也可以使主设备确定该总线上有多少个什么类型的设备或者有温度报警信号的设备。总共包含有5种ROM命令,每个命令的长度都是8 Bit。主设备在执行DS18B20功能命令之前必须先执行一个适当的ROM命令。
跳过ROM[CCh]
主设备可以使用该命令来同时向总线上的所有从设备发送不要发送任何的ROM编码命令。例如,主设备通过向总线上所有的DS18B20发送跳过ROM命令后再发送温度转换[44h]命令,则所有设备将会同时执行温度转。
需要注意的是,当总线上仅有一个从设备时,读取暂存寄存器[BEh]命令后面可以跟随跳过ROM命令。在这种情况下,主设备可以读取从设备中的数据而不发送64位ROM编码。当总线上有多个从设备时,若在跳过ROM命令后再发送读取暂存寄存器命令,则所有的从设备将会同时开始传送数据而导致总线上的数据冲突。
温度转换[44h]
该命令为初始化单次温度转换。温度转换完后,温度转换的数据存储在暂存寄存器的2个字节长度的温度寄存器中,之后DS18B20恢复到低功耗的闲置状态。如果该设备是采用的“寄生电源”供电模式,在该命令执行10uS(最大)后主设备在温度转换期间必须强制拉高数据线(“DS18B20的供电”章节所描述)。如果该设备是采用的外部供电模式,主设备在温度转换命令之后可以执行读取数据时序,若DS18B20正在进行温度转换则会响应0电平,温度转换完成则响应1电平。在“寄生电源”供电模式下,因为在整个温度转换期间总线都是强制拉高的状态,故不会有上述响应。
读取暂存寄存器[BEh]
该命令使得主设备可以读取暂存寄存器中存储的值。数据从Byte 0的低位开始传送直到第9个字节(Byte 8 - CRC)读取完毕。主设备若只需要暂存寄存器中的部分数据,则可以在读取数据中通过复位来终止。
DS18B20温度采集工作流程:
Reset:
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#044H ;开始转换
CALL DS18B20_WriteByte ;送出命令
JNB DQ,$ ;等待转换完成
;CALL 750MS
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#0BEH ;读暂存存储器
CALL DS18B20_WriteByte ;送出命令
CALL DS18B20_ReadByte ;读温度低字节
MOV TPL,A ;存储数据
CALL DS18B20_ReadByte ;读温度高字节
MOV TPH,A ;存储数据
RET
温度值换算:
18B20的寄存器格式如下图所示,
最高位5位表示符号位,00000为正值,111111为负值;
最低的4位决定分辨率,如表中+0.5一行所示,最低四位为1000,
2
−
1
即
0.5
2^{-1}即0.5
2−1即0.5;
以此类推,最低四位为0100时,
2
−
2
即
0.25
2^{-2}即0.25
2−2即0.25。
温度采集与数码管显示函数:
TPH DATA 20H ;存放温度值的高字节
TPL DATA 21H ;存放温度值的低字节
TAB1: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0C6H,89H,0C7H ;8段数码管编码表
TAB2: DB 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 ;分辨率为0.5℃
CAIJI:
SETB ES
LCALL RESET ;初始化,开始温度采集
MOV A,TPH ;读取温度高字节
ANL A,#00000111B ;取低3位,高5位为符号位
RL A ;左移至高地址
RL A
RL A
RL A
MOV 40H,A ;存入40H
MOV A,TPL
ANL A,#11110000B ;屏蔽低地址
SWAP A
ORL A,40H ;40H存放数据温度低四位+高四位 1111
MOV B,#64H ;0110 0100
DIV AB ;除以100D,取百位
MOV 54H,A ;40H中的十位放入54H,百位
MOV A,B
MOV B,#10
DIV AB ;百位再除10得十位、个位
MOV 53H,A ;十位
MOV 52H,B ;个位
MOV A,TPL
ANL A,#00001111B
MOV DPTR,#TAB2
MOVC A,@A+DPTR
MOV 51H,A ;小数点后的一位
RET
DISPLAY:
MOV 50H,#0AH ;50H存入十六进制的10
MOV R0,#50H
MOV R7,#0FEH
MOV DPTR,#TAB1
LOOPD: ;动态扫描显示
MOV A,@R0
MOVC A,@A+DPTR ;取TAB1中的第十位数据0C6H,即大写C
MOV P1,A ;段选
MOV P2,R7 ;位选P2.0显示摄氏度符号C
ACALL DELAY
INC R0 ;显示下一位51H、52H、53H
MOV A,R7
RL A
MOV R7,A
JB ACC.4,LOOPD
MOV P2,#0FBH ;位选带小数点的那位
MOV P1,#07FH ;段选显示小数点
ACALL DELAY
MOV P2,#0FFH ;位选关闭
RET
实物效果:
由于上电复位时温度寄存器中的值为+85℃,故一开始数码管上会看到显示85.0℃。
还可用过添加按键功能,设置温度上下限,以及蜂鸣器温度报警:
以下程序通过一个死循环中根据按键K4的变化,调用响应子程序。实现三种模式,MENU0为实时温度检测、MENU1为设置高温上限、MENU2为设置低温上限。
K4 BIT P3.4 ;菜单键
K3 BIT P3.3 ;加计数键
K2 BIT P3.2 ;减计数键
;主循环
MAIN:
MOV MENU,#0
MOV V_HH,#02H ;温度上限值高字节初值
MOV V_HL,#30H ;温度上限值低字节初值
MOV V_LH,#00H ;温度下限值高字节初值
MOV V_LL,#0A0H ;温度下限值低字节初值
LOOP111:
CJNE A,#0,START
LCALL MENU0 ;初始化先进入菜单0,实时温度采集
START:
JNB K4,NEXT ;检测K4是否被按下
LJMP NO_NEXT
NEXT:
INC MENU ;按下则MENU+1
LCALL SETTLE
JNB K4,$
NO_NEXT:
MOV A,MENU
CJNE A,#0,NEXT0
LJMP RESTART
NEXT0:
CJNE A,#01H,NEXT1
LCALL MENU1
NEXT1:
CJNE A,#02H,RESTART
LCALL MENU2
RESTART:
SJMP loop111
SETTLE:
LCALL DELAY
MOV A,MENU
CJNE A,#03H,NEXT5
LCALL CLR_MENU ;MENU为3时,则通过子程序清0
NEXT5:
RET
MENU0:
LCALL CAIJI ;18B20温度采集
LCALL DISPLAY ;数码管显示
LCALL BUZZER ;温度报警
RET
MENU1: ;模式1,用于调节高温上限值
;LCALL BUZZER
LCALL UP_KEYH ;检测按键K3子程序
LCALL DOWN_KEYH ;检测按键K2子程序
MOV TPH,V_HH ;上限值存入TPH用于数码管显示
MOV TPL,V_HL ;下限值存入TPL用于数码管显示
LCALL EN_VHL
LCALL DISP_COVERH
RET
MENU2: ;模式2,用于调节低温下限值
;LCALL BUZZER
LCALL UP_KEYL ;同上
LCALL DOWN_KEYL
MOV TPH,V_LH
MOV TPL,V_LL
LCALL EN_VHL
LCALL DISP_COVERL
RET
通过按键调节温度上下限值:
以调节高温上限值为例
UP_KEYH: ;按键3用于上限值+计数,短按+1,长按连续++
JB K3,EXH3
UP_KH3:
LCALL DEL1S
MOV A,V_HL
ADD A,#10H
MOV V_HL,A
MOV A,V_HH
ADDC A,#0
MOV V_HH,A
EXH3:
RET
DOWN_KEYH: ;按键2用于上限值-计数,短按-1,长按连续--
JB K2,EXH4
DOWN_KH4:
LCALL DEL1S
MOV A,V_HL
SUBB A,#10H
MOV V_HL,A
MOV A,V_HH
SUBB A,#0
MOV V_HH,A
EXH4:
RET
蜂鸣器报警函数:
BUZZER: ;报警程序
MOV A,TPH
CJNE A,V_HH,STEP
STEP:
JC SAFE1 ;比较高字节后,若温度值高字节小于上限值高字节,直接比较下限值
SUBB A,V_HH
JZ IF_SAFE
LJMP BZ_IN
IF_SAFE:
MOV A,TPL
CJNE A,V_HL,SAFE
SAFE:
JNC BZ_IN
SAFE1:
MOV A,TPH
CJNE A,V_LH,STEP1 ;比较低字节,若温度值低字节低于上限值低字节,报警
STEP1:
JC BZ_IN
SUBB A,V_LH
JZ IF_SAFE1
LJMP BZ_OUT
IF_SAFE1:
MOV A,TPL
CJNE A,V_LL,SAFE2
SAFE2:
JC BZ_IN
LJMP BZ_OUT
BZ_IN: ;无源蜂鸣器响
CPL FMQ
BZ_OUT: ;不响,退出子程序
RET
若使用无源蜂鸣器,则需提供一定频率的脉冲才可正常发声,方法见下载资料中所提供。
下载资料:
完整C程序工程文件:
C语言DS18B20
完整汇编程序工程文件:
汇编DS18B20