使用汇编语言实现的单片机高温报警系统温度检测方案

单片机温度检测高温报警系统

  1. 实验目的

1) 掌握 51 单片机定时器/计数器工作原理与应用;

2) 掌握 51 单片机中断系统工作原理与应用;

3) 掌握 Keil μVision 软件开发环境,汇编语言源程序的编制与调试;

4)掌握ds18b20温度检测传感器使用方法

5)掌握单片机拓展总线的工作原理和时序操作;

2.实验设备机器软件

1) Keil μVision 软件

2) Proteus 软件

3) 计算机

4)ds18b20传感器

3. 实验内容

1)利用定时器中断显示数据

2)理解和合理利用ds18b20温度传感器使用方法

3)合理利用严格的时序进行数据的写入和读出

4)利用共阴极的二位数码管动态显示温度

5)高温检测报警

4. 实验要求

1) 在 Proteus ISIS 集成环境中,绘制电路原理图;

2) 设计程序流程,并绘制程序流程图;

3) 在 Keil μVision中编制汇编语言源程序,调试实现要求功能,生成可 执行程序;

4) 在 Proteus ISIS 完成硬件仿真调试。

5) 提交 Keil μVision 程序、Proteus ISIS 设计文件、实验报告。

5. 设计要点

1) 采用定时器/计数器T0进行计时,工作方式1(16 位定时器/计数器),振频率12MHz,定10ms;

2) 定时器/计数器工作在中断方式,打开定时器0的中断开关,每10ms进行一次温度动态显示;

3)按照时序读出温度数据,进行温度数据处理,存储在一个字节(34H)里,然后分别存储个位、十位;

4) P0.0-P0.3进行个位十位的数以四位二进制的形式输出,经过编码器,传递给七段数码管,同时用P0.4、P0.5进行个位十位的选通,间隔10ms,达到动态显示的效果 ;

5) 软件自行设定温度阈值,与实时温度相比较,超出阈值温度,蜂鸣器响,显示温度。

6.程序流程设计

1)主程序流程图设计

 

2)T0中断程序

 

3)复位程序(RSTSNR)

 

 4)写入指令程序(SEND_BYTE)

 

5)数据读取指令

 

5) 2 位动态数码管显示子程序

 

6)温度超过阈值报警

7.Proteus 电路原理图

 

参与的电子元件

 

ds18b20:温度传感器

74ls74:四位二进制的七段数码管编码器

8.工作原理简述

DS18B20简介

DS18B20连接在单片机的P3.7口上。P3口发挥了作为I/O口的功能。通过一根单总线连接,单片机向DS18B20发出时序信号来对DS18B20做出指令。

 

DS18B20的暂存寄存器

 单片机通过单总线读取DS18B20的数据时,总是从Byte 0的最低位开始传输的。Byte 0和Byte 1用来存储温度的第八位和高八位。本次设计只用到byte0和byte1以及用byte4的配置寄存器来设定分辨率。

 

 配置寄存器与温度分辨率的配置

 配置寄存器只有bit5和bit6是可以写入的,其他不可以写入。上电默认R1R0=11(十二位分辨率),在这次设计中我采用默认分辨率。

复位原理

 

初始化时序

 复位讲究严格的时序,主控制器首先发送一个高电平,然后再拉低,并维持500us,然后主机转为输入状态,上大电阻将总线拉为高电平。DS18B20在上电之后就检测是否存在480-960us的低电平出现,如果有总线拉为高电平之后的50us左右等待时间后将总线拉低60-240us告诉主机DS18B20处于ready状态。复位程序中使用F0来做响应标志位,F0=1表示从机存在,F0=0表示从机不存在。

//复位程序
RSTSNR: SETB DAT           //拉高DQ
NOP
NOP
CLR DAT            //拉低DQ 600
μs
MOV R6,#250
DJNZ R6,$
MOV R6,#50
DJNZ R6,$
SETB DAT                                 //释放DQ
MOV R6,#15
DJNZ R6,$
lCALL CHCK            //调用应答回应判断程序
MOV R6,#60
DJNZ R6,$
SETB DAT
RET

CHCK: MOV C,DAT              //进位标志位
JC RST0            //DAT为1 跳转
SETB F0            //DAT为0 应答信号 置位 F0
SJMP CHCK0
RST0:  CLR F0            //为准备好 F0复位
CHCK0: RET

 

写入数据

 

写时序

 主控制器的写时序包括写1和写0,写时序周期大于60us小于120us。每一个写时序都开始于主控制器拉低总线0-15us,若要写“0”,继续拉低总线,使总线自开始到拉高至少60us。若要写“1”,则在拉低总线开始写时序1us之后释放总线为高电平。写入数据必须先复位然后跳过ROM,再进行读写。

SEND_BYTE:MOV A,R0
MOV R5,#8
SEN3: CLR C
RRC A
JC SEN1
LCALL WRITE_0
SJMP SEN2
SEN1: LCALL WRITE_1
SEN2: DJNZ R5,SEN3      //循坏8次,发送一个字节
RET

 

读出数据

 

读时序

 只有在读时段期间DS18B20才能向主设备传输数据,在读数据前可以对数据进行转换为温度操作。读时段通过主控制器将总线拉低至少1us再释放总线来完成初始化,初始化完成后DS18B20会向总线发送0或1。DS18B20通过将总线拉高来发送1,将总线拉低来发送0。发送完后,总线通过上拉电阻恢复到高电平。DS18B20发送的数据在初始化后只有15us的有效时间。读出数据后延时50us。

/读一个字节程序
READ_BYTE:MOV R5,#8
READ1: LCALL READ
RRC A
DJNZ R5,READ1
MOV R0,A
RET
//读一位数据
READ: SETB DAT     //产生读时序
NOP
NOP
CLR DAT
NOP
NOP
SETB DAT     //置位DAT准备接受数据
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,DAT
MOV R6,#23
DJNZ R6,$
RET
 

温度转换

 

RAM操作指令

 

ROM操作指令

    首先根据F0判断DS18B20是否存在。不存在跳回主程序,存在则写0CCH入DS18B20跳过ROM指令,然后写44H,使DS18B20温度转换。然后读时序,先复位,然后写入0CCH跳过ROM,然后写0BEH读暂存器内容。

DSWD: LCALL RSTSNR          //调用复位子程序
JNB F0,KEND           //判断是否应答
MOV R0,#0CCH          //应答后,写入跳过ROM匹配命令
LCALL SEND_BYTE
MOV R0,#44H           //写入温度转换命令
LCALL SEND_BYTE
SETB EA
MOV 48H ,#1            //延时75ms以上准备读
SS2: MOV 49H,#255
SS1: MOV  4AH,#255
SS0: DJNZ 4AH,SS0
DJNZ 49H,SS1
DJNZ 48H,SS2
CLR  EA              //禁止中断
LCALL RSTSNR
JNB F0,KEND             //应答后 跳转
        MOV R0,#0CCH                                    
LCALL SEND_BYTE
MOV R0,#0BEH            //写入读取温度指令
LCALL SEND_BYTE
LCALL READ_BYTE          //读一个字节温度(低8字节)
MOV WDLSB,A
LCALL READ_BYTE          //读一个字节温度(低8字节)
MOV WDMSB,A
LCALL TRANS12
KEND:   SETB EA              //开中断
RET

 

数据处理

读取数据后,对数据进行处理,只取整数部分,将读出的高位与地位相结合后处理为一个八位二进制的数。随后对其除以10取余得到十位与各位数字,分别用四位二进制表示。

TRANS12:MOV A,30H        //低字节数据传入A       00000 1111 1010 0000
ANL A,#0F0H
MOV 3AH,A
MOV A,31H
ANL A,#0FH
ORL A,3AH
SWAP A         //得到表示温度整数部分的8位二进制数
MOV 34H,A

JIXU: NOP
MOV B,#10
DIV AB
MOV 43H,B
MOV B,#10
DIV AB
MOV 42H,B
MOV 41H,A        //分离两位温度值的十位(存到B)个位(存到A)
MOV A,#wenduyuzhi
CJNE A,34H,BEED
LJMP FANHUI
BEED:   JNC FANHUI
        CLR P1.0
LCALL DELAY
        CLR C
FANHUI: RET

 

温度显示

 

温度显示

数码管显示部分由一个二位动态数码显示器和一个编码器组成。通过控制P0.4和P0.5口的数值来改变二位动态数管显示的开关,然后再改变P0口的值进行选择数码管显示,以此来实现数码管的动态显示。这个过程通过一个10ms的中断来达到动态显示的效果。

TO_INT: MOV TH0,#swpH          //重装定时初值
MOV TL0,#swpL
//利用位21H控制高低位的数据显示
MOV P0,42H            //温度高位传送到P0
ORL P0,#00100000B          //选通P0.5,控制高位数码管显示
LCALL DELAY_10MS

dsl:  MOV P0,43H          //温度的低位数据传送到P0
ORL P0,#00010000B        //选通P0.4,控制低位数码管显示
kkk:                 //求反
RETI           //中断返回

 

