?? 1602_lcd at89s52.txt
字號:
;********************************************************
;使用1602_LCD AT89S52 18B20實現的溫度報警,時間可調顯示,
;一天可設三個鬧鐘,八首音樂,一個秒表,
;全匯編實現,程序差不多寫滿8K BYTES 了
;硬件電路比較簡單,主要靠程序上的實現
;完成時間____2006\09\27\sml
;********系統初始化***********************
T2CON EQU 0C8H
CP_RL2 BIT 0C8H.0
C_T2 BIT 0C8H.1
TR2 BIT 0C8H.2
EXEN2 BIT 0C8H.3
TCLK BIT 0C8H.4
RCLK BIT 0C8H.5
EXF2 BIT 0C8H.6
TF2 BIT 0C8H.7
RCAP2H EQU 0CBH
RCAP2L EQU 0CAH
TH2 EQU 0CDH
TL2 EQU 0CCH
ET2 BIT IE.5
ORG 00H
JMP INPORT
ORG 0BH
LJMP TM0
ORG 001BH
LJMP INTT0
ORG 002BH
LJMP TIME_T2
ORG 30H
INPORT:
TMP_H EQU 29H ;溫度高字節
TMP_L EQU 28H
TEMPHEAD EQU 6BH
DI_DA DATA 21H
SEC DATA 22H
MIN DATA 23H
HOUR DATA 24H
RS EQU P3.5;確定具體硬件的連接方式
RW EQU P3.4 ;確定具體硬件的連接方式
E EQU P3.3 ;確定具體硬件的連接方式
;秒表暫RAM單元定義
WATCH_H EQU 4DH
WATCH_M EQU 4EH
WATCH_S EQU 4FH
WATCH_MS EQU 50H
WATCH_H_H EQU 51H
WATCH_H_L EQU 52H
WATCH_M_H EQU 53H
WATCH_M_L EQU 54H
WATCH_S_H EQU 55H
WATCH_S_L EQU 56H
WATCH_MS_H EQU 57H
WATCH_MS_L EQU 58H
ALARM1_H EQU 59H
ALARM1_M EQU 5AH
ALARM2_H EQU 5BH
ALARM2_M EQU 5CH
ALARM3_H EQU 5DH
ALARM3_M EQU 5EH
ALARM1_H_H EQU 5FH
ALARM1_H_L EQU 60H
ALARM2_H_H EQU 61H
ALARM2_H_L EQU 62H
ALARM3_H_H EQU 63H
ALARM3_H_L EQU 64H
ALARM1_M_H EQU 65H
ALARM1_M_L EQU 66H
ALARM2_M_H EQU 67H
ALARM2_M_L EQU 68H
ALARM3_M_H EQU 69H
ALARM3_M_L EQU 6AH
STOPWATCH_FLAG1 EQU 04H
CLR 04H
ALARM1_ON_OR_OFF EQU 07H
ALARM2_ON_OR_OFF EQU 06H
ALARM3_ON_OR_OFF EQU 05H
;TEMPERATURE_ALARM_BEEP_FLAG EQU 04H;在溫度CONTROL時,要考慮到這條件進去
KEY_SET EQU P0.3
KEY_UP EQU P0.4
KEY_DOWN EQU P0.5
DS18B20_FLAG EQU PSW.0;開始時要查18B20存在否
SET_FLAG EQU 01H
FLASH_FLAG EQU 02H
K_ON EQU 03H;是個位標志哦
SETB K_ON
SETB FLASH_FLAG
SETB SET_FLAG
CLR 07H
CLR 06H
CLR 05H
MOV A,#0
MOV 25H,A
MOV 26H,A
MOV 32H,A
MOV 33H,A
MOV R4,#14;
MOV TMOD,#11H
MOV TL0,#0B0H
MOV TH0,#3CH
SETB ET0
SETB TR0
SETB ET1
MOV DI_DA,#00H
CLR C_T2 ;
CLR CP_RL2;允許重載
;T2MOD的TO2是T2輸出允許
MOV RCAP2H,#0D9H ;預先值高 10ms 12MHZ
MOV RCAP2L,#0B8H
MOV TH2,#0D9H
MOV TL2,#0B8H
SETB ET2
SETB EA
LCD_INIT://lcd的初化配置
;15MS
MOV R6,#30
LCALL DELAY_BY_R6 ;15ms
MOV P1,#38H ;寫38h
LCALL WRITE_NOT_CHECK_BUSY
MOV R6,#10
LCALL DELAY_BY_R6 ;5ms
MOV P1,#38H
LCALL WRITE_NOT_CHECK_BUSY
MOV R6,#10
LCALL DELAY_BY_R6 ;5ms
;-----設轉初始值
SETB E
MOV P1,#00000001B ;清屏并光標復位
LCALL ENABLE;調用寫入命令子程序
MOV P1,#00111000B ;8位2行5x7點陣
LCALL ENABLE ;調用寫入命令子程序
MOV P1,#00001100B ;顯示器開、光標開、光標允許閃爍
LCALL ENABLE ;調用寫入命令子程序
MOV P1,#00000110B;文字不動,光標自動右移
LCALL ENABLE ;調用寫入命令子程序
STORE_DEFINE_DATA: ;把自定義字符存入CGRAM
MOV P1,#40H ;CGRAM起始地址
LCALL ENABLE
MOV R2,#8
MOV DPTR,#DEFINE_DATA
MOV R3,#0
NEXTP:
MOV A,R3
MOVC A,@A+DPTR
MOV P1,A
LCALL WRITE_DATA_TO_LCD
INC R3
DJNZ R2,NEXTP
;****************主程序*******************
START:
LCALL RESET
JNB 70h,MAIN1
MOV P1,#0C0H ;寫入顯示起始地址(第二行第一個位置)
LCALL ENABLE ;調用寫入命令子程序(寫入字符串前要查忙)
DS18B20_NOT_READY:
LCALL DISPLAY_18B20_ERROR
LOOP1:
LCALL RESET
JNB 70h,MAIN1
JMP LOOP1 ;如果栓測不到18b20程序下面不執行
MAIN1:
MOV R1,#4 ;清單元數據
MOV R0,#21H
CLEAR:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR
MOV R1,#30
MOV R0,#4DH
CLEAR1:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR1
MOV R1,#9
MOV R0,#6BH
CLEAR2:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR2
MOV R1,#6
MOV R0,#40H
CLEAR3:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR3
BACKK:
MOV P1,#00000001B ;清屏并光標復位
LCALL ENABLE;調用寫入命令子程序
LCALL DISPLAY_WATING ;等待第一次結果.
LCALL SKIP_ROM
LCALL TEMP_CONV
LCALL DELAY_600MS
MOV P1,#00000001B ;清屏并光標復位
LCALL ENABLE;調用寫入命令子程序
MAIN :
LCALL RESET
LCALL SKIP_ROM
LCALL RELCALL_EPROM ;調入溫度限值
MAIN_MAIN:
LCALL READ_TEMP ;讀18b20的內部溫度
JB 70h,DS18B20_NOT_READY ;中途失敗!
LCALL DATA_CONV ; 數據轉換,同時有溫度比較和報警動作標志K_ON=1則對應開機器
LCALL DISPLAY_18B20_TEMP
LCALL DISPLAY_TIME
LCALL CONTROL
LCALL ALARM_COMPARE
JNB KEY_SET,S1;KEY_SET是設定上下限的標志按鈕P0.3。。。
LCALL TIME_ADJ
LCALL MUSIC
JMP MAIN_MAIN
S1:LCALL DELAY_2MS ;延時消抖
JB KEY_SET,MAIN
JNB KEY_SET,$;等待按鍵放開
LCALL KEY ;有鍵輸入
AJMP MAIN
MUSIC:MOV A,#0F0H
MOV P2,A
MOV A,P2
CJNE A,#0F0H,KEYIN1
RET
KEYIN1:MOV R3,#0F7H;令第四行為0
MOV R1,#00H
SCAN: MOV A,R3
MOV P2,A
MOV A,P2
MOV R4,A;讀回的值暫放R4中
SETB C
MOV R5,#04H;四列要掃描
K: RLC A
JNC DONE
INC R1
INC R1
DJNZ R5,K
MOV A,R3
SETB C
RRC A
MOV R3,A
JC SCAN
RET
DONE:MOV A,P2
XRL A,R4
JZ DONE
MOV A,R1
MOV DPTR,#FUNCTION_TAB
JMP @A+DPTR
FUNCTION_TAB:
AJMP FU0
AJMP FU1
AJMP FU2
AJMP FU3
AJMP FU4
AJMP FU5
AJMP FU6
AJMP FU7
AJMP FU8
AJMP FU9
AJMP FU10
AJMP FU11
AJMP FU12
AJMP FU13
AJMP FU14
AJMP FU15
FU0:
RET
FU1:
RET
FU2:
RET
FU3:
RET
FU4:
RET
FU5:;SETB P0.1
;CLR TEMPERATURE_ALARM_BEEP_FLAG
RET
FU6:
;MOV P1,#00000001B ;清屏并光標復位
;LCALL ENABLE;調用寫入命令子程序
LCALL DISPLAY_ALARM_CLOCK_1;程序在后面加,只顯示"ALARM_CLOCK_1"
ALARM_K:JB ALARM1_ON_OR_OFF,DISPLAY__ON
LCALL DISPLAY_ALARM_OFF
LJMP ALARM_DATACON_DIS
DISPLAY__ON:LCALL DISPLAY_ALARM_ON
;下面是轉換
ALARM_DATACON_DIS:
MOV A,ALARM1_H
SWAP A
ANL A,#0FH
MOV ALARM1_H_H,A
MOV A,ALARM1_H
ANL A,#0FH
MOV ALARM1_H_L,A
MOV A,ALARM1_M
SWAP A
ANL A,#0FH
MOV ALARM1_M_H,A
MOV A,ALARM1_M
ANL A,#0FH
MOV ALARM1_M_L,A
;下面是顯示鬧鐘值
MOV P1,#11000101B
LCALL ENABLE
MOV DPTR,#LED_DATA
MOV R1,ALARM1_H_H //已經是壓縮型BCD碼了,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM1_H_L //已經是壓縮型BCD碼了,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#MAO
MOV R1,#0;從字串中的第一個開始顯示
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM1_M_H //已經是壓縮型BCD碼了,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM1_M_L //已經是壓縮型BCD碼了
MOV R0,#1
LCALL DISPLAY
;再下面就是判P0.30.40.5了
LOOPP: JB P0.4,PANP05;轉判P0.5;;;;;;;;;
LCALL DELAY2S
JB P0.4,ADJ_ALARM_H ;如果一S之后為放開了,其實是在1S前就放開了的,則知道是調鬧鐘的小時值的
JNB P0.4,$;1S后還未放開,則等,1S后已經放開,則早就放開,所以進行不同操作
CPL ALARM1_ON_OR_OFF;如果一S后還為0則取反ALARM1_ON_OR_OFF標志,關掉鬧鐘
LJMP ALARM_K
ADJ_ALARM_H:MOV A,ALARM1_H
ADD A,#1
DA A
MOV ALARM1_H,A
CJNE A,#24H,ALARM_NEXT
MOV A,#0
MOV ALARM1_H,A
ALARM_NEXT:LJMP ALARM_DATACON_DIS;跳到先轉換數據,再顯示
PANP05:JB P0.5,PAN03; 如果此時P0.5也為1,則轉判P0.3
LCALL DELAY2S
JNB P0.5,$;等放開
MOV A,ALARM1_M
ADD A,#1
DA A
MOV ALARM1_M,A
CJNE A,#60H,ALARM_NEXT
MOV A,#0
MOV ALARM1_M,A
LJMP ALARM_DATACON_DIS
PAN03: JB P0.3,LOOPP
LCALL DELAY2S
JB P0.3,DISPLAY_ALARM2 ;如果一S之后為放開了,其實是在1S前就放開了的,則知道是設鬧鐘2
JNB P0.3,$;
LJMP BACKK;如果長久按P0.3則跳出到主程序中去
;下面是設置第二個鬧鐘
DISPLAY_ALARM2:
LCALL DISPLAY_ALARM_CLOCK_2
ALARM_K1:JB ALARM2_ON_OR_OFF,DISPLAY__ON_2
LCALL DISPLAY_ALARM_OFF
LJMP ALARM_DATACON_DIS_2
DISPLAY__ON_2:LCALL DISPLAY_ALARM_ON
ALARM_DATACON_DIS_2:
MOV A,ALARM2_H
SWAP A
ANL A,#0FH
MOV ALARM2_H_H,A
MOV A,ALARM2_H
ANL A,#0FH
MOV ALARM2_H_L,A
MOV A,ALARM2_M
SWAP A
ANL A,#0FH
MOV ALARM2_M_H,A
MOV A,ALARM2_M
ANL A,#0FH
MOV ALARM2_M_L,A
;下面是顯示鬧鐘值
MOV P1,#11000101B
LCALL ENABLE
MOV DPTR,#LED_DATA
MOV R1,ALARM2_H_H //已經是壓縮型BCD碼了,,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM2_H_L //已經是壓縮型BCD碼了,,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#MAO
MOV R1,#0;從字串中的第一個開始顯示
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM2_M_H //已經是壓縮型BCD碼了,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM2_M_L //已經是壓縮型BCD碼了,,
MOV R0,#1
LCALL DISPLAY
;順序執行下面的
LOOPPP: JB P0.4,PANP05_2;轉判P0.5;;;;;;;;;還沒有寫此句程序呢后面
LCALL DELAY2S
JB P0.4,ADJ_ALARM_2_H ;如果一S之后為放開了,其實是在1S前就放開了的,則知道是調鬧鐘的小時值的
JNB P0.4,$;1S后還未放開,則等,1S后已經放開,則早就放開,所以進行不同操作
CPL ALARM2_ON_OR_OFF;如果一S后還為0則取反ALARM1_ON_OR_OFF標志,關掉鬧鐘
LJMP ALARM_K1
ADJ_ALARM_2_H:
MOV A,ALARM2_H
ADD A,#1
DA A
MOV ALARM2_H,A
CJNE A,#24H,ALARM_NEXT_2
MOV A,#0
MOV ALARM2_H,A
ALARM_NEXT_2:LJMP ALARM_DATACON_DIS_2;跳到先轉換數據,再顯示
PANP05_2:JB P0.5,PAN03_2; 如果此時P0.5也為1,則轉判P0.3
LCALL DELAY2S
JNB P0.5,$;等放開
MOV A,ALARM2_M
ADD A,#1
DA A
MOV ALARM2_M,A
CJNE A,#60H,ALARM_NEXT_2
MOV A,#0
MOV ALARM2_M,A
LJMP ALARM_DATACON_DIS_2
PAN03_2: JB P0.3,LOOPPP
LCALL DELAY2S
JB P0.3,DISPLAY_ALARM3 ;如果一S之后為放開了,其實是在1S前就放開了的,則知道是設鬧鐘2
JNB P0.3,$;
LJMP BACKK;如果長久按P0.3則跳出到主程序中去
;下面是設置第三個鬧鐘
DISPLAY_ALARM3:
LCALL DISPLAY_ALARM_CLOCK_3
ALARM_K2:JB ALARM3_ON_OR_OFF,DISPLAY__ON_3
LCALL DISPLAY_ALARM_OFF
LJMP ALARM_DATACON_DIS_3
DISPLAY__ON_3:LCALL DISPLAY_ALARM_ON
ALARM_DATACON_DIS_3:
MOV A,ALARM3_H
SWAP A
ANL A,#0FH
MOV ALARM3_H_H,A
MOV A,ALARM3_H
ANL A,#0FH
MOV ALARM3_H_L,A
MOV A,ALARM3_M
SWAP A
ANL A,#0FH
MOV ALARM3_M_H,A
MOV A,ALARM3_M
ANL A,#0FH
MOV ALARM3_M_L,A
;下面是顯示鬧鐘值
MOV P1,#11000101B
LCALL ENABLE
MOV DPTR,#LED_DATA
MOV R1,ALARM3_H_H //已經是壓縮型BCD碼了
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM3_H_L //已經是壓縮型BCD碼了,,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#MAO
MOV R1,#0;從字串中的第一個開始顯示
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM3_M_H //已經是壓縮型BCD碼了,
MOV R0,#1
LCALL DISPLAY
MOV DPTR,#LED_DATA
MOV R1,ALARM3_M_L //已經是壓縮型BCD碼了
MOV R0,#1
LCALL DISPLAY
;順序執行下面的
LOOPPPP: JB P0.4,PANP05_3;轉判P0.5;;;;;;;;;還沒有寫此句程序呢后面
LCALL DELAY2S
JB P0.4,ADJ_ALARM_3_H ;如果一S之后為放開了,其實是在1S前就放開了的,則知道是調鬧鐘的小時值的
JNB P0.4,$;1S后還未放開,則等,1S后已經放開,則早就放開,所以進行不同操作
CPL ALARM3_ON_OR_OFF;如果一S后還為0則取反ALARM1_ON_OR_OFF標志,關掉鬧鐘
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -