使用汇编语言实现的单片机高温报警系统温度检测方案
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中编制汇编语言源程序,调试实现要求功能,生成可 执行程序;
5) 提交 Keil μVision 程序、Proteus ISIS 设计文件、实验报告。
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:四位二进制的七段数码管编码器
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,再进行读写。
只有在读时段期间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
ROM操作指令
首先根据F0判断DS18B20是否存在。不存在跳回主程序,存在则写0CCH入DS18B20跳过ROM指令,然后写44H,使DS18B20温度转换。然后读时序,先复位,然后写入0CCH跳过ROM,然后写0BEH读暂存器内容。
数据处理
读取数据后,对数据进行处理,只取整数部分,将读出的高位与地位相结合后处理为一个八位二进制的数。随后对其除以10取余得到十位与各位数字,分别用四位二进制表示。
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
温度显示
dsl: MOV P0,43H //温度的低位数据传送到P0
ORL P0,#00010000B //选通P0.4,控制低位数码管显示
kkk: //求反
RETI //中断返回
超温检测
在温度转化完成后,将数据存储在34H,将软件中设置的温度阈值与之相比较,利用CJNE与JNC指令来完成比较大小操作,达到在温度超过温度阈值时,P1.0置1,蜂鸣器报警操作。
1)DS18B20对于数据的读取、检测等方式讲究严格的时序,在编写程序的过程中,需要考虑好相应指令所需的机器周期,以及进行相应的延时操作来读写数据。我再实验过程中尤其是读取DS18B20传输过来的数据时,最开始一直不对,根本原因就是时序延时没有掌握好,掌握好延时和时序后,就能够顺利读取数据。
2)在对DS18B20操作时需要,讲究遵守规则,需要先复位,跳过 ROM,才能进行读写,更改初值等操作。在编写代码的过程中,需要严格历经这三个过程,不要漏步跳步。
3)动态数码管的温度显示要求时刻不断对数码管有数据输入,不能延迟太大导致肉眼可见的掉帧现象,将显示函数写入函数放在10ms一次的定时器中断当中,完成10ms刷新一次的功能。
4)DS18B20的温度数据传入或给温度传感器的写入都是从地位开始输出,在调试过程中没有注意到这个问题导致,温度读取的数据一直有错误,一直到重新看了一边DS18B20后注意到这个细节,专门写了一个输入和读取函数,与RRC指令相配合达到正确输入和读取数据。
代码
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