给你个参考程序,是我自己做测试的,做了上下限温度报警限制。看不清你的硬件接线,可根据自己改下引脚。
/********************************************************************************
;温度传感器在P3.6
;数据经P0.0~3输出到译码器,位数选择经P0.4~7输出到译码器
********************************************************************************/
Start_NUM_Byte EQU 50H
Temp_LByte EQU 40H
Temp_HByte EQU 41H
TemperatureI EQU 62H
TemperatureD EQU 63H
TemperatureMAXI EQU 64H
TemperatureMAXD EQU 66H
TemperatureMINI EQU 67H
TemperatureMIND EQU 68H
Temp_COMP_Tag EQU 20H.1
Exist_Tag EQU 20H.0
BEEP_Bit bit P3.7
TEMP_PIN bit P3.6
DISP_PORT EQU P0 ;高4位为数码管位数
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TIMER0
ORG 0080H
;--------------------------------------------------
MAIN:
;LCALL Test_Bit
;LCALL Test_NUM
MOV TemperatureMAXI,#30 ;温度设定25.5<=正常<=30.5
MOV TemperatureMAXD,#50
MOV TemperatureMINI,#25
MOV TemperatureMIND,#50
;LCALL SetNum
;AAA5:LCALL DispNum
;AJMP AAA5
;AJMP AAA
LCALL Open_Timer0Int
AAA:
LCALL Read_Temperature
JMP AAA
;*****定时器0中断服务********************************************************
Open_Timer0Int:
MOV TMOD,#01H
MOV TH0,#LOW(65536-10000) ; TH0=(65536-10000) mod 256
MOV TL0,#HIGH(65536-10000) ; TL0=(65536-10000) / 256 ,从55536向上计数10000次
SETB ET0
SETB TR0
SETB EA
RET
TIMER0:
ACALL DispNUM
MOV TH0,#LOW(65536-10000) ;定时器10MS中断
MOV TL0,#HIGH(65536-10000)
CLR EA
JNB Temp_COMP_Tag, No_Alarm
MOV A,#13H
ACALL Beep
CLR Temp_COMP_Tag
No_Alarm:
SETB EA
RETi
;*****温度传感器********************************************************
Trans_Temperature:
MOV R0,#Start_NUM_Byte
MOV A,Temp_LByte
ANL A,#0F0H
MOV 3AH,A
MOV A,Temp_HByte
ANL A,#0FH
ORL A,3AH
SWAP A
MOV B,#10
DIV AB
MOV @R0,A
INC R0
MOV @R0,B
INC R0
MOV DPTR,#TABB
MOV A,Temp_LByte
ANL A,#0FH
MOV B,#2
MUL AB
MOVC A,@A+DPTR
MOV @R0,A
INC R0
MOV A,Temp_LByte
ANL A,#0FH
MOV B,#2
MUL AB
INC A
MOVC A,@A+DPTR
MOV @R0,A
INC R0
MOV @R0,#0F0H
ACALL Get_Temp_Value
ACALL CompareTemp
RET
TABB: DB 0,0,0,6,1,2,1,8,2,5,3,1,3,7,4,3,5,0
DB 5,6,6,2,6,8,7,5,8,1,8,7,9,3
/*将温度转换成10进制数, TemperatureI为整数部分,TemperatureD为小数部分*/
Get_Temp_Value:
MOV R0,#Start_NUM_Byte
MOV A,@R0
MOV B,#10
MUL AB
MOV TemperatureI,A
INC R0
MOV A,@R0
ADD A,TemperatureI
MOV TemperatureI,A
INC R0
MOV A,@R0
MOV B,#10
MUL AB
MOV TemperatureD,A
INC R0
MOV A,@R0
ADD A,TemperatureD
MOV TemperatureD,A
RET
CompareTemp:
CLR Temp_COMP_Tag
CLR C
MOV R1,TemperatureI
MOV A,TemperatureMAXI
SUBB A, TemperatureI
JC SET_COMP_TAG
; AJMP Exit_Comp_88
JZ COMP_MAX_D
AJMP COMP_MIN_I
COMP_MAX_D:
CLR C
MOV A,TemperatureMAXD
SUBB A, TemperatureD
JC SET_COMP_TAG
COMP_MIN_I:
MOV A,TemperatureI
SUBB A, TemperatureMINI
JC SET_COMP_TAG
JZ COMP_MIN_D
AJMP Exit_Comp_88
COMP_MIN_D:
MOV A,TemperatureD
SUBB A, TemperatureMIND
JC SET_COMP_TAG
AJMP Exit_Comp_88
SET_COMP_TAG:
SETB Temp_COMP_Tag
Exit_Comp_88:
RET
/*-------------------------------
读:在A中 写:在A中 检查F0,F0==1则无设备
*-------------------------------*/
Read_Temperature:
CLR EA ;屏蔽中断
LCALL Check_Exist
JB Exist_Tag,EXIT_READ ;如果没有应答,返回主程序
MOV A,#0CCH
LCALL Send_Byte ;跳过ROM匹配
MOV A,#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 Check_Exist
JB Exist_Tag,EXIT_READ
MOV A,#0CCH ;跳过ROM匹配
LCALL Send_Byte
MOV A,#0BEH ;发出读温度命令
LCALL Send_Byte
LCALL Read_Byte
MOV Temp_LByte,A
LCALL READ_BYTE
MOV Temp_HByte,A
LCALL Trans_Temperature
EXIT_READ:
SETB EA
RET
/*----------------------------------
18B20由低电平触发,所以主机平常保持高电平
主机下拉480~960us,然后上拉后延时等待15~60us,然后检测总线是否被下拉,
如果下拉,则表示有设备,18B20下拉信号后会延时60~240us。
--------------------------------*/
Check_Exist:
SETB TEMP_PIN
NOP
NOP
CLR TEMP_PIN
MOV R6,#250 ;主机发复位脉冲:MOV:2周期,DJNZ:2周期, 2+2*250+2+2*48=600us
DJNZ R6,$
MOV R6,#48
DJNZ R6,$
SETB TEMP_PIN ;主机释放总线,口线改为输入
MOV R6,#35 ;延时 2+2*35=72us, 18B20会在60us内作出响应
DJNZ R6,$
MOV C,TEMP_PIN ; 将状态保存,F0==0则无设备
MOV Exist_Tag,C
MOV R6,#120 ;延时 2+2+2*120=244us 等待18B20释放总线,否则有可能被重新拉低
DJNZ R6,$
SETB TEMP_PIN
RET
;==========================================================
;重新对 DS18B20 初始化
;将设定的温度报警值写入 DS18B20
;==========================================================
SetTempAlarmValue:
ACAll Check_Exist
JB Exist_Tag,EXIT_SetValue2
MOV A,#0CCH ;跳过ROM匹配
LCALL Send_Byte
MOV A,#4EH ;写暂存寄存器
LCALL Send_Byte
MOV A,#88H ;TH(报警上限)
LCALL Send_Byte
MOV A,#08H ;TL(报警下限)
LCALL Send_Byte
MOV A,#7FH ;12位精确度
LCALL Send_Byte
EXIT_SetValue2:
RET
/*-------------------------------
发送一个字节程序,字节放在A中
带进位位的右移,每移1位到C中,就将C中的1位数据发送出去
--------------------------------*/
Send_Byte:
PUSH B
MOV B,#8
START_A_BIT:
RRC A
ACALL WriteABit
DJNZ B,START_A_BIT
POP B
RET
/*-------------------------------
写一位, 下降沿触发18B20接收1位,主机在下降沿之后的15us内必须把数据放到总线上,
18B20会在15~60us内采样数据,所以主机必须保持信号持续75us以上,再次发送一位就再次上拉下降
如果主机一直下拉480us,则会产生复位信号。所以
PIN = 1;PIN = 0;Delay = 5~10us ----开始
PIN = 0/1(data);Delay = 70us ---输出
Delay = 2us ---保持>1us间隙发送下1位
--------------------------------*/
WriteABit:
PUSH B
CLR TEMP_PIN ; 写开始
MOV B,#3 ; 2+3*2 = 8us
DJNZ B,$
MOV TEMP_PIN,C ;C内容到总线
MOV B,#28 ;等待56Us
DJNZ B,$
POP B
SETB TEMP_PIN ;释放总线
RET
/*-------------------------------
读1位, 15us内由下降、上升沿两个信号触发读
PIN =0;Delay = 5~10us, PIN = 1; ----开始
PIN = 0/1(data);Delay = 70us ---输出
Delay = 2us ---保持>1us间隙发送下1位
--------------------------------*/
Read_Byte: ;读一个字节程序
MOV R5,#8
READ_A_BIT:
LCALL ReadABit
RRC A
DJNZ R5,READ_A_BIT
RET
ReadABit:
PUSH B
PUSH ACC
SETB TEMP_PIN ;先复位至少1US产生读起始信号
NOP
NOP
CLR TEMP_PIN
NOP
NOP
SETB TEMP_PIN ;置位DAT准备接收数据
MOV B,#10 ;等待数据准备好(60us内) 2+10*2 = 22us
DJNZ B,$
MOV C,TEMP_PIN
MOV B,#15 ;等待32us + 10 + 22 + 2=总66us
DJNZ B,$
SETB TEMP_PIN
POP ACC
POP B
RET
;*********数码管********************************************************
/*--------------------------------------------
dispNum
*---------------------------------------------*/
DispNum:
MOV R0,#Start_NUM_Byte
MOV R1,#0H
ST_NUM_Dsp:
MOV A,@R0 ;从Start_NUM_Byte开始读取数据,如果高字节大于0则结束。
MOV R5,A ;用R5暂时保存数据,然后获取高4位,低4位input R5
ANL A,#0F0H
JNZ EXIT_DSP
MOV A, R5
ANL A,#0FH
SWAP A
ORL A,R1
SWAP A
MOV DISP_PORT,A ;开始显示数据,
ACALL T1MS
INC R1
INC R0
AJMP ST_NUM_Dsp
EXIT_DSP:
RET
T1MS: mov r5,#00h ;延时子程序
tt889: mov r6,#9
djnz r6,$
djnz r5,tt889
ret
/*--------------------------------------------
test Bit
*---------------------------------------------*/
Test_bit:
MOV A,#11111110b
TTT:MOV P0,A
RL A
ACALL DELAY
AJMP TTT
RET
/*--------------------------------------------
SetNum
*---------------------------------------------*/
SetNum:
MOV R0,#Start_NUM_Byte
MOV @R0,#01H
INC R0
MOV @R0,#02H
INC R0
MOV @R0,#03H
INC R0
MOV @R0,#0CH
INC R0
MOV @R0,#05H
INC R0
MOV @R0,#0F0H
RET
/*--------------------------------------------
Test Num
*---------------------------------------------*/
Test_NUM:
MOV R0,#0
MOV DPTR,#Num_TABLE
TTT_NUM:
MOV A,R0
MOVC A,@A+DPTR
JNZ Next_NUM
MOV R0,#0
AJMP TTT_NUM
Next_NUM:
MOV P0,A
inc R0
ACALL DELAY
AJMP TTT_NUM
RET
;-------------------------------------------------------
DELAY:
MOV R5, #10
DEL1: MOV R7,#200
DEL2: MOV R6,#200
DJNZ R6,$
DJNZ R7,DEL2
DJNZ R5,DEL1
RET
/*----------------------------------
Beep:时间参数在A中,时间为A*256*256*12/f
f(时钟频率),输出引脚在头部定义
A中低4位为延时,高4位为声音频率 0=高音,1=中;2=高
------------------------------------*/
BEEP:
PUSH 05h
PUSH 06h
PUSH 07h
MOV R5,A
ANL A,#0FH
XCH A,R5
ANL A,#0F0H
SWAP A
BEEP_1: MOV R6,#050H
BEEP_2: MOV R7,#05FH
BEEP_3:
CJNE A,#0, NextF1
CPL BEEP_Bit
NextF1:
DJNZ R7,BEEP_3
CJNE A,#1, NextF2
CPL BEEP_Bit
NextF2:
DJNZ R6,BEEP_2
CJNE A,#2, NextF3
CPL BEEP_Bit
NextF3:
DJNZ R5,BEEP_1
POP 07h
POP 06h
POP 05h
RET
;-------------------------------------------------------
Num_TABLE:
DB 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h,00H
;DB 00101000b,01111110b,10100010b,01100010b,01110100b,01100001b,00100001b,01111010b,00100000b,01100000b,00H
;-------------------------------------------------------
END
温馨提示:内容为网友见解,仅供参考