ME300實例-DS18B20溫度控制實驗(匯編語言源程序)
程序說明:
DS18B20的管腳定義:
1、GND
2、DQ
3、VCC
?DQ???→??P3.3
?K1???→??P1.4
?K2???→??P1.5
?K3???→??P1.6
?K4???→??P1.7
JP2?用跳線帽短接1和2,選用LCD。
溫度顯示用四位,當溫度>=100度時,第四位才顯示。
檢測?DS18B20?狀態:
DS18B20正常顯示:
??DS18B20??OK
?TEMP:??25.8℃?←?顯示實際溫度
DS18B20不正常顯示:
DS18B20??ERROR
?TEMP:?----℃??←?顯示----
這時你要檢查DS18B20是否連接好、接對,否則要更換一個新的?DS18B20?芯片。
一、查看溫度報警值:
K1?→?進入查看溫度報警值狀態。
LCD?1602?顯示:
??LOOK?ALERT?CODE
?TH:028℃?TL:18℃
TH:028??高位報警值
TL:18???低位報警值
K3?→?退出查看溫度報警值狀態。
二、設定溫度報警值:
K2?→?進入設定溫度報警值狀態。
LCD?1602?顯示:
?RESET?ALERT?CODE
?TH:028℃?TL:18℃
K1?:?設定值加(UP)、減(DOWN)方式選擇鍵(默認為減少)
K2?:?TH值設定鍵
K3?:?TL值設定鍵
K4?:?確定鍵?(退出設定狀態)
?K2?或?K3?以減(DOWN)方式設定,當設定數值減到“0”時自動轉換為加(UP)方式。
?K2?或?K3?以加(UP)方式設定,當設定數值?TH=120、TL=99?時,設定數值均變為“0”。
K4?→?確定并退出設定溫度報警值狀態。
將設定的溫度報警值自動存入?DS18B20?的?EEROM?中,可永久保存。
每次開機時自動從?DS18B20?的?EEROM?讀出溫度報警值。
三、報警狀態的顯示:
1、當實際溫度大于?TH?的設定值時,
??LCD1602?顯示:
???DS18B20??OK
?TEMP:??88.8℃?>?H
關閉繼電器,蜂鳴器響,表示超溫。
2、當實際溫度小于?TL?的設定值時,
??LCD1602?顯示:
???DS18B20??OK
?TEMP:??18.8℃?蜂鳴器響,表示加熱部分出現故障。
3、當實際溫度小于?TH?的設定值時,繼電器吸合,開始加熱。
??加熱標記為“!”
源程序(匯編語言)
;*??描述:???????????????????????????????????????????????????????????????????????*
;*??????????DS18B20溫度控制1602LCD顯示??????????????????????????????????????????*
;*??????????????????????????????????????????????????????????????????????????????*
;*??????????使用方法參考readme.txt文檔??????????????????????????????????????????*
;*??????????????????????????????????????????????????????????????????????????????*
;*??????????????????????????????????????????????????????????????????????????????*
??????????TEMP_ZH???DATA??24H?????;實時溫度值存放單元
??????????TEMPL?????DATA??25H?????;
??????????TEMPH?????DATA??26H?????;
??????????TEMP_TH???DATA??27H?????;高溫報警值存放單元
??????????TEMP_TL???DATA??28H?????;低溫報警值存放單元
??????????TEMPHC????DATA??29H?????;
??????????TEMPLC????DATA??2AH
??????????K1?????EQU??P1.4
??????????K2?????EQU??P1.5
??????????K3?????EQU??P1.6
??????????K4?????EQU??P1.7
??????????BEEP???EQU??P3.7
??????????RELAY??EQU??P1.3
??????????LCD_X?????EQU??2FH??????;LCD?地址變量
??????????LCD_RS????EQU??P2.0
??????????LCD_RW????EQU??P2.1
??????????LCD_EN????EQU??P2.2
??????????flag1?????equ??20H.0????;DS18B20是否存在標記
??????????KEY_UD????EQU??20H.1????;設定?KEY?的UP與DOWN?標記
??????????date_line?equ?p3.3
;=====================================================
???????????ORG??0000H
???????????JMP??MAIN
MAIN:?????MOV??SP,#60H
??????????MOV??A,#00H
??????????MOV??R0,#20H???????;將?20H-2FH?單元清零
??????????MOV??R1,#10H
CLEAR:????MOV??@R0,A
??????????INC??R0
??????????DJNZ??R1,CLEAR
??????????CALL??SET_LCD
??????????CALL??RE_18B20
start:????CALL??RESET??????????;18B20復位子程序
??????????JNB???FLAG1,START1???;DS1820不存在
??????????CALL??MENU_OK
??????????CALL??READ_E2
??????????CALL??TEMP_BJ????????;顯示溫度標記
??????????JMP???START2
START1:???CALL??MENU_ERROR
??????????CALL??TEMP_BJ????????;顯示溫度標記
??????????JMP??$
START2:
??????????CALL??RESET
??????????JNB??FLAG1,START1????;DS1820不存在
??????????MOV???A,#0CCH????????;?跳過ROM匹配
??????????CALL??WRITE
??????????MOV???A,#44H?????????;?發出溫度轉換命令
??????????CALL??WRITE
??????????CALL??RESET
??????????MOV???A,#0CCH????????;?跳過ROM匹配
??????????CALL??WRITE
??????????MOV???A,#0BEH????????;?發出讀溫度命令
??????????CALL??WRITE
??????????CALL??READ
??????????call?CONVTEMP
??????????Call?DISPBCD
??????????CALL?CONV
??????????CALL?TEMP_COMP
??????????CALL??PROC_KEY???????;?鍵掃描
???SJMP?START2
;-----------------------------------------------------
PROC_KEY:
??JB??K1,PROC_K1????;?按鍵K1處理
?????????CALL??BEEP_BL
?????????JNB??K1,$
?????????MOV??DPTR,#M_ALAX1
?????????MOV??A,#1
?????????CALL??LCD_PRINT
?????????CALL??LOOK_ALARM
?????????JB??K3,$
?????????CALL??BEEP_BL
?????????JMP??PROC_K2
PROC_K1:?????;?按鍵K2處理
?????????JB??K2,PROC_END
?????????CALL??BEEP_BL
?????????JNB??K2,$
?????????MOV???DPTR,#RESET_A1
?????????MOV???A,#1
?????????CALL??LCD_PRINT
?????????CALL??SET_ALARM
?????????CALL??RE_18B20???????????;將設定的TH,TL值寫入DS18B20內
?????????CALL??WRITE_E2
PROC_K2:
?????????CALL??MENU_OK
?????????CALL??TEMP_BJ
PROC_END:
?????????RET
;============================================
;設定報警值?TH、TL
;============================================
SET_ALARM:
?????????;CALL??RESET_ALARM
?????????CALL??LOOK_ALARM
AS0:
?????????JB???K1,AS00
?????????CALL??BEEP_BL
?????????JNB??K1,$
?????????CPL??20H.1????????????;UP/DOWN?標記
AS00:????JB??20H.1,ASZ01???????;20H.1=1,UP
?????????JMP??ASJ01????????????;20H.1=0,DOWN
ASZ01:???JB??K2,ASZ02??????????;TH值調整(增加)
?????????CALL??BEEP_BL
?????????INC??TEMP_TH
?????????MOV??A,TEMP_TH
?????????CJNE??A,#120,ASZ011
?????????MOV??TEMP_TH,#0
ASZ011:??CALL??LOOK_ALARM
?????????MOV??R5,#10
?????????CALL??DELAY
?????????JMP??ASZ01
ASZ02:???JB??K3,ASZ03??????????;TL值調整(增加)
?????????CALL??BEEP_BL
?????????INC??TEMP_TL
?????????MOV??A,TEMP_TL
?????????CJNE??A,#99,ASZ021
?????????MOV??TEMP_TL,#00H
ASZ021:??CALL??LOOK_ALARM????;
?????????MOV??R5,#10
?????????CALL??DELAY
?????????JMP??ASZ02
ASZ03:???JB??K4,AS0??????????;確定調整?OK
?????????CALL??BEEP_BL
?????????JNB??K4,$
?????????RET
ASJ01:
?????????JB??K2,ASJ02??????????;TH值調整?(減少)
?????????CALL??BEEP_BL
?????????DEC???TEMP_TH
?????????MOV??A,TEMP_TH
?????????CJNE??A,#0FFH,ASJ011
?????????JMP??ASJ022
ASJ011:??CALL??LOOK_ALARM
?????????MOV??R5,#10
?????????CALL??DELAY
?????????JMP??AS0
ASJ02:???JB??K3,ASJ03?????????;TL值調整(減少)
?????????CALL??BEEP_BL
?????????DEC??TEMP_TL
?????????MOV??A,TEMP_TL
?????????CJNE??A,#0FFH,ASJ021
?????????JMP??ASJ022
ASJ021:??CALL??LOOK_ALARM????;
?????????MOV??R5,#10
?????????CALL??DELAY
?????????JMP??AS0
ASJ022:??CPL??20H.1
?????????JMP??ASZ01
ASJ03:???JMP??ASZ03
?????????RET
RESET_ALARM:
??????????MOV??DPTR,#RESET_A1??;指針指到顯示信息區
??????????MOV??A,#1????????????;顯示在第一行
??????????CALL??LCD_PRINT
??????????RET
RESET_A1:
?????DB??"RESET?ALERT?CODE"
;====================================================
;實際溫度值與標記溫度值比較子程序
;====================================================
TEMP_COMP:
??????????MOV??A,TEMP_TH???????
??????????SUBB??A,TEMP_ZH???????;減數>被減數,則
??????????JC??CHULI1????????????;借位標志位C=1,轉
??????????MOV??A,TEMP_ZH
??????????SUBB??A,TEMP_TL???????;減數>被減數,則
??????????JC??CHULI2????????????;借位標志位C=1,轉
??????????MOV??DPTR,#BJ5
??????????CALL??TEMP_BJ3
??????????CLR???RELAY???????????;繼電器吸合
??????????RET
?CHULI1:
??????????MOV??DPTR,#BJ3
??????????CALL??TEMP_BJ3
??????????SETB??RELAY???????????;繼電器關閉
??????????CALL??BEEP_BL
??????????RET
?CHULI2:
??????????MOV??DPTR,#BJ4
??????????CALL??TEMP_BJ3
??????????CALL??BEEP_BL
??????????RET
;-----------------------------------------
TEMP_BJ3:
??????????MOV??A,#0CEH
??????????CALL?WCOM
??????????MOV??R1,#0
??????????MOV??R0,#2
BBJJ3:????MOV??A,R1
??????????MOVC?A,@A+DPTR
??????????CALL??WDATA
??????????INC?R1
??????????DJNZ??R0,BBJJ3
??????????RET
BJ3:
??????DB??">H"
BJ4:
??????DB??"
BJ5:
??????DB??"?!"
;==================================================
;顯示溫度標記子程序
;==================================================
TEMP_BJ:
??????????MOV??A,#0CBH
??????????CALL?WCOM
??????????MOV??DPTR,#BJ1??;指針指到顯示消息
??????????MOV??R1,#0
??????????MOV??R0,#2
BBJJ1:????MOV??A,R1
??????????MOVC?A,@A+DPTR
??????????CALL??WDATA
??????????INC?R1
??????????DJNZ??R0,BBJJ1
??????????RET
BJ1:
??????DB??00H,"C"
;=================================================
MENU_OK:
??????????MOV??DPTR,#M_OK1??;指針指到顯示消息
??????????MOV??A,#1??????????;顯示在第一行
??????????CALL??LCD_PRINT
??????????MOV??DPTR,#M_OK2??;指針指到顯示消息
??????????MOV??A,#2??????????;顯示在第一行
??????????CALL??LCD_PRINT
??????????RET
M_OK1:
????DB???"???DS18B20?OK???",0
M_OK2:
????DB???"?TEMP:??????????",0
;-----------------------------------------------
MENU_ERROR:
??????????MOV??DPTR,#M_ERROR1??;指針指到顯示消息1
??????????MOV??A,#1??????????;顯示在第一行
??????????CALL??LCD_PRINT
??????????MOV??DPTR,#M_ERROR2??;指針指到顯示消息1
??????????MOV??A,#2??????????;顯示在第一行
??????????CALL??LCD_PRINT
??????????RET
M_ERROR1:
????DB???"?DS18B20?ERROR??",0
M_ERROR2:
????DB???"?TEMP:?----?????",0
;====================================================
reset:??setb?date_line
????????nop
????????clr?date_line
????????mov?r0,#6bh?????????;主機發出延時復位低脈沖
????????mov?r1,#04h
tsr1:???djnz?r0,$
????????mov?r0,#6bh
????????djnz?r1,tsr1
????????setb?date_line????????;然后拉高數據線
????????nop
????????nop
????????nop
????????mov?r0,#32h
tsr2:???jnb?date_line,tsr3???;等待DS18B20回應
????????djnz?r0,tsr2
????????jmp?tsr4?????????????;?延時
tsr3:???setb?flag1???????????;?置標志位,表示DS1820存在
????????jmp?tsr5
tsr4:???clr?flag1????????????;?清標志位,表示DS1820不存在
????????jmp?tsr7
tsr5:???mov?r0,#06bh
tsr6:???djnz?r0,$????????????;?時序要求延時一段時間
tsr7:???setb?date_line
????????ret
;=======================================================
RE_18B20:
????????JB??FLAG1,RE_18B20A
????????RET
RE_18B20A:
????????CALL??RESET
????????MOV??A,#0CCH???????;跳過ROM匹配
????????LCALL??WRITE
????????MOV??A,#4EH????????;寫暫存寄存器
????????LCALL??WRITE
????????MOV??A,TEMP_TH?????;TH(報警上限)
????????LCALL??WRITE
????????MOV??A,TEMP_TL?????;TL(報警下限)
????????LCALL??WRITE
????????MOV??A,#7FH????????;12位精確度
????????LCALL??WRITE
????????RET
;------------------------------------------------------------
WRITE_E2:
????????CALL??RESET
????????MOV??A,#0CCH????????;跳過ROM匹配
????????LCALL??WRITE
????????MOV??A,#48H?????????;把暫存器里的溫度報警值拷貝到EEROM
????????LCALL??WRITE
????????RET
;--------------------------------------------------------------
READ_E2:
????????CALL??RESET
????????MOV??A,#0CCH????????;跳過ROM匹配
????????LCALL??WRITE
????????MOV??A,#0B8H????????;把EEROM里的溫度報警值拷貝回暫存器
????????CALL??WRITE
????????RET
;--------------------------------------------------------------
;將自定義字符寫入LCD1602的CGRAM中
;--------------------------------------------------------------
STORE_DATA:
????????MOV??A,#40H
????????CALL??WCOM
????????MOV??R2,#08H
????????MOV??DPTR,#D_DATA
????????MOV??R3,#00H
S_DATA:
????????MOV??A,R3
????????MOVC??A,@A+DPTR
????????CALL??WDATA??????;寫入數據
????????INC??R3
????????DJNZ??R2,S_DATA
????????RET
D_DATA:
????DB??0CH,12H,12H,0CH,00H,00H,00H,00H
;====================================================
write:??mov?r2,#8????????????;一共8位數據
????????CLR??C
wr1:
????????clr?date_line????????;開始寫入DS18B20總線要處于復位(低)狀態
????????mov?r3,#07
????????djnz?r3,$????????????;總線復位保持16微妙以上
????????rrc?a????????????????;把一個字節DATA?分成8個BIT環移給C
????????mov?date_line,c??????;寫入一個BIT
????????mov?r3,#3CH
????????djnz?r3,$????????????;等待100微妙
????????setb?date_line???????;重新釋放總線
????????nop
????????djnz?r2,wr1??????????;寫入下一個BIT
????????setb?date_line
????????ret
;--------------------------------------------------------------------
read:????mov?r4,#4??????????;?將溫度低位、高位、TH、TL從DS18B20中讀出
?????????mov?r1,#TEMPL????????;?存入25H、26H、27H、28H
re00:????mov?r2,#8
re01:????clr?cy
?????????setb?date_line
?????????nop
?????????nop
?????????clr?date_line????????;讀前總線保持為低
?????????nop
?????????nop
?????????nop
?????????setb?date_line???????;開始讀總線釋放
?????????mov?r3,#09???????????;延時18微妙
?????????djnz?r3,$
?????????mov?c,date_line??????;從DS18B20總線讀得一個BIT
?????????mov?r3,#3CH
?????????djnz?r3,$????????????;等待100微妙
?????????rrc?a????????????????;把讀得的位值環移給A
?????????djnz?r2,re01?????????;讀下一個BIT
?????????mov?@r1,a
?????????inc?r1
?????????djnz?r4,re00
?????????ret
;*****************************************************
;??處理溫度?BCD?碼子程序
;****************************************************
CONVTEMP:??????MOV??A,TEMPH???????;判溫度是否零下
???????????????ANL??A,#80H
???????????????JZ??TEMPC1?????????;溫度零上轉
???????????????CLR??C
???????????????MOV??A,TEMPL???????;二進制數求補(雙字節)
???????????????CPL??A?????????????;取反加1
???????????????ADD??A,#01H
???????????????MOV??TEMPL,A
???????????????MOV??A,TEMPH
???????????????CPL??A
???????????????ADDC??A,#00H
???????????????MOV??TEMPH,A
???????????????SJMP??TEMPC11
TEMPC1:????????MOV??TEMPHC,#0AH?????;+
TEMPC11:???????MOV??A,TEMPHC
???????????????SWAP??A
???????????????MOV??TEMPHC,A
???????????????MOV??A,TEMPL
???????????????ANL??A,#0FH??????????????;乘0.0625
???????????????MOV??DPTR,#TEMPDOTTAB
???????????????MOVC??A,@A+DPTR
???????????????MOV??TEMPLC,A????????????;TEMPLC?LOW=小數部分?BCD
???????????????MOV??A,TEMPL?????????????;整數部分
???????????????ANL??A,#0F0H?????????????;取出高四位
???????????????SWAP??A
???????????????MOV??TEMPL,A
???????????????MOV??A,TEMPH?????????????;取出低四位
???????????????ANL??A,#0FH
???????????????SWAP??A
???????????????ORL??A,TEMPL?????????????;重新組合
???????????????MOV??TEMP_ZH,A
???????????????LCALL??HEX2BCD1
???????????????MOV??TEMPL,A
???????????????ANL??A,#0F0H
???????????????SWAP??A
???????????????ORL??A,TEMPHC????????????;TEMPHC?LOW?=?十位數?BCD
???????????????MOV??TEMPHC,A
???????????????MOV??A,TEMPL
???????????????ANL??A,#0FH
???????????????SWAP??A??????????????????;TEMPLC?HI?=?個位數?BCD
???????????????ORL??A,TEMPLC
???????????????MOV??TEMPLC,A
???????????????MOV??A,R4
???????????????JZ??TEMPC12
???????????????ANL??A,#0FH
???????????????SWAP??A
???????????????MOV??R4,A
???????????????MOV??A,TEMPHC????????????;TEMPHC?HI?=?百位數?BCD
???????????????ANL??A,#0FH
???????????????ORL??A,R4
???????????????MOV??TEMPHC,A
TEMPC12:???????RET
;---------------------------------------------------------------
HEX2BCD1:
??????????????MOV??B,#064H??????????;十六進制->?BCD
??????????????DIV??AB???????????????;B=?A?%?100
??????????????MOV??R4,A?????????????;R7?=?百位數
??????????????MOV??A,#0AH
??????????????XCH??A,B
??????????????DIV??AB???????????????;B?=?A?%?B
??????????????SWAP??A
??????????????ORL??A,B
??????????????RET
;-------------------------------------------------------------
;??小數部分碼表
;-------------------------------------------------------------
TEMPDOTTAB:
?????????DB???00H,00H,01H,01H,02H,03H,03H,04H
?????????DB???05H,05H,06H,06H,07H,08H,08H,09H
;=====================================================
LOOK_ALARM:
??????????MOV??DPTR,#M_ALAX2???;指針指到顯示信息區
??????????MOV??A,#2????????????;顯示在第二行
??????????CALL??LCD_PRINT
??????????MOV??A,#0C6H
??????????CALL??TEMP_BJ1
??????????MOV??A,TEMP_TH???????;加載TH數據
??????????MOV??LCD_X,#3????????;設置位置
??????????CALL??SHOW_DIG2H?????;顯示數據
??????????MOV??A,#0CEH
??????????CALL??TEMP_BJ1
??????????MOV??A,TEMP_TL???????;加載TL數據
??????????MOV??LCD_X,#12???????;設置位置
??????????CALL??SHOW_DIG2L?????;顯示數據
??????????RET
;--------------------------------------------
M_ALAX1:
?????DB???"?LOOK?ALERT?CODE",0
M_ALAX2:
?????DB???"TH:??????TL:????",0
;--------------------------------------------
TEMP_BJ1:
??????????CALL?WCOM
??????????MOV??DPTR,#BJ2??????;指針指到顯示信息區
??????????MOV??R1,#0
??????????MOV??R0,#2
BBJJ2:????MOV??A,R1
??????????MOVC?A,@A+DPTR
??????????CALL??WDATA
??????????INC?R1
??????????DJNZ??R0,BBJJ2
??????????RET
BJ2:
??????DB??00H,"C"
;---------------------------------------------------
SHOW_DIG2H:????????????????;在?LCD?的第二行顯示數字
??????????MOV??B,#100
??????????DIV??AB
??????????ADD??A,#30H
??????????PUSH??B
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????POP??B
??????????MOV??A,#0AH
??????????XCH??A,B
??????????DIV??AB
??????????ADD??A,#30H
??????????INC??LCD_X
??????????PUSH??B
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????POP??B
??????????INC??LCD_X
??????????MOV??A,B
??????????MOV??B,LCD_X
??????????ADD??A,#30H
??????????CALL??LCDP2
??????????RET
SHOW_DIG2L:????????????????;在?LCD?的第二行顯示數字
??????????MOV??B,#100
??????????DIV??AB
??????????MOV??A,#0AH
??????????XCH??A,B
??????????DIV??AB
??????????ADD??A,#30H
??????????PUSH??B
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????POP??B
??????????INC??LCD_X
??????????MOV??A,B
??????????MOV??B,LCD_X
??????????ADD??A,#30H
??????????CALL??LCDP2
??????????RET
;-------------------------------------------------------------
;顯示區?BCD?碼溫度值刷新子程序
;-------------------------------------------------------------
DISPBCD:
??????????????MOV??A,TEMPLC
??????????????ANL??A,#0FH
??????????????MOV??70H,A?????????????????;小數位
??????????????MOV??A,TEMPLC
??????????????SWAP??A
??????????????ANL??A,#0FH
??????????????MOV??71H,A?????????????????;個位
??????????????MOV??A,TEMPHC
??????????????ANL??A,#0FH
??????????????MOV??72H,A?????????????????;十位
??????????????MOV??A,TEMPHC
??????????????SWAP??A
??????????????ANL??A,#0FH
??????????????MOV??73H,A?????????????????;百位
??????????????MOV??A,TEMPHC
??????????????ANL??A,#0F0H
??????????????CJNE??A,#010H,DISPBCD0
??????????????SJMP??DISPBCD2
DISPBCD0:?????MOV??A,TEMPHC
??????????????ANL??A,#0FH
??????????????JNZ??DISPBCD2???????????????;十位數是0
??????????????MOV??A,TEMPHC
??????????????SWAP??A
??????????????ANL??A,#0FH
??????????????MOV??73H,#0AH???????????????;符號位不顯示
??????????????MOV??72H,A??????????????????;十位數顯示符號
DISPBCD2:?????RET
;==========================================================
;?LCD?1602?顯示子程序
;==========================================================
CONV:
??????????MOV??A,73H?????????;加載百位數據
??????????MOV??LCD_X,#6??????;設置位置
??????????CJNE?A,#1,CONV1
??????????JMP??CONV2
CONV1:????MOV??A,#"?"
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????JMP??CONV3
CONV2:????CALL??SHOW_DIG2????;顯示數據
CONV3:????INC??LCD_X?????????????;
??????????mov??a,72h?????????;十位
??????????CALL??SHOW_DIG2
??????????inc??LCD_X
??????????mov??a,71h?????????;個位
??????????CALL??SHOW_DIG2
??????????inc??LCD_X
??????????MOV??A,#'.'
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????MOV??A,70h?????????;加載小數點位
??????????INC??LCD_X?????????;設置位置
??????????CALL??SHOW_DIG2????;顯示數據
??????????RET
;-------------------------------------------------------
SHOW_DIG2:?????????????????;在?LCD?的第二行顯示數字
??????????ADD??A,#30H
??????????MOV??B,LCD_X
??????????CALL??LCDP2
??????????RET
;---------------------------------------------------------
LCDP2:????????????????????;在LCD的第二行顯示字符
?????????PUSH??ACC????????;
?????????MOV??A,B?????????;設置顯示地址
?????????ADD??A,#0C0H?????;設置LCD的第二行地址
?????????CALL??WCOM???????;寫入命令
?????????POP??ACC?????????;由堆棧取出A
?????????CALL??WDATA??????;寫入數據
?????????RET
;---------------------------------------------------------
SET_LCD:?????????????????????;對?LCD?做初始化設置及測試
??????????CLR??LCD_EN
??????????CALL??INIT_LCD?????;初始化?LCD
??????????CALL??STORE_DATA???;將自定義字符存入LCD的CGRAM
??????????RET
INIT_LCD:??????????????????;8位I/O控制?LCD?接口初始化
??????????MOV??A,#38H????????;雙列顯示,字形5*7點陣
??????????CALL??WCOM
??????????call??delay1
??????????MOV??A,#38H
??????????CALL??WCOM
??????????call??delay1
??????????MOV??A,#38H
??????????CALL??WCOM
??????????call??delay1
??????????MOV??A,#0CH????????;開顯示,顯示光標,光標不閃爍
??????????CALL??WCOM
??????????call??delay1
??????????MOV??A,#01H????????;清除?LCD?顯示屏
??????????CALL??WCOM
??????????call??delay1
??????????RET
;==================================================
CLR_LINE1:???????????????????;清除LCD的第一行字符
??????????MOV??A,#80H????????;設置?LCD?的第一行地址
??????????CALL??WCOM?????????;
??????????MOV??R0,#24????????;設置計數值
????C1:???MOV??A,#'?'????????;載入空格符至LCD
??????????CALL??WDATA????????;輸出字符至LCD
??????????DJNZ??R0,C1????????;計數結束
??????????RET
;==================================================
LCD_PRINT:???????;在LCD的第一行或第二行顯示字符
??????????CJNE??A,#1,LINE2??;判斷是否為第一行
??LINE1:??MOV??A,#80H???????;設置?LCD?的第一行地址
??????????CALL??WCOM????????;寫入命令
??????????CALL??CLR_LINE????;清除該行字符數據
??????????MOV??A,#80H???????;設置?LCD?的第一行地址
??????????CALL??WCOM????????;寫入命令
??????????JMP??FILL
??LINE2:??MOV??A,#0C0H??????;設置?LCD?的第二行地址
??????????CALL??WCOM????????;寫入命令
??????????CALL??CLR_LINE????;清除該行字符數據
??????????MOV??A,#0C0H??????;設置?LCD?的第二行地址
??????????CALL??WCOM
??FILL:???CLR??A????????????;填入字符
??????????MOVC??A,@A+DPTR???;由消息區取出字符
??????????CJNE??A,#0,LC1????;判斷是否為結束碼
??????????RET
??LC1:????CALL??WDATA???????;寫入數據
??????????INC??DPTR?????????;指針加1
??????????JMP??FILL?????????;繼續填入字符
??????????RET
;=========================================
CLR_LINE:??????????????????;清除該行?LCD?的字符
??????????MOV??R0,#24
???CL1:???MOV??A,#'?'
??????????CALL??WDATA
??????????DJNZ??R0,CL1
??????????RET
???DE:????MOV??R7,#250
??????????DJNZ??R7,$
??????????RET
;============================================
WCOM:?????????????????????;以8位控制方式將命令寫至LCD
??????????MOV??P0,A???????;寫入命令
??????????CLR?LCD_RS??????;RS=L,RW=L,D0-D7=指令碼,E=高脈沖
??????????CLR?LCD_RW
??????????SETB?LCD_EN
??????????ACALL?DELAY1????????
??????????CLR?LCD_EN
??????????RET
;=============================================
WDATA:????????????????????;以8位控制方式將數據寫至LCD
??????????MOV??P0,A???????;寫入數據
??????????SETB??LCD_RS????????
??????????CLR??LCD_RW
??????????SETB??LCD_EN????????
??????????CALL??DE
??????????CLR??LCD_EN
??????????CALL??DE
??????????RET
;=============================================
;PRINT?A?CHAR?ON?LINE?1
;A=ASC?DATA,?B=LINE?X?POS
;==============================================
LCDP1:????????????????????;在LCD的第一行顯示字符
?????????PUSH??ACC????????;
?????????MOV??A,B?????????;設置顯示地址
?????????ADD??A,#80H??????;設置LCD的第一行地址
?????????CALL??WCOM???????;寫入命令
?????????POP??ACC?????????;由堆棧取出A
?????????CALL??WDATA??????;寫入數據
?????????RET
;==============================================
BEEP_BL:
?????????MOV??R6,#100
?BL2:????CALL??DEX1
?????????CPL??BEEP
?????????DJNZ??R6,BL2
?????????MOV??R5,#10
?????????CALL??DELAY
?????????RET
?DEX1:???MOV??R7,#180
?DE2:????NOP
?????????DJNZ??R7,DE2
?????????RET
DELAY:????????????????????;(R5)*延時10MS
?????????MOV??R6,#50
?DL1:????MOV??R7,#100
?????????DJNZ??R7,$
?????????DJNZ??R6,DL1
?????????DJNZ??R5,DELAY
?????????RET
DELAY1:????????????????????;延時5MS
?????????MOV??R6,#25
?DL2:????MOV??R7,#100
?????????DJNZ??R7,$
?????????DJNZ??R6,DL2
?????????RET
;================================================
?????????END
評論
查看更多