单片机数字温度计设计

基于89c51和ds18b20,proteus仿真最好有.dsn以及.hex文件打包
2024-11-02 07:41:38
推荐回答(1个)
回答1:

;调试成功,还能凑合用
;有什么具体的设计要求请说明,现场改。protues电路图,联系zxcscm@sina.com
DATA_BUS BIT P1.2
FLAG BIT 00H
NEG BIT 01H
TURN BIT 02H
TEMP_L EQU 30H
TEMP_H EQU 31H
TEMP_DP EQU 32H
TEMP_INT EQU 33H
TEMP_BAI EQU 34H
TEMP_SHI EQU 35H
TEMP_GE EQU 36H
T_UP EQU 37H
T_DOWN EQU 38H
MARK EQU 39H
DIS_DP EQU 3AH
DIS_ADD EQU 3BH
KEY_HUAN BIT P3.0
KEY_A BIT P3.1
KEY_D BIT P3.2

ORG 0000H
AJMP START

ORG 0040H
START:
MOV SP, #50H
MOV P2,#00H; 先关闭所有数码管 共阴则 MOV P2, #0FFH
CLR FLAG
CLR NEG
CLR TURN ;按键转换标志,只有转换按键按过,再按其他的键才能调整温度。
MOV T_UP,#60H ;初始化温度上限
MOV T_DOWN,#30H ;初始化温度下限
MOV MARK,#00H ;当前显示数值的标志。0显示当前温度,1显示并调节最高温度,2显示并调节最低温度。
MOV TEMP_DP, #08H
MOV TEMP_BAI, #08H
MOV TEMP_SHI, #08H
MOV TEMP_GE, #08H
LCALL DISPLAY
MAIN:
LCALL READ_TEMP
LCALL PROCESS
LCALL KEYSCAN
LJMP MAIN

;读温度程序
READ_TEMP:
LCALL RESET_PULSE ;18B20初始化,对18B20的每一个读写操作都是从初始化开始的。
MOV A, #0CCH ;指令0CCH 跳过读ROM,至于为什么看看DS18B20的中文资料就知道了。
LCALL WRITE ;往18B20写指令
MOV A, #44H ;指令44H 温度变换。
LCALL WRITE
LCALL DISPLAY ;调用显示
LCALL RESET_PULSE ;18B20初始化
MOV A, #0CCH
LCALL WRITE
MOV A, #0BEH ;0BEH 读暂存存储器
LCALL WRITE ;先写“读温度”指令
LCALL READ ;再读温度值
RET

;复位脉冲程序

;/*--------------------------------------------------------------------------------------------------------------------
; 时序:初始化时序、读时序、写时序。
;
;初始化:检测总线控制器发出的复位脉冲
;
;和ds18b20的任何通讯都要从初始化开始
;
;初始化序列包括一个由总线控制器发出的复位脉冲
;
;和跟在其后由从机发出的存在脉冲。
;
;始化:复位脉冲+存在脉冲
;
;具体操作:
;
;总线控制器发出(TX)一个复位脉冲 (一个最少保持480μs 的低电平信号),然后释放总线,
;
;进入接收状态(RX)。单线总线由5K 上拉电阻拉到高电平。探测到I/O 引脚上的上升沿后
;
;DS1820 等待15~60μs,然后发出存在脉冲(一个60~240μs 的低电平信号)。
;
;具体看" 18b20"文档里的 " 单线复位脉冲时序和1-wire presence detect "的时序图
;对着18B20的复位时序图就看明白了
;--------------------------------------------------------------------------------------------------------------------*/
;
RESET_PULSE:
RESET: SETB DATA_BUS
NOP
NOP
CLR DATA_BUS
MOV R7, #255
DJNZ R7, $
SETB DATA_BUS
MOV R7, #30
DJNZ R7, $
JNB DATA_BUS, SETB_FLAG
CLR FLAG
AJMP NEXT
SETB_FLAG:
SETB FLAG
NEXT: MOV R7, #120
DJNZ R7, $
SETB DATA_BUS
JNB FLAG, RESET
RET

;写命令 同样对着写时序图看
WRITE: SETB DATA_BUS ;数据线置1
MOV R6, #8
CLR C
WRITING:
CLR DATA_BUS
MOV R7, #5
DJNZ R7, $
RRC A
MOV DATA_BUS, C
MOV R7, #30H
DJNZ R7, $
SETB DATA_BUS
NOP
DJNZ R6, WRITING
RET

;读命令

READ: SETB DATA_BUS
MOV R0, #TEMP_L
MOV R6, #8
MOV R5, #2
CLR C
READING:
CLR DATA_BUS
NOP
NOP
SETB DATA_BUS
NOP
NOP
NOP
NOP
MOV C, DATA_BUS
RRC A
MOV R7, #30H
DJNZ R7, $
SETB DATA_BUS
DJNZ R6, READING
MOV @R0, A
INC R0
MOV R6, #8
SETB DATA_BUS
DJNZ R5, READING
RET

