?? text1.asm
字號:
TEMP1 EQU 5AH ;符號位和百位公用的存放單元
TEMP2 EQU 5BH ;十位存放單元
TEMP3 EQU 5CH ;個位存放單元
TEMP4 EQU 5DH ;
TEMP5 EQU 5EH
TEMP6 EQU 5FH ;數據臨時存放單元
TEMP7 EQU 60H
TEMP8 EQU 61H
ORG 0000H
AJMP MAIN
ORG 0020H
MAIN: MOV SP,#70H
LCALL INT ;調用DS18B20初始化函數
MAIN1: LCALL GET_TEMP ;調用溫度轉換函數
LCALL CHULI ;調用溫度計算函數
LCALL DISP ;調用溫度顯示函數
AJMP MAIN1 ;循環
INT:
L0: SETB P3.7 ;先釋放DQ總線
MOV R2,#250 ;給R2賦延時初值,同時可讓DQ保持高電平2us
L1: CLR P3.7 ;給DQ一個復位低電平
DJNZ R2,L1 ;保持低電平的時間至少為480us
SETB P3.7 ;再次拉高DQ釋放總線
MOV R2,#25
L2: DJNZ R2,L2 ;保持15us-60us
CLR C
ORL C,P3.7 ;判斷是否收到低脈沖
JC L0
MOV R6,#100
L3: ORL C,P3.7
DJNZ R6,L3 ;存在低脈沖保持保持60us-240us
; JC L0 ;否則繼續從頭開始,繼續判斷
SETB P3.7
RET
GET_TEMP:
CLR PSW.4
SETB PSW.3 ;設置工作寄存器當前所在的區域
CLR EA ;使用DS18B20前一定要禁止任何中斷
LCALL INT ;初始化DS18B20
MOV A,#0CCH ;送入跳過ROM命令
LCALL WRITE
MOV A,#44H ;送入溫度轉換命令
LCALL WRITE
LCALL INT ;溫度轉換完成,再次初始化18b20
MOV A,#0CCH ;送入跳過ROM命令
LCALL WRITE
MOV A,#0BEH ;送入讀溫度暫存器命令
LCALL WRITE
LCALL READ
MOV TEMP4,A ;讀出溫度的低字節存在TEMP4
LCALL READ
MOV TEMP5,A ;讀出溫度的高字節存在TEMP5
SETB EA
RET
CHULI : MOV A,TEMP5 ;將溫度的高字節取出
JNB ACC.7,ZHENG ;判斷最高位是否為0,為0則表示溫度為正,則轉到ZHENG
MOV A,TEMP4 ;否則溫度為負,將溫度的低字節取出
CPL A ;求反
INC A ;加1
MOV TEMP8,A ;存到TEMP8中
ANL A,#0FH ;保留低四位
LCALL MULD ;調用乘以625子程序
LCALL HB2 ;調用雙字節16進制數轉換成BCD碼子程序
MOV A,R4 ;將結果的千位百位取出
ANL A,#0F0H ;保留千位
SWAP A ;
MOV TEMP7,A ;把小數結果保存在TEMP7中
MOV A,TEMP4 ;再次取出溫度的低字節
ANL A,#0FFH ;判斷是否為0
JZ XX ;為0則轉到XX執行
MOV A,TEMP5 ;
CPL A ;不為0則直接將溫度的高字節取反
SJMP YY ;
XX: MOV A,TEMP5 ;為0則求補碼
CPL A ;
INC A ;
YY: ANL A,#0FH ;保留高字節的低四位
SWAP A ;將其換到高4位
MOV R5,A ;暫時保存于R5中
MOV A,TEMP8 ;取出求反后的低位字節
ANL A,#0F0H ;取其高4位
SWAP A ;將其換到低4位
ORL A,R5 ;合并成溫度的整數部分
MOV TEMP6,A ;將整數部分存到TEMP6中
LCALL HBCD ;調用一字節的16進制數轉換BCD數的子程序
MOV TEMP1,#0BH ;將"-"號的段選值存到符號位
MOV A,TEMP2 ;取出十位
CJNE A,#00H,NEXT
MOV TEMP2,#0CH ;十位為0不顯示
RET
ZHENG: MOV A,TEMP4 ;將溫度的低字節取出
ANL A,#0FH ;保留低四位
LCALL MULD ;調用乘以625子程序
LCALL HB2 ;調用雙字節16進制數轉換成BCD碼子程序
MOV A,R4 ;將結果的千位百位取出
ANL A,#0F0H ;保留千位
SWAP A ;
MOV TEMP7,A ;把小數結果保存在TEMP7中
MOV A,TEMP4 ;再次取出溫度的低字節
ANL A,#0F0H ;保留高4位
SWAP A ;換到低4位
MOV R5,A ;暫時保存于R5中
MOV A,TEMP5 ;取出溫度的高字節
ANL A,#0FH ;保留低4位
SWAP A ;換到高4位
ORL A,R5 ;合并成溫度的整數部分
MOV TEMP6,A ;整數部分存到TEMP6中
LCALL HBCD ;單字節的16進制數轉換成BCD碼
MOV A,TEMP1 ;取出百位
CJNE A,#00H,NEXT ;百位不為0則轉NEXT
MOV TEMP1,#0CH ;為0則不顯
MOV A,TEMP2 ;取出十位
CJNE A,#00H,NEXT
MOV TEMP2,#0CH ;十位為0也不顯
NEXT:RET
;小數部分乘以625轉換子程序
MULD:
MOV B,#71H
MUL AB
MOV R7,A
MOV R6,B
MOV B,#02H
MUL AB
ADD A,R6
MOV R6,A
RET
;寫字節到18b20子程序
WRITE:
MOV R3,#8 ;一個字節共8位
WR1: SETB P3.7 ;先釋放總線
MOV R4,#8
RRC A ;把要寫的字節的最低位右環移到C中
CLR P3.7 ;寫開始
WR3: DJNZ R4,WR3 ;保持低電平0-15us,等待
MOV P3.7,C ;將C中的位寫到DQ總線上
MOV R4,#20
DJNZ R4,$ ;18b20在15us-60us期間對DQ總線進行采樣
DJNZ R3,WR1 ;判斷8位是否寫完,沒完則繼續寫下一位
SETB P3.7 ;寫完了一個字節,則釋放總線
RET
;從18b20里讀取一個字節子程序
READ:
MOV R6,#8 ;一個字節有8位
RE1: SETB P3.7 ;先釋放總線
NOP
CLR P3.7 ;拉低總線,讀前總線保持為低
NOP ;保持1-2us
MOV R4,#4 ;設置讀時間隙
SETB P3.7 ;讀開始
RE2: DJNZ R4,RE2 ;產生讀時間隙
MOV C,P3.7 ;將總線上的位讀到C
MOV R5,#30 ;
DJNZ R5,$ ;持續60us
RRC A ;將C里的位右環移到A里
DJNZ R6,RE1 ;讀下一位
SETB P3.7
RET
;單字節16進制數轉換成BCD碼子程序
HBCD: MOV A,TEMP6
MOV B,#10
DIV AB
MOV TEMP3,B ;將個位存到TEMP3
MOV B,#10
DIV AB
MOV TEMP2,B ;將十位存到TEMP2
MOV TEMP1,A ;將百位存到TEMP1
RET
;雙字節的16進制數轉換成BCD碼子程序
HB2: CLR A
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H
HB3: MOV A,R7
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5
ADDC A,R5
DA A
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
MOV R3,A
DJNZ R2,HB3
RET
;顯示子程序
DISP: MOV DPTR,#DISPTAB
MOV R0,#4
DP1:MOV R1,#140
LOOP: MOV A,TEMP7 ;取出小數部分
MOVC A,@A+DPTR ;取出相應的字型碼
MOV P1,A ;顯示在數碼管上
SETB P3.0 ;數碼管位選
ACALL DELAY100 ;延時
CLR P3.0 ;清數碼管位選
MOV A,TEMP3 ;取個位
MOVC A,@A+DPTR
ANL A,#7FH ;顯示小數點
MOV P1,A
SETB P3.1
ACALL DELAY100
CLR P3.1
MOV A,TEMP2 ;取十位
MOVC A,@A+DPTR
MOV P1,A
SETB P3.2
ACALL DELAY100
CLR P3.2
MOV A,TEMP1 ;取符號位或百位
MOVC A,@A+DPTR
MOV P1,A
SETB P3.3
ACALL DELAY100
CLR P3.3
DJNZ R1,LOOP ;循環顯示
DJNZ R0,DP1
RET
;延時
DELAY100: MOV R7,#180
DJNZ R7,$
RET
DISPTAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH,0FFH
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -