📄 temperature.asm
字号:
;---AT89C2051读DS1820温度程序----
;---AT89C2051读TLC549湿度程序----
;---------2004-06-02---------
REST_ERR BIT 00H ;复位正确否标志位
READ_OK BIT 01H ;读数据正确标志
TEMP_FLG BIT 02H ;读出温度符号标志位
T0_OVER BIT 03H
T1_OVER BIT 04H
LED_IND BIT 05H
RS_REVFA BIT 06H
RS_REVFB BIT 07H
;----------------------------
ALARM_ON BIT 08H
; BIT 09H
; BIT 0AH
; BIT 0BH
; BIT 0CH
; BIT 0DH
; BIT 0EH
; BIT 0FH
;----------------------------
DAT_OUTA BIT P1.1 ;X5045-SO
CLK_A BIT P1.2 ;TLC549-CLK
LED BIT P1.3 ;工作指示
ALM_IN BIT P1.4 ;ALARM_IN
CS_A BIT P1.5 ;TLC549-CS
DAT_OUTB BIT P1.6 ;TLC549_DAT-OUT
MAX485 BIT P1.7 ;RS485-RE/DE
CS_B BIT P3.2 ;X5045-CS
CLK_B BIT P3.3 ;X5045-SCK
DAT_IN BIT P3.4 ;X5045-SI
SER_DAT BIT P3.7 ;DS1820数据线
;----------------------------
TEMPER_DAT DATA 30H
; DATA 31H
; DATA 32H
; DATA 33H
; DATA 34H
; DATA 35H
; DATA 36H
; DATA 37H
; DATA 38H
; DATA 39H
; DATA 3AH
; DATA 3BH
; DATA 3CH
; DATA 3DH
; DATA 3EH
; DATA 3FH
;-----------------------------
SAVE_DAT DATA 40H
COMM_DAT DATA 42H
TACOM DATA 43H
TBCOM DATA 44H
TEM_FDAT DATA 45H ;温度符号位
SER_DATA DATA 46H ;
HUMID_DAT DATA 47H ;温度值
TEMP_DATA DATA 48H ;湿度值
RS_DATA DATA 49H
;------RS232数据缓冲区--------
RS_BUFFER DATA 50H
; DATA 51H
; DATA 52H
; DATA 53H
; DATA 54H
; DATA 55H
; DATA 56H
; DATA 57H
; DATA 58H
; DATA 59H
;----------------------------
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TIME0PR
ORG 0023H
LJMP RS_RECEIVE
ORG 100H
;--------初始化内存单元------
MAIN: MOV A,#00H
MOV R1,#20H
MAINA: MOV @R1,A
INC R1
CJNE R1,#60H,MAINA
CLR MAX485
SETB SER_DAT
MOV RS_BUFFER+0,#0AAH
MOV RS_BUFFER+9,#0BBH
MOV SP,#60H
LCALL RS_SET
SETB LED_IND
LCALL READ_DS1820
LCALL TEMPER_PROG
LCALL HUMID_AD
LCALL SEND_TEMPER
LCALL SEND_HUMID
;----------工作主程序--------
BEGIN00:JNB ALARM_ON,BEGIN01
CLR ALARM_ON
LCALL SEND_ALARM
BEGIN01:JNB T0_OVER,BEGIN02
CLR T0_OVER
LCALL READ_DS1820
SETB TR0
JNB READ_OK,BEGIN02
LCALL TEMPER_PROG
LCALL HUMID_AD
LCALL CLEAR_DATA
BEGIN02:JNB RS_REVFB,BEGIN03
CLR RS_REVFB
MOV A,RS_BUFFER+1
CJNE A,#07H,BEGIN03
LCALL SEND_TEMPER
LCALL DELAY_TIME_A
LCALL DELAY_TIME_A
LCALL SEND_HUMID
BEGIN03:JNB T1_OVER,BEGIN00
CLR T1_OVER
JB LED_IND,BEGIN04
SETB LED_IND
SETB LED
LJMP BEGIN00
BEGIN04:CLR LED
CLR LED_IND
LJMP BEGIN00
;-------------------------------
SEND_TEMPER:
LCALL CLR_BUFFER
MOV RS_BUFFER+1,#02H
MOV RS_BUFFER+2,TEMP_DATA
LCALL RS_SEND_DATA
RET
;-------------------------------
SEND_HUMID:
LCALL CLR_BUFFER
MOV RS_BUFFER+1,#03H
MOV RS_BUFFER+2,HUMID_DAT
LCALL RS_SEND_DATA
RET
;-------------------------------
SEND_ALARM:
LCALL CLR_BUFFER
MOV RS_BUFFER+1,#0CH
LCALL RS_SEND_DATA
LCALL CLR_BUFFER
RET
;------清除已读取的温度数据-----
CLEAR_DATA:
MOV R0,#30H
MOV A,#00H
CLEAR_A:MOV @R0,A
INC R0
CJNE R0,#3AH,CLEAR_A
RET
;--------处理温度数据程序--------
TEMPER_PROG:
MOV A,TEMPER_DAT+1
JNZ TEMPRA
MOV TEM_FDAT,#01H
LJMP TEMPRC
TEMPRA: MOV TEM_FDAT,#00H
MOV A,TEMPER_DAT+0
CPL A
INC A
TEMPRB: MOV B,#02H
DIV AB
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV TEMP_DATA,A
RET
TEMPRC: MOV A,TEMPER_DAT+0
LJMP TEMPRB
;-----------------------------
TRN_DECIMAL:
MOV A,SAVE_DAT+7
MOV R0,SAVE_DAT+6
SUBB A,R0
MOV B,SAVE_DAT+7
DIV AB
RET
;-----------------------------
TEMPER_DIV2:
MOV B,#02H
DIV AB
RET
;-----------------------------
HEX_TOBCD:
MOV B,#10
DIV AB
RET
;-------------------------------
READ_DS1820:
LCALL RESET ;复位DS1820
LCALL TIME_10us
JB REST_ERR,REDS_RET
READ01: MOV COMM_DAT,#0CCH ;给DS1820发SKIP ROM命令
LCALL WRITE_BYTE
LCALL TIME_10us
MOV COMM_DAT,#044H ;给DS1820发转换温度指令,需要一定的时间
LCALL WRITE_BYTE ;才能转换完毕
LCALL D200MS
LCALL D300MS
LCALL RESET ;复位DS1820
LCALL TIME_10us
JB REST_ERR,REDS_RET
READ02: MOV COMM_DAT,#0CCH ;给18B20发SKIP ROM命令
LCALL WRITE_BYTE
LCALL TIME_10us
MOV COMM_DAT,#0BEH ;DS给1820发读温度指令
LCALL WRITE_BYTE
LCALL READ_BYTE ;读DS1820 RAM字节
SETB READ_OK
RET
REDS_RET:
CLR READ_OK
RET
;-------------------------
RESET: CLR SER_DAT ;SER_DAT位数据零
MOV R4,#0AH
RESET_B:LCALL TIME_60us ;复位低电平,480us-960us
DJNZ R4,RESET_B ;预计600us
SETB SER_DAT
ACKN_0: MOV A,#30
ACKN_1: LCALL TIME_02us
JNB SER_DAT,ACKN_2 ;检测SER_DAT位物理电平。为0跳行。
DEC A
JZ ACKN_4 ;若长时间为高,转错误处理。60us的等待
LJMP ACKN_1 ;等待18B20自动变低。发低电平响应脉冲。
ACKN_2: LCALL TIME_02us
JB SER_DAT,ACKN_3 ;等待DS1820的低电平相应脉冲过。此时自动拉高。
LJMP ACKN_2
ACKN_3: LCALL TIME_60us ;等待DS1820的低电平相应脉冲过。此时自动拉高。
CLR REST_ERR
RET
ACKN_4: SETB REST_ERR ;数字温度传感器DS1820损坏标记
RET ;
;----入口参数COMM_DAT=发送的命令字----
WRITE_BYTE:
MOV A,COMM_DAT
LCALL TIME_02us
MOV R4,#08H ;写一个字节8 Bit
NEXT: CLR C
SETB SER_DAT
LCALL TIME_02us
CLR SER_DAT ;起始位
LCALL TIME_02us ;保持低电平大于1uS小于15uS
RRC A ;A= 输出命令字节
MOV P3.7,C
WRITE_1:LCALL TIME_60us ;保持输出60us左右时间。
NOP ;要求持续时间大于60us,小于120us
NOP ;DS1820在低电平后15us-60us对数据进行采样。
WRITE_H:SETB SER_DAT ;回复高电平。准备写下一位数据。
LCALL TIME_02us ;两次写数据之间的时间间隔大于1us
LCALL TIME_02uS
DJNZ R4,NEXT ;8 Bit未发完,继续发送。
RET
;----读出的温度值存入地址30H__39H-----
READ_BYTE:
MOV R0,#30H
SETB SER_DAT
MOV R3,#09H
MOV A,#00H
NEXT_BYTE:
CLR C
MOV R4,#08H ;一个字节8个位
NEXT_BIT:
CLR SER_DAT
LCALL TIME_02us
SETB SER_DAT
LCALL TIME_10us
LCALL TIME_10us
NOP ;等待10个周期
NOP ;在这10个输入周期,DS1820自动拉高
MOV C,P3.7
READ_A: RRC A ;通过进位右循环。读DS1820数据
DJNZ R4,READ_B
LJMP READ_RET
READ_B: LCALL TIME_60us
LJMP NEXT_BIT
READ_RET:
MOV @R0,A ;存读出的DS1820数据
INC R0
LCALL TIME_60us
DJNZ R3,NEXT_BYTE
RET
;----------------------------
TIME_02us:
RET
;----------------------------
TIME_60us:
MOV R2,#08
TIME_B: LCALL TIME_02us
DJNZ R2,TIME_B
NOP
NOP
NOP
RET
;----------------------------
TIME_10us:
MOV R1,#02
DJNZ R1,$
RET
;*********发送数据程序****
RS_SEND_DATA:
SETB MAX485
LCALL DELAY_TIME
CLR ES
MOV R0,#50H
MOV R2,#00H
RS_SEND_A:
MOV A,@R0
LCALL SEND
INC R0
INC R2
CJNE R2,#0AH,RS_SEND_A
LCALL DELAY_TIME
CLR MAX485
LCALL DELAY_TIME
SETB ES
RET
;-------------------------------
SEND: MOV SBUF,A
JNB TI,$
CLR TI
LCALL DTIME
RET
;-------------------------
DTIME: MOV R3,#080H
DJNZ R3,$
RET
;--------------------------
CLR_BUFFER:
MOV R0,#51H
MOV A,#00H
CLR_BUA:MOV @R0,A
INC R0
CJNE R0,#59H,CLR_BUA
RET
RET
;--------------------------
D10MS: MOV R2,#012H
D10MA: MOV R1,#0FFH
D10MB: DJNZ R1,D10MB
DJNZ R2,D10MA
RET
;-------------------------
D200MS: MOV R3,#20
D20MS: LCALL D10MS
DJNZ R3,D20MS
RET
;-------------------------
D300MS: MOV R3,#30
D30MS: LCALL D10MS
DJNZ R3,D30MS
RET
;-----RS232初始化程序--------
RS_SET: MOV TMOD,#21H
MOV TH1,#0F4H
MOV TL1,#0F4H
MOV SCON,#01010000B
MOV PCON,#80H ;4800bps
MOV TH0,#0CH
MOV TL0,#58H
SETB ET0 ;允许"T0"中断
SETB TR0 ;启动定时器"0"
SETB TR1
SETB ES
SETB EA
RET
;******* 定时器“0”中断 ******
TIME0PR:PUSH ACC
PUSH PSW
MOV TH0,#0CH
MOV TL0,#58H
MOV A,TACOM
INC A
CJNE A,#08H,TIME0PA
MOV A,#00H
MOV TACOM,A
SETB T1_OVER
JNB ALM_IN,TIME0PA
SETB ALARM_ON
LJMP TIME0PB
TIME0PA:CLR ALARM_ON
TIME0PB:MOV TACOM,A
MOV A,TBCOM
INC A
CJNE A,#090H,TIME0PC
MOV TBCOM,#00H
SETB T0_OVER
POP PSW
POP ACC
RETI
TIME0PC:MOV TBCOM,A
SETB TR0
POP PSW
POP ACC
RETI
;--------湿度A/D变换程序--------
HUMID_AD:
LCALL READ_TLC549B
LCALL D200MS
LCALL READ_TLC549B
LCALL HUMID_CHANG
RET
;┌───湿度变换子程序──────┐
;│ 湿度H=[(V_HEX)/8×5]-25 │
;│ 0.8V≤输入电压V≤4.08V │
;│ 25%≤相对湿度H≤100% │
;│ 其中V_HEX=输入电压的AD变换值 │
;└────────────────┘
HUMID_CHANG:
MOV A,SER_DATA
MOV B,#08H
DIV AB
MOV B,#05H
MUL AB
SUBB A,#25
CJNE A,#100,HUMID_C
HUMID_A:MOV A,#99
HUMID_B:LCALL HEX_TOBCD
SWAP A
ORL A,B
MOV HUMID_DAT,A
RET
HUMID_C:JNC HUMID_A
LJMP HUMID_B
;┌─────读程序湿度AD变换────┐
;│ 返回值SER_DAT=湿度A/D变换数据 │
;└─────────────────┘
READ_TLC549A:
SETB CS_A
CLR CLK_A
MOV R3,#08H
CLR CS_A
LCALL D10US
TLC_PRA:SETB CLK_A
MOV C,P1.6
RLC A
CLR CLK_A
DEC R3
DJNZ R3,TLC_PRA
MOV SER_DATA,A
SETB CS_A
RET
;--------------------------------
D10uS: MOV R4,#1
DJNZ R4,$
RET
;--------------------------------
READ_TLC549B:
SETB CS_A ;置CS为
CLR CLK_A ;置I/O CLOCK为零。
MOV R3,#00H ;移位计数为零。
CLR CS_A
NOP ;等待1.4μs,数根据晶振情况选择。
NEXTB: SETB CLK_A ;P1.0
MOV C,P1.6
RLC A
CLR CLK_A
INC R3
CJNE R3,#08H,NEXTB
MOV R3,#00H
SETB CS_A
MOV SER_DATA,A
RET
;-------RS232接收程序---------
RS_RECEIVE:
PUSH ACC
PUSH PSW
JNB TI,RS_RECA
POP PSW
POP ACC
RETI
RS_RECA:JNB RI,RS_RET
CLR RI
MOV A,SBUF
CJNE A,#0AAH,RS_RECD
SETB RS_REVFA
RS_RECB:MOV R1,RS_DATA
MOV @R1,A
INC R1
MOV RS_DATA,R1
LJMP RS_RET
RS_RECD:JNB RS_REVFA,RS_RET
CJNE A,#0BBH,RS_RECB
MOV R1,RS_DATA
MOV @R1,A
MOV RS_DATA,#50H
CLR RS_REVFA
SETB RS_REVFB
RS_RET: POP PSW
POP ACC
RETI
;--------------------------
DELAY_TIME:
MOV R2,#05H
DELAY_A:MOV R3,#010H
DELAY_B:MOV R4,#0FFH
DJNZ R4,$
DJNZ R3,DELAY_B
DJNZ R2,DELAY_A
RET
;--------------------------
DELAY_TIME_A:
MOV R2,#10H
DELAY_C:MOV R3,#0FFH
DELAY_D:MOV R4,#0FFH
DJNZ R4,$
DJNZ R3,DELAY_D
DJNZ R2,DELAY_C
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -