求~~用51单片机+DS18B20+蜂鸣器做出的温度报警器仿真图.

2024-12-13 06:39:15
推荐回答(3个)
回答1:

用AVR单片机加个IN4148的两极管,再加一些电路就能做成一个测温电路,很简单,精度也可以,至于报警电路与程序不用让别人再替你做了吧,你查查有关资料就可以了,成本低,又能达到要求,何乐而不为呢

回答2:

单片机7元,DS18B20 10元,蜂鸣器 1元,总成本在20元左右。
程序就不帮你写了,这个不是一时半会能搞好的,有问题可以问,最好别像这样动不动就出个大题目让别人帮你,没人稀罕这些积分的。
学习是自己的事!

回答3:

程序自己修改:
;***************WAVE-E6000/T**********************
;*MCU: AT892051 *
;*MCU-crystal: 12M *
;*Version: 01 *
;*Last Updata: 2007-6-3 *
;*Author: zhaojun *
;*Description: *
;DS18B20的读写程序,数据脚P3.4 *
;显示数据通过P1口传输,P3.0控制小数位的显示 *
;P3.1控制个位的显示,P3.2控制十位的显示 *
;P3.3控制百位的显示,P1.7控制小数点的显示 *
;温度传感器18B20汇编程序,采用器件默认的12位转化 *
;最大转化时间750微秒,显示温度-55到+125度,显示精度*
;为0.1度,显示采用4位LED共阳显示测温值 *

;*************************************************
;单片机内存分配申明!
;*************************************************
TEMPER_L EQU 40H ;用于保存读出温度的低8位
TEMPER_H EQU 41H ;用于保存读出温度的高8位

FLAG1 EQU 38H ;是否检测到DS18B20标志位
TEMPL EQU 30H ;用于保存读出正确温度值的低8位
TEMPH EQU 31H ;用于保存读出正确温度值的高8位
TEMPHC EQU 32H ;温度转换寄存器低8位
TEMPLC EQU 33H ;温度转换寄存器高8位

BUF1 EQU 34H ;显示缓冲寄存器小数位
BUF2 EQU 35H ;显示缓冲寄存器个数位
BUF3 EQU 36H ;显示缓冲寄存器十数位
BUF4 EQU 37H ;显示缓冲寄存器百数位

TEMPDIN BIT P3.4 ;数据脚定义
DIN BIT P1.7 ;小数点控制
;**********************************************

ORG 0000H ;主程序入口地址
AJMP MAIN ;转主程序
ORG 0003H ;外中断0中断入口
DB 00H,00H,00H,00H,00H,00H,00H;
RETI ;跳至INTEX0执行中断服务程序
ORG 000BH ;定时器T0中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至定时器T0执行中断服务程序
ORG 0013H ;外中断1中断入口
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至INTEX1执行中断服务程序
ORG 001BH ;定时器T1中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中断返回(不开中断)
ORG 0023H ;串行口中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中断返回(不开中断)
;**********************************************
;两位数码管来显示温度,显示范围00到99度,显示精度为1度
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
;无需乘于0.0625系数
;**********************************************
MAIN:
MOV SP, #50H ;设置堆栈
MOV P1, #0FFH ;

LPTEMP:
LCALL GET_TEMPER ;调用读温度子程序
LCALL CONVTEMP ;温度BCD码计算处理子程序
LCALL DISPBCD ;显示区BCD码温度值刷新子程序
;*************************************
LCALL DISPLAY ;调用数码管显示子程序
;*************************************
;CPL P3.5 ;
AJMP LPTEMP ;循环
;*************************************
; 这是DS18B20复位初始化子程序
;*************************************
INIT_1820:
SETB TEMPDIN
NOP
CLR TEMPDIN ;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:
MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB TEMPDIN ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H ;延时
TSR2:
JNB TEMPDIN,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ;DS1820不存在
TSR3:
SETB FLAG1 ;置标志位,表示DS1820存在
;CLR P3.7 ;检查到DS18B20就点亮P3.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ;清标志位,表示DS1820不存在
;CLR P3.1
LJMP TSR7
TSR5: MOV R0,#117
TSR6: DJNZ R0,TSR6 ;时序要求延时一段时间
TSR7: SETB TEMPDIN ;结束
RET
;****************************************
; 读出转换后的温度值
;****************************************
GET_TEMPER:
SETB TEMPDIN ;
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
;CLR P3.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
RET
;*******************************************
;写DS18B20的子程序(有具体的时序要求)
;*******************************************
WRITE_1820:
MOV R2,#8 ;一共8位数据
CLR C ;C清0
SETB TEMPDIN ;/
NOP ;/
NOP ;/
WR1:
CLR TEMPDIN ;
MOV R3,#6 ;延时
DJNZ R3,$
RRC A ;数据右移
MOV TEMPDIN,C ;写入一位数据
MOV R3,#23 ;延时
DJNZ R3,$
SETB TEMPDIN ;拉高数据端口
NOP
DJNZ R2,WR1 ;判断是否写完
SETB TEMPDIN ;拉高数据端口
RET
;*************************************
;处理温度BCD码子程序
;*************************************
CONVTEMP:
MOV A,TEMPH ;
ANL A,#80H ; 判断最高位
JZ TEMPC1 ; 判断温度是否在零下?

CLR C ; 温度值补码 变成原码
MOV A,TEMPL ;
CPL A
ADD A,#01H ;
MOV TEMPL,A ;
MOV A, TEMPH ; -
CPL A ;
ADDC A,#00H ;
MOV TEMPH,A ; TEMPHC HI=符号位
MOV TEMPHC,#0BH ; 置"-"标志
SJMP TEMPC11 ;
TEMPC1: MOV TEMPHC,#0AH ; 置"+"标志 不显示
;**************************************
TEMPC11: MOV A,TEMPHC ; 计算小数位温度BCD值
SWAP A
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ; 乘0.0625
MOV DPTR,#TEMPDOTTAB ;
MOVC A,@A+DPTR ;
MOV TEMPLC,A ; TEMPLC LOW= 小数部分 BCD
;**************************************
MOV A,TEMPL ; 计算整数位温度BCD值
ANL A,#0F0H ;
SWAP A ;
MOV TEMPL,A ;
MOV A,TEMPH ;
ANL A,#0FH ;
SWAP A ;
ORL A,TEMPL ;
MOV TEMPER_L ,A ;//
LCALL HEX2BCD1 ; 调用单字节十六进制转BCD子程序
;************************************
MOV TEMPL,A ;
ANL A,#0F0H ;
SWAP A ;
ORL A,TEMPHC ; TEMPHC LOW = 十位数 BCD
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ;
SWAP A ; TEMPLC HI = 个位数 BCD
ORL A,TEMPLC ;
MOV TEMPLC,A ;
MOV A,R7 ;
JZ TEMPOUT ;
ANL A,#0FH ;
SWAP A ;
MOV R7,A ;
MOV A,TEMPHC ; TEMPHC HI = 百位数 BCD
ANL A,#0FH ;
ORL A,R7 ;
MOV TEMPHC,A ;
TEMPOUT: RET ;
;**************************************
;小数部分分码表
;**************************************
TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H ;

;**************************************
;显示区 BCD 码温度值刷新子程序
;**************************************
;温度暂存器内的2字节中,高字节的低半字节和低字节的高半字节组成一个字节,
;这个字节的二进制值转换为十进制后,就是温度值的百、十、个位值,而剩下的低字节化为
;十进制后,就是温度值的小数部分.
;**************************************
DISPBCD:
MOV A,TEMPLC ; 温度数据移入显示寄存器
ANL A,#0FH ; 取低字节的低4位(小数部分)
MOV BUF1,A ; 小数部分放入寄存器
MOV A,TEMPLC ; 取低字节的高4位(个位数)
SWAP A ;
ANL A,#0FH ;
MOV BUF2,A ; 个位数放入寄存器

MOV A,TEMPHC ; 取高字节的低4位(十位数)
ANL A,#0FH ;
MOV BUF3,A ; 十位数放入寄存器
MOV A,TEMPHC ; 取高字节的高4位(百位数)
SWAP A ;
ANL A,#0FH ;
MOV BUF4,A ; 百位数放入寄存器

MOV A,TEMPHC ;
ANL A,#0F0H ;
CJNE A,#10H,DISPBCD0 ; 百位数=0?
SJMP DISPOUT ;
;*************************************
;最高位为0和正数的符号位都不显示
;*************************************
DISPBCD0:
MOV A,TEMPHC ;
ANL A,#0FH ;
JNZ DISPOUT ; 十位数是0?
MOV A,TEMPHC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF4,0AH ; 符号位不显示
MOV BUF3,A ; 十位数显示符号
DISPOUT: RET ;
;*************************************
;单字节十六进制转BCD
;*************************************
HEX2BCD1:MOV B,#64H ; 十六进制 ->BCD
DIV AB ; B=A%100
MOV R7,A ; R7=百位数
MOV A,#0AH ;
XCH A,B ;
DIV AB ; B=A%B
SWAP A ;
ORL A,B ;
RET ;
;*************************************
; Calculate CRC-8 Values, Uses The
; CCITT-8 Polynomial,Expressed As
; X^8+X^5+X^4+1
;CRC8 = X8+X5+X4+1

