;===================================================================================
; Main.asm file generated by New Project wizard
;
; Created: //周四 6 月 7 2018
; Processor: 80C51
; Compiler: ASEM-51 (Proteus)
;===================================================================================
$NOMOD51
$INCLUDE (8051.MCU)
;===================================================================================
; DEFINITIONS
;===================================================================================
;===================================================================================
; VARIABLES
;===================================================================================
;===================================================================================
; RESET and INTERRUPT VECTORS
;===================================================================================
FLAG BIT F0 ; //聲明傳感器復位返回的標志位
DQ BIT P1.7 ; //定義DQ 作為數據傳輸端口名
ABIT EQU 35H
BBIT EQU 36H
CBIT EQU 37H ; //固定個,十,百位的存儲位置,名稱
ORG 0000H
AJMP MAIN
ORG 0100H
;//主程序
MAIN: LCALL INIT_1 ; //復位
LCALL FBLCHANGE ; //改變溫度的初始分辨率為9位
LCALL GET_TEMP ; //得到溫度
AJMP CHANGE ; //跳轉到數據處理子程序
;//復位程序
INIT_1:SETB DQ ; //總線釋放
NOP ; //保持高電平,延時
CLR DQ ; //總線置 0,請求響應
MOV R0,#0FBH
TSR1: DJNZ R0,TSR1 ; //延時
SETB DQ ; //再釋放
MOV R0,#25H
TSR2: JNB DQ,TSR3 ; //改變為 0,則代表得到對應
DJNZ R0,TSR2 ; //未得到則繼續等待,判斷
TSR3: SETB FLAG ; //得到相應則標志位置 1,代表傳感器正常存在
MOV R0,#06BH
TSR4: DJNZ R0,TSR4 ; //延時
SETB DQ ; //釋放總線,完成復位
RET
;//改變溫度分辨率
FBLCHANGE:
LCALL INIT_1 ; //復位
MOV A,#0CCH ; //跳過ROM
LCALL WRITE ; //把A寫入傳感器
MOV A,#1FH ; //改變溫度分辨率為9
LCALL WRITE ; //把A寫入傳感器
RET
://得到溫度并轉換
GET_TEMP:
SETB DQ ; //釋放總線
LACALL INIT_1 ; //復位
JB FLAG,TSS1 ; //若傳感器不存在,則直接返回主程序
RET
TSS2: MOV A,#0CCH
LCALL WRITE ; //執行跳過ROM指令
MOV A,#44H
LCALL WRITE ; // 執行測溫指令
LCALL DISPLAY ; //不僅延時,還讓程序完全生效前數碼管置零
LCALL INIT_1 ; //復位
MOV A,#0CCH
LCALL WRITE ; //執行跳過ROM置零
MOV A,#0BEH
LCALL WRITE ; //執行讀取溫度數據指令
LCALL READ ; //跳轉至通信子程序
RET
;//寫入數據 ; 注:不可超過120us,否則無法寫入
WRITE:MOV R2,#8 ; //寫入八位二進制碼,即循環次數
CLR C ; //進位標志位初始置零
WR1: CLR DQ ; //拉低總線為寫入做準備
MOV R3,#6
DJNZ R3,$ ; //快速延時
RRC A
MOV DQ,C ; //將A又循環寫入C,寫入總線以輸入到傳感器
MOV R3,#23
DJNZ R3,$ ; //快速延時
SETB DQ ; //釋放,表示此位寫入完畢
NOP
DJNZ R2,WR1 ; //循環八次,一次寫入八位
SETB DQ ; //釋放總線
RET
;//讀入數據
READ: MOV R4,#2 ; //讀取兩個八位數據,是外層循環次數
MOV R1,#29H ; //立即數尋址給定存儲位置
REE0: MOV R2,#8 ; //給定數據位數,是內層循環次數
REE1: CLR C ; //進位標志位初始置零
SETB C
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ ; //輸入脈沖并持續2-3個機器周期
MOV R3,#7
DJNZ R3,$ ; //快速延時,等待傳感器響應
MOV C,DQ ; //按位讀出
MOV R3,#23
DJNZ R3,$ ; //快速延時
RRC A ; //把C存入A內
DJNZ R2,REE1 ; //循環8次
MOV @R1,A ; //存儲A
DEC R1 ; //更換地址
DJNZ R4,REE0 ; //循環2次
RET
;//數據處理函數
CHANGE:
MOV A,29H
MOV 26H,29H
MOV 25H,28H
MOV 24H,28H ; //在24H存儲原始數據防止丟失
MOV C,25H.7 ; //存儲符號位進C
JNC SN1 ; //判斷溫度的正負,正數則跳過轉補碼程序
MOV A,25H
CPL A ; //取補碼,由于無效位置1,25H不必擔心數據溢出
MOV 25H,A
MOV A,26H
CPL A
INC A ; //由于是末位,需要加一
MOV 26H,A
MOV 29H,26H
MOV 28H,25H ; //在26H,25H中操作后放回29H,28H
SN1: MOV C,28H.0 ; //正負溫度到此均得到整數部分絕對值
RRC A
MOV C,28H.1
RRC A
MOV C,28H.2
RRC A
MOV C,28H.3 ; //分別循環,存入A內,連續4次濾掉小數部分
RRC A ; //可分析A內八位恰為整數部分(最高位為0)
JC SL0
MOV 27H,#00H
AJMP SL5
SL0: MOV 27H,#05H
SL5: MOV 29H,A ; //為小數部分顯示0和5做準備
LCALL DISPLAY ; //轉入顯示函數
LJMP MAIN ; //返回主函數,程序執行完畢
;//顯示函數
DISPLAY:
MOV A,29H
MOV B,#10
DIV AB
MOV ABIT,B
MOV B,#10
DIV AB
MOV BBIT,B
MOV CBIT,A ; //此時可知CBA即為百十個位
MOV R0,#4 ; //循環顯示
DPL1: MOV R1,#250 ; //長時間延時循環
DPL2: MOV C,24H.7
JNC DPL3
MOV P0,#0BFH
SETB P1.2
LCALL DELAY
CLR P1.2
AJMP DPL4
DPL3: MOV P0,#0FFH
SETB P1.2
LCALL DELAY
CLR P1.2 ; //符號位判斷顯示
DPL4: MOV DPTR,#TAB
MOV A,27H
MOVC A,@A+DPTR
MOV P0,A
SETB P1.6
LCALL DELAY
CLR P1.6 ; //小數位判斷顯示
MOV A,ABIT
MOV DPTR,#TAB1
MOVC A,@A+DPTR
MOV P0,A
SETB P1.5
LCALL DELAY
CLR P1.5
MOV A,BBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P0,A
SETB P1.4
LCALL DELAY ; //個十百位顯示
CLR P1.4
MOV A,CBIT
MOVC A,@A+DPTR
MOV P0,A
SETB P1.3
LCALL DELAY
CLR P1.3
DJNZ R1,DPL2
DJNZ R0,DPL1
RET
;//延遲函數
DELAY:MOV R5,#10
DEL0: MOV R6,#1
DEL1: MOV R7,#20
DEL2: DJNZ R7,DEL2
DJNZ R6,DEL1
DJNZ R5,DEL0
RET
TAB: ; //正常陽極數碼0-9
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
TAB1: ; //帶小數點的個位顯示數碼0-9
DB 40H,79H,24H,30H,19H,12H,02H,78H,00H,10H
LOOP:
JMP LOOP ;====================================================================
END
|