超温检测

 

报警电路

在温度转化完成后,将数据存储在34H,将软件中设置的温度阈值与之相比较,利用CJNE与JNC指令来完成比较大小操作,达到在温度超过温度阈值时,P1.0置1,蜂鸣器报警操作。

JIXU: NOP
MOV B,#10
DIV AB
MOV 43H,B
MOV B,#10
DIV AB
MOV 42H,B
MOV 41H,A        //分离两位温度值的十位(存到B)个位(存到A)
MOV A,#wenduyuzhi
CJNE A,34H,BEED
LJMP FANHUI
BEED:   JNC FANHUI
        CLR P1.0
LCALL DELAY
        CLR C
FANHUI: RET
DELAY:
       SETB TR1
MOV 35H,#5
JISHI: CLR TF1
       MOV TH1,#0D8H
MOV TL1,#0F0H
JNB TF1,$
       DJNZ 35H,JISHI
       SETB P1.0   
NOP
CLR TR1
SETB EA
RET

 

9.问题与解决方案

1)DS18B20对于数据的读取、检测等方式讲究严格的时序,在编写程序的过程中,需要考虑好相应指令所需的机器周期,以及进行相应的延时操作来读写数据。我再实验过程中尤其是读取DS18B20传输过来的数据时,最开始一直不对,根本原因就是时序延时没有掌握好,掌握好延时和时序后,就能够顺利读取数据。

2)在对DS18B20操作时需要,讲究遵守规则,需要先复位,跳过 ROM,才能进行读写,更改初值等操作。在编写代码的过程中,需要严格历经这三个过程,不要漏步跳步。

3)动态数码管的温度显示要求时刻不断对数码管有数据输入,不能延迟太大导致肉眼可见的掉帧现象,将显示函数写入函数放在10ms一次的定时器中断当中,完成10ms刷新一次的功能。

4)DS18B20的温度数据传入或给温度传感器的写入都是从地位开始输出,在调试过程中没有注意到这个问题导致,温度读取的数据一直有错误,一直到重新看了一边DS18B20后注意到这个细节,专门写了一个输入和读取函数,与RRC指令相配合达到正确输入和读取数据。

10.总结

这次自主实验,给了我很大的锻炼,这与二位倒计时完全不同,还要重新学习使用温度传感器DS18B20温度传感器,对于初学的我还是有着不小的挑战。在尝试的过程中,使用DS18B20就出现了很多错误,有关于时序的把握,写入数据与读取数据的顺序以及如何实现这些东西都需要去研读使用说明,并配合自己的尝试来得到正确的使用方法。动态数码管的显示方法也是我在这次实验中所学习到的。当然不仅仅只是这个电路图所呈现,我在过程中做过很多尝试,尝试过用锁存器74HC574来作为动态数码管的输入,对于数据显示的方式也采用过将显示子程序放在主函数中,实验的过程中有不断地尝试与试错,可能最终没有被我采纳,但我也学习到了更多的知识。其次单片机,也让我体会到了知识的交叉与融合,在选取硬件设备过程中我用到了上一学期所学的数电模电相关知识。

通过这次实验我更加充分的理解了中断、定时器、引脚输入输出、外部传感器的使用相关知识,让我对单片机从毫不了解到逐渐熟悉地一步步走来。我个人对单片机很感兴趣,我也自己买了一套硬件设备,在后续中我也会继续尝试自己学习,感谢老师在这一学期地悉心指点与教学。

代码

DAT BIT P3.7            //定义P3.7为DQ线
swpH EQU 0D2H
swpL EQU 0FFH
wenduyuzhi DATA 10
WDLSB DATA 30H
WDMSB DATA 31H           //定义读出温度高低字节存放的地址
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TO_INT
ORG 0100H
 //10ms中断函数
TO_INT: MOV TH0,#swpH          //重装定时初值
MOV TL0,#swpL
//利用位21H控制高低位的数据显示
MOV P0,42H            //温度高位传送到P0
ORL P0,#00100000B          //选通P0.5,控制高位数码管显示
LCALL DELAY_10MS

dsl:  MOV P0,43H          //温度的低位数据传送到P0
ORL P0,#00010000B        //选通P0.4,控制低位数码管显示
kkk:                 //求反
RETI           //中断返回

MAIN:  CLR EA
MOV TMOD,#11H         //定时初始化
MOV TH0,#swpH         //定时器装初值
MOV TL0,#swpL
SETB EA           //开中断、允许T0中断、启动T0
SETB ET0
SETB TR0
MOV  R2,#2
MOV  R0,#42H         //定义缓冲单元42H
OVER: MOV @R0,#00H          //清零缓冲单元42H、43H
INC R0            //自加一指向43H
DJNZ R2,OVER
LOOP: LCALL DSWD           //调用读出温度子程序
SJMP  LOOP
DSWD: LCALL RSTSNR          //调用复位子程序
JNB F0,KEND           //判断是否应答
MOV R0,#0CCH          //应答后,写入跳过ROM匹配命令
LCALL SEND_BYTE
MOV R0,#44H           //写入温度转换命令
LCALL SEND_BYTE
SETB EA
MOV 48H ,#1            //延时75ms以上准备读
SS2: MOV 49H,#255
SS1: MOV  4AH,#255
SS0: DJNZ 4AH,SS0
DJNZ 49H,SS1
DJNZ 48H,SS2
CLR  EA              //禁止中断
LCALL RSTSNR
JNB F0,KEND             //应答后 跳转
            MOV R0,#0CCH                                                      
LCALL SEND_BYTE
MOV R0,#0BEH            //写入读取温度指令
LCALL SEND_BYTE
LCALL READ_BYTE          //读一个字节温度(低8字节)
MOV WDLSB,A
LCALL READ_BYTE          //读一个字节温度(低8字节)
MOV WDMSB,A
LCALL TRANS12
KEND:   SETB EA              //开中断
RET

//温度转换程序(只取整)
TRANS12:MOV A,30H        //低字节数据传入A       00000 1111 1010 0000
ANL A,#0F0H
MOV 3AH,A
MOV A,31H
ANL A,#0FH
ORL A,3AH
SWAP A         //得到表示温度整数部分的8位二进制数
MOV 34H,A

JIXU: NOP
MOV B,#10
DIV AB
MOV 43H,B
MOV B,#10
DIV AB
MOV 42H,B
MOV 41H,A        //分离两位温度值的十位(存到B)个位(存到A)
MOV A,#wenduyuzhi
CJNE A,34H,BEED
LJMP FANHUI
BEED:   JNC FANHUI
        CLR P1.0
LCALL DELAY
        CLR C
FANHUI: RET

 //发送一个字节子程序
SEND_BYTE:MOV A,R0
MOV R5,#8
SEN3: CLR C
RRC A
JC SEN1
LCALL WRITE_0
SJMP SEN2
SEN1: LCALL WRITE_1
SEN2: DJNZ R5,SEN3      //循坏8次,发送一个字节
RET

//读一个字节程序
READ_BYTE:MOV R5,#8
READ1: LCALL READ
RRC A
DJNZ R5,READ1
MOV R0,A
RET

//复位程序
RSTSNR: SETB DAT           //拉高DQ
NOP
NOP
CLR DAT            //拉低DQ 600
μs
MOV R6,#250
DJNZ R6,$
MOV R6,#50
DJNZ R6,$
            SETB DAT                                                     //释放DQ
MOV R6,#15
DJNZ R6,$
lCALL CHCK            //调用应答回应判断程序
MOV R6,#60
DJNZ R6,$
SETB DAT
RET

CHCK: MOV C,DAT              //进位标志位
JC RST0            //DAT为1 跳转
SETB F0            //DAT为0 应答信号 置位 F0
SJMP CHCK0
RST0:  CLR F0            //为准备好 F0复位
CHCK0: RET

//写0程序
WRITE_0:CLR DAT
MOV R6,#30
DJNZ R6,$
SETB DAT
RET
//写1程序
WRITE_1:CLR DAT
NOP
NOP
NOP
NOP
NOP
SETB DAT
MOV R6,#30
DJNZ R6,$
RET

//读一位数据
READ: SETB DAT     //产生读时序
NOP
NOP
CLR DAT
NOP
NOP
SETB DAT     //置位DAT准备接受数据
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,DAT
MOV R6,#23
DJNZ R6,$
RET
DELAY:
       SETB TR1
MOV 35H,#5
JISHI: CLR TF1
       MOV TH1,#0D8H
MOV TL1,#0F0H
JNB TF1,$
       DJNZ 35H,JISHI
       SETB P1.0     
NOP
CLR TR1
SETB EA
RET
DELAY_10MS:
       SETB TR1
       MOV TH1,#0D8H
MOV TL1,#0F0H
JNB TF1,$
CLR TF1
CLR TR1
RET
END
 

物联沃分享整理
物联沃-IOTWORD物联网 » 使用汇编语言实现的单片机高温报警系统温度检测方案

发表评论