;X8 表示第7位需要异或运算
;X5 表示第4位需要异或运算
;X4 表示第3位需要异或运算
;1 表示第0位需要异或运算

;*************************************
CRC8CAL:
PUSH ACC ;
MOV R7,#08H ; Number Bits Byte
CRC8LOOP1:
XRL A,B ; Calculate CRC
RRC A ; Move T0 Carry
MOV A,B ; Get The Last CRC Value
JNC CRC8LOOP2 ; Skip If Data==0
XRL A,#18H ; Update The CRC Value
CRC8LOOP2:
RRC A ; Position The New CRC
MOV B,A ; Store The New CRC
POP ACC ; Get The Remaining Bits
RR A ; Possition The Next Bit
PUSH ACC ; Save The Remaining Bits
DJNZ R7,CRC8LOOP1 ; Repeat For 8 Bits
POP ACC ;
RET ;
;******************************************
;读DS18B20的程序,从DS18B20中读出9个字节数据
;开始的两个字节为温度数据
;******************************************
READ_18200:
MOV R4,#9 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TEMPER_L ; 低位存入40H(TEMPER_L),高位存入41H(TEMPER_H)
MOV B, #00H ;
;************************************
RE00:
MOV R2,#8 ; 数据一共有8位
RE01:
CLR C
SETB TEMPDIN ; 拉高数据端口
NOP
NOP
CLR TEMPDIN ; 拉低数据端口
NOP
NOP
NOP

SETB TEMPDIN ;
MOV R3,#9 ; 延时
RE10:
DJNZ R3,RE10 ;
MOV C,TEMPDIN ; 读出数据
MOV R3,#23 ; 延时
RE20:
DJNZ R3,RE20 ;
RRC A ; 数据右移一位
DJNZ R2,RE01 ; 是否读完一个字节?
;************************************
MOV @R1,A ;
INC R1 ; 读下一字节
LCALL CRC8CAL ; 数据验证
DJNZ R4,RE00 ; 9字节数据是否读完?
MOV A,B ; 验证数据放入A中
JNZ READ_OUT ; 验证出错则不改变温度值

MOV TEMPL,TEMPER_L ; 温度数据的低字节放入寄存器
MOV TEMPH,TEMPER_H ; 温度数据的高字节放入寄存器
READ_OUT: RET
;*****************************************
;显示子程序
;*****************************************
DISPLAY:
MOV DPTR,#NUMTAB ; 指定查表启始地址
MOV R0,#4 ; 显示4位数据
DP11: MOV R1,#250 ; 显示1000次

DPLP: SETB P1.7 ; 小数点不亮
MOV A,BUF1 ; 取小位数
MOVC A,@A+DPTR ; 查小位数的7段代码
MOV P1,A ; 送出小位的7段代码
CLR P3.0 ; 开小位显示
ACALL DL1ms ; 显示1ms
SETB P3.0 ; 关小数显示

MOV A,BUF2 ; 取个位数
MOVC A,@A+DPTR ; 查个位数的7段代码
MOV P1,A ; 送出个位的7段代码
CLR P1.7 ; 小数点亮
CLR P3.1 ; 开个位显示
ACALL DL1ms ; 显示1ms
SETB P3.1 ; 关个位显示

SETB P1.7 ; 小数点不亮
MOV A,BUF3 ; 取十位数
MOVC A,@A+DPTR ; 查十位数的7段代码
MOV P1,A ; 送出十位的7段代码

CLR P3.2 ; 开十位显示
ACALL DL1ms ; 显示1ms
SETB P3.2 ; 关十位显示

SETB P1.7 ; 小数点不亮
MOV A,BUF4 ; 取百位数
MOVC A,@A+DPTR ; 查百位数的7段代码
MOV P1,A ; 送出百位的7段代码
CLR P3.3 ; 开百位显示
ACALL DL1ms ; 显示1ms
SETB P3.3 ; 关百位显示

DJNZ R1,DPLP ; 250次没完循环
DJNZ R0,DP11 ; 4个100次没完循环
RET
;****************************************
;0.2MS延时(按12MHZ算)
;****************************************
DL1MS: MOV R7,#100
DJNZ R7,$
RET
;****************************************
;7段数码管0~9数字的共阳显示代码
;****************************************
NUMTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH ;
; "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
;****************************************
END