;循环显示段位
DISPLAY:
MOV R4, #50

DIS_LOOP:
MOV P2,#00H
MOV A, TEMP_DP
MOV DPTR, #TABLE_DP ;真不知这TABLE_DP能干什么,不显示负号时加上后还会显示255.9.
MOVC A, @A+DPTR ;现在看来必须得加上他,否则添加了负号处理并显示后会间歇性的显示-01.8. 很奇怪这是为什么
MOV DPTR, #TABLE_INTER
MOVC A, @A+DPTR
MOV P0, A
SETB P2.3
LCALL D1MS
CLR P2.3

MOV A, TEMP_GE
MOV DPTR, #TABLE_INTER
MOVC A, @A+DPTR
MOV P0, A
CLR P0.7
SETB P2.2
LCALL D1MS
CLR P2.2

MOV A, TEMP_SHI
MOV DPTR, #TABLE_INTER
MOVC A, @A+DPTR
MOV P0, A
SETB P2.1
LCALL D1MS
CLR P2.1

JNB NEG,BAI
MOV A,#0BFH
MOV P0,A
SETB P2.0
LCALL D1MS
CLR P2.0
;AJMP NEXTT

BAI: MOV A, TEMP_BAI
CJNE A, #0, SKIP
AJMP NEXTT
SKIP: MOV A, TEMP_BAI
MOV DPTR, #TABLE_INTER
MOVC A, @A+DPTR
MOV P0, A
SETB P2.0
LCALL D1MS
CLR P2.0
NEXTT: NOP
DJNZ R4, DIS_LOOP
RET

KEYSCAN:
JB KEY_HUAN,KEY2
LCALL D2MS
JB KEY_HUAN,KEY2
CPL TURN
INC MARK
MOV A,MARK
CJNE A,#03H,KEY2
MOV MARK,#00H

KEY2: JNB TURN, OVER

JB KEY_A,KEY3
LCALL D2MS
JB KEY_A,KEY3
MOV A,MARK
CJNE A,#01H,N1
INC T_UP
N1: MOV A,MARK
CJNE A,#02H,OVER
INC T_DOWN

KEY3: JB KEY_D,OVER
LCALL D2MS
JB KEY_D,OVER
MOV A,MARK
CJNE A,#01,N2
DEC T_UP
N2: MOV A,MARK
CJNE A,#2,OVER
DEC T_DOWN
OVER:
RET

/* ------------------------------------------------------------------------------------------
当温度转换命令发布后,经转换所得的温度值以二字节补码的形式存放在高速暂存存储器的第0、1个字节。
;单片机可通过单线接口读到该数据,读取时低位在前,高位在后。
;对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。
;数据处理
--------------------------------------------------------------------------------------------*/
PROCESS:
MOV A,MARK
CJNE A,#01H,TP1
MOV A,T_UP
AJMP SEP
TP1:MOV A,MARK
CJNE A,#02H,TP2
MOV A,T_DOWN
AJMP SEP
TP2: MOV R7, TEMP_L ;取二进制温度最低四位,即温度的小数位。
MOV A, #0FH
ANL A, R7
MOV TEMP_DP,A ;小数位存到TEMP-DP中。

MOV R7, TEMP_L ;取二进制温度整数部分低四位。
MOV A, #0F0H
ANL A, R7
SWAP A
MOV TEMP_L, A

MOV R7, TEMP_H ;取二进制温度整数部分高四位
MOV A, #0FH
ANL A, R7
SWAP A
ORL A, TEMP_L ;温度的整数位在A,
MOV TEMP_L,A ;暂存当前温度值

;比较温度是否超过报警温度。
CJNE A,T_UP,NEQ1
NEQ1: JC NUP
CLR P3.3
AJMP TP
NUP:SETB P3.3
MOV A,TEMP_L
CJNE A,T_DOWN,NEQ2
NEQ2: JNC NDOWN
CLR P3.4
AJMP TP
NDOWN:SETB P3.4

TP: MOV A,TEMP_L
MOV R7, #80H ;判断是否为负数。即温度是否为零下
ANL A, R7
CJNE A, #00H,NG
CLR NEG
MOV A,TEMP_L
AJMP SEP
NG: SETB NEG
MOV A,TEMP_L
CPL A
INC A

SEP:
MOV B, #64H
DIV AB ;
MOV TEMP_BAI,A
MOV A, #0AH
XCH A, B
DIV AB
MOV TEMP_SHI,A
MOV TEMP_GE,B

RET

D1MS:
MOV R7,#250
DJNZ R7,$
RET

D2MS:
MOV R6, #3
LOOP3: MOV R5, #250
DJNZ R5, $
DJNZ R6, LOOP3

RET

TABLE_DP:
DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H

TABLE_INTER:
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H

END