?? 01-15.asm
字號:
;==============================
;地址分配
;=============================
BYTECNT DATA 30H ;I2C字節計數器地址
BITCNT DATA 31H ;I2C位計數器地址
RTCADR DATA 32H ;PCF8563在I2C上從器件地址
RTCREGADR DATA 33H ;PCF8563內部寄存器地址
RECDATBUF DATA 40H ;接收數據緩沖區 (40H-45H)
SENDATBUF DATA 50H ;發送數據緩沖區
FINISH BIT 00H ;發送及接收成功標志;0成功,1表示失敗
ACK BIT 20H ;接收數據非應答標志位
TIMEDATA DATA 70H ;時間設置與鬧鐘設定的時間臨時緩沖區
KEYNAME DATA 34H ;b4~b0位記錄按鍵值
;b7-作為按鍵有效標志,b7為0時,表示b4-b0位中的鍵值無效。
;b7為1時,表示b4-b0位記錄的按鍵值有效,且未尚未處理,不能
;接受新按鍵。
;外部程序執行了按鍵功能后,將按鍵有效標志清0,允許接收新按鍵
;b6-保留。
KEYSTU DATA 35H ;鍵盤按鍵狀態寄存器,其中b2、b1、b0分別記錄最近
;三次定時中斷的按鍵狀態。
PORTDR DATA 36H ;U105(八上升沿D型觸發器74HC273)芯片在內存中的影射地址
;設置影射地址的目的是為了在執行鍵盤掃描過程中不影響
;該輸出口高3位(b7~b5)位內容
TIMEBELL DATA 37H ;蜂鳴器鳴響時間
BTIME DATA 38H ;50ms計數單元
DISPB BIT 01H ;50ms定時時間到標志
PORTA EQU 9000H ;8255A口地址
PORTB EQU 9100H ;8255B口地址
PORTC EQU 9200H ;8255C口地址
PORTS EQU 9300H ;8255控制/狀態口地址
PORTD EQU 8800H ;U105(八上升沿D型觸發器74HC273)地址
MOUSE DATA 3AH ;光標地址單元
CLONUM DATA 39H ;鬧鐘數量計數單元
CLONUM1 DATA 3DH ;鬧鐘序數
CLOADR1 DATA 3BH ;鬧鐘存儲單元的首地址低四位
CLOADR2 DATA 3CH ;鬧鐘存儲單元的首地址高四位
ALMTIME DATA 0000H ;將外部RAM的0000H~0DFH共256個單元作為定時時間
;保存區。8個單元(1個序號+6個具體時間) X 32個鬧鐘時間 = 224個單元
CONTROL1 EQU 50H ;定義控制寄存器1
CONTROL2 EQU 51H ;定義控制寄存器2
SEC EQU 52H ;定義秒初值存儲地址
MIN EQU 53H ;定義分初值存儲地址
HOUR EQU 54H ;定義時初值存儲地址
DATE EQU 55H ;定義天初值存儲地址
WEEK EQU 56H ;定義周初值存儲地址
MONTH EQU 57H ;定義月初值存儲地址
YEAR EQU 58H ;定義年初值存儲地址
MINAL DATA 59H ;定義分定時初值存儲地址
HOURAL DATA 5AH ;定義時定時初值存儲地址
DATEAL DATA 5BH ;定義日定時初值存儲地址
WEAKAL DATA 5CH ;定義星期定時初值存儲地址
MONTHAL DATA 5DH ;定義月定時初值存儲地址
YEARAL DATA 5EH ;定義年定時初值存儲地址
ALMODE DATA 5FH ;鬧鐘模式地址(有1.2.3種模式 )
ALMODE1 BIT 10H ;鬧鐘輔助標志位(1:表示鬧鐘還有效;0表示無效)
TEMPER_L EQU 4BH ;用于保存讀出溫度的低8位
TEMPER_H EQU 4AH ;用于保存讀出溫度的高8位
FLAG1 EQU 4CH ;是否檢測到DS18B20標志位
TEM1 EQU 4DH ;數碼管個位數存放內存位置
TEM2 EQU 4EH ;數碼管十位數存放內存位置
;===========================
;端口位定義
;===========================
SCL BIT P1.0 ;定義 P1.0為I2C總線串行時鐘輸入端
SDA BIT P1.1 ;定義P1.1為I2C總線串行數據雙向輸入輸出端
RS BIT P1.4 ;定義P3.3為LCM寄存器選擇控制端
R_W BIT P1.5 ;定義P3.4為LCM 讀寫控制端
E BIT P1.6 ;定義P3.5為LCM使能控制端
DB0_DB7 EQU P2 ;定義P0端口為LCD數據端口
IO BIT P1.7
;========================
;程序開始
;========================
ORG 0000H
LJMP MAIN
;ORG 0003H ;開INT0外中斷
;LJMP INT0
;ORG 002BH ;定時器T2中斷服務入口地址
;LJMP CTC2
ORG 0050H
PROC MAIN
MAIN:
MOV SP,#07FH ;重新設定SP起始位置
MOV DPTR,#8000H ;關閉峰鳴器
MOV A,#0FFH
MOVX @DPTR,A
MOV R0,#08H ;將080H-0FFH內部RAM清零
LOOP: MOV @R0,#0
INC R0
CJNE R0,#0,LOOP
;----------------------------------------------------------
;初始化U107(8255)可編程并行I/O接口芯片的工作方式
;----------------------------------------------------------
MOV DPTR, #PORTS ;8255控制/狀態口地址
MOV A, #10011011B ;A口工作在方式0,輸入;B口工作在方式0,輸入;
;C口高、低半部暫時定義為輸入
MOVX @DPTR, A ;送控制字寄存器
;將PD4~PD0置為高電平,使U105(74HC273)輸出級截止,降低功耗。
MOV DPTR, #PORTD ;U105口地址送DPTR
MOV A, PORTDR ;讀U105口在內存中的映象地址
ORL A, #1FH
MOVX @DPTR, A ;數據送U105輸出口
SETB P1.3
;-----------------------------------------------------
;賦時間初值
;-------------------------------------------------
LCALL INITIAL ;初始化LCM
MOV 76H,#00H
MOV 75H,#01H
MOV 74H,#00H
MOV 73H,#01H
MOV 72H,#00H
MOV 71H,#01H
MOV 70H,#00H
;LCALL READTIME ;若時間不為零(即時間有效)則不用再賦初值
;MOV A,46H
;CJNE A,#00H,LOOP1
LCALL SENDTIME ;否則賦初值
MOV DPTR,#0000H ;清外部RAM
LOOP2:
MOV A,#00H
MOVX @DPTR,A
INC DPTR
MOVX A,@DPTR
CJNE A,#00H,LOOP2
MOV CLOADR1,#00H ;賦指針初值
MOV CLOADR2,#00H
CLR ALMODE1 ;清空鬧鐘模式標志位
LCALL INITIAL ;調用LCM初始化子程序
LOOP1:
LCALL READTIME ;調用時間讀取子程序
MOV A,42H
CJNE A,#023H,NEXT1
CLR C
MOV A,41H
SUBB A,#059H
JNC NEXT2
CLR C
NEXT1:
LCALL DISP ;調用LCM顯示子程序
LCALL TEMPER
LCALL DEL10MS ;調用50ms延時子程序
LCALL KEY ;調用鍵盤掃描程序
LCALL ALMCHECK ;調用鬧鐘與實時時間比較子程序
AJMP LOOP1 ;返回繼續循環
NEXT2:
CLR ALMODE1
LCALL DISP
LCALL TEMPER
LCALL DEL10MS
AJMP LOOP1
END
;-------------------------------------------
;溫度顯示子程序
;----------------------------------------------
PROC TEMPER
TEMPER:
LCALL INIT_1820
LCALL RE_CONFIG
LCALL GET_TEMPER ;調用讀溫度子程序
;進行溫度顯示
;顯示范圍00到99度,顯示精度為1度
;因為12位轉化時每一位的精度為0.0625度,我們不要求顯示小數所以可以拋棄29H的低4位
;將28H中的低4位移入29H中的高4位,這樣獲得一個新字節,這個字節就是實際測量獲得的溫度
MOV A,#0F0H
ANL A,4BH ; 舍去溫度低位中小數點
SWAP A
MOV 4BH,A
MOV A,4BH
JNB ACC.3,TEMPER_COV1 ; 四舍五入去溫度值
INC 4BH
TEMPER_COV1:
MOV A,4AH
ANL A,#07H
SWAP A
ADD A,4BH
MOV 4BH,A ; 保存變換后的溫度數據
LCALL DISPLAY ;調用顯示子程序
LJMP EXIT
;DS18B20復位初始化子程序
INIT_1820:
SETB IO
NOP
CLR IO
;主機發出延時537微秒的復位低脈沖
MOV R0,#0FAH
TSR1:
DJNZ R0,TSR1
SETB IO ;然后拉高數據線
NOP
NOP
NOP
MOV R0,#17H
TSR2:
JNB IO,TSR3 ;等待DS18B20回應
DJNZ R0,TSR2
LJMP TSR4 ;延時
TSR3:
SETB FLAG1 ;置標志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ;清標志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#0FCH
TSR6:
DJNZ R0,TSR6 ;時序要求延時一段時間
TSR7:
SETB IO
RET
RE_CONFIG:JB FLAG1,RE_CONFIG1 ; 若DS18B20存在,轉RE_CONFIG1
RET
RE_CONFIG1:
MOV A,#0CCH ; 發SKIP ROM命令
LCALL WRITE_1820
MOV A,#4EH ; 發寫暫存存儲器命令
LCALL WRITE_1820
MOV A,#00H ; TH(報警上限)中寫入00H
LCALL WRITE_1820
MOV A,#00H ; TL(報警下限)中寫入00H
LCALL WRITE_1820
MOV A,#1FH ; 選擇9位溫度分辨率
LCALL WRITE_1820
RET
; 讀出轉換后的溫度值
GET_TEMPER:
SETB IO
LCALL INIT_1820 ;先復位DS18B20
JB FLAG1,TSS2
RET ;判斷DS1820是否存在?若DS18B20不存在則返回
TSS2:
;DS18B20已經被檢測到!!!!!!!!!!!!!!!!!!
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE_1820
MOV A,#44H ;發出溫度轉換命令
LCALL WRITE_1820
MOV R5,#0DH
NEXT7:
LCALL DEL10MS
DJNZ R5,NEXT7
;這里通過調用顯示子程序實現延時一段時間,等待AD轉換結束,12位的話750微秒
LCALL INIT_1820 ;準備讀溫度前先復位
MOV A,#0CCH ; 跳過ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 發出讀溫度命令
LCALL WRITE_1820
LCALL READ_18200 ; 將讀出的溫度數據保存到35H/36H
RET
;**************************************寫DS18B20的子程序(有具體的時序要求)
WRITE_1820:
MOV R2,#8 ;一共8位數據
CLR C
WR1:
CLR IO
MOV R3,#7
DJNZ R3,$
RRC A
MOV IO,C
MOV R3,#25
DJNZ R3,$
SETB IO
NOP
DJNZ R2,WR1
SETB IO
RET
;***************************************讀DS18B20的程序,從DS18B20中讀出兩個字節的溫度數據
READ_18200:
MOV R4,#2 ;將溫度高位和低位從DS18B20中讀出
MOV R1,#4BH ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8 ;數據一共有8位
RE01:
CLR C
SETB IO
NOP
NOP
CLR IO
NOP
NOP
NOP
SETB IO
MOV R3,#7
DJNZ R3,$
MOV C,IO
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;**********************************************************顯示子程序
display:
MOV A,4BH ;將29H中的十六進制數轉換成10進制
MOV B,#10 ;10進制/10=10進制
DIV AB
MOV TEM1,A ;十位在a
MOV TEM2,B ;個位在b
MOV A,#0CDH
LCALL WRITE_COM
CLR C
MOV A,#30H
ADD A,TEM1
LCALL WRITE_DATA
MOV A,#30H
CLR C
ADD A,TEM2
LCALL WRITE_DATA
MOV A,#0DFH
LCALL WRITE_DATA
EXIT:
RET
END
;-----------------------------------------
;鬧鐘與實時時間比較子程序
;------------------------------------------
PROC ALMCHECK
ALMCHECK:
LCALL READTIME ;讀入此時時間
MOV R4,#8
LOOP1:
LCALL CLOLOCATE ;載入鬧鐘值子程序
MOV A,MINAL
CJNE A,41H,LOOP3 ;將第一個鬧鐘的時間從年到分逐一與實時時間的年到分比較若相等則報警
MOV A,HOURAL
CJNE A,42H,LOOP3
;比較鬧鐘模式選擇,進行相應處理
MOV A,ALMODE
CJNE A,#02H,NEXT1 ;進入模式2,鬧鐘為一次性的
SJMP NEXT3
NEXT1:
CJNE A,#03H,NEXT2 ;進入模式3,鬧鐘為每日都有效
SJMP NEXT5
NEXT2:
CJNE A,#01H,NEXT3 ;進入模式1,鬧鐘為每周同一時間有效
SJMP NEXT4
NEXT3:
MOV A,DATEAL
CJNE A,43H,LOOP3
NEXT4:
MOV A,WEAKAL
CJNE A,44H,LOOP3
;MOV A,MONTHAL
;CJNE A,45H,LOOP3
;MOV A,YEARAL
;CJNE A,46H,LOOP3
NEXT5:
MOV C,ALMODE1
JC EXIT2
LCALL INITIAL
MOV A,#084H
LCALL WRITE_COM
MOV DPTR,#LINE7
LCALL DISP2
MOV A,#0C0H
LCALL WRITE_COM
MOV DPTR,#LINE8
LCALL DISP2
MOV A,ALMODE
CLR C
SUBB A,#01H
JC NEXT6
CLR C
SETB ALMODE1
NEXT6:
LCALL DEL5S
MOV A,KEYNAME
CJNE A,#00H,EXIT ;若有鍵盤輸入則退出報警子程序
LCALL DEL2S ;停兩秒后再報警
CJNE A,#00H,EXIT
LCALL DEL5S
EXIT:
LCALL INITIAL
;MOV DPL,CLOADR1
;MOV DPH,CLOADR2
MOV C,ALMODE1
JC EXIT2
MOV R2,#8
MOV DPTR,#0000H
MOV A,#0
LOOP2:
MOVX @DPTR,A
INC DPTR
DJNZ R2,LOOP2
;MOV CLOADR1,DPL
;MOV CLOADR2,DPH
NEXT10:
MOV A,#00H ;將鍵名清空
MOV KEYNAME,A
SJMP EXIT2
LOOP3:
;MOV A,#08H
;ADD A,CLOADR1
;MOV CLOADR1,A
;DJNZ R4,LOOP1
;MOV CLOADR1,#00H
EXIT2:
RET
END
;----------------------------------------------------
; 載入鬧鐘值子程序
;---------------------------------------------------
PROC CLOLOCATE
CLOLOCATE:
MOV DPL,CLOADR1
MOV DPH,CLOADR2
MOV DPTR,#0000H
NEXT1:MOV R5,#8
MOV R0,#059H ;提取的鬧鐘時間值放入以#059H為首的緩沖區內
LOOP: MOVX A,@DPTR
MOV @R0,A
INC DPTR
INC R0
DJNZ R5,LOOP
EXIT:
RET
END
;-----------------------------------------------------
;鍵盤響應子程序
;----------------------------------------------------
PROC KEYDO
KEYDO:
LOOP1:
LCALL INITIAL ;初始化LCM
MOV A,#080H ;顯示功能選擇菜單1
LCALL WRITE_COM
MOV DPTR,#LINE1
LCALL DISP2 ;調用字符串顯示子程序
MOV A,#0C0H
LCALL WRITE_COM
MOV DPTR,#LINE2
LCALL DISP2
FUN1:
LCALL KEYWAIT
MOV A,KEYNAME
CJNE A,#00H,LOOP2
SJMP FUN1
LOOP2:
CJNE A,#011H,NEXT1 ;當按下"ESC"時退出 ,否則向下運行
LCALL INITIAL
LJMP EXIT2
NEXT1:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -