?? pcf8574led.#2
字號:
;實驗程序A:PCF8574LED。ASM PCF8574控制6位數碼顯示
;顯示子程序 : 在六個數碼管上顯示數據。數值在71H ~ 76H之中。不用鍵盤。
SLA1W EQU 70H ;PCF8574 A片寫的節點地址 (可選地址開關:000H)
SLA1R EQU 71H ;PCF8574 A片讀的節點地址
SLA2W EQU 72H ;PCF8574 B片寫的節點地址 (可選地址開關:001H )
SLA2R EQU 73H ;PCF8574 B片讀的節點地址
SLA3W EQU 76H ;PCF8574 C片寫的節點地址 (可選地址開關:011H)
SLA3R EQU 77H ;PCF8574 C片讀的節點地址
SLA EQU 60H
SLAW EQU 62H
SLAR EQU 63H
NUMBYT EQU 61H ;被傳送的字節數存放單元
MTD EQU 20H ;發送數據緩沖區首地址
MRD EQU 30H ;接收字節緩沖區首地址
VSCL EQU P0.1 ;模擬I2C總線時鐘線
VSDA EQU P0.0 ;模擬I2C總線數據線
ORG 00H
AJMP START
ORG 0030H
START: MOV SP,#7H ;堆棧地址
MOV WDTCN,#0DEH ;禁止看門狗定時器
MOV WDTCN,#0ADH;
MOV XBR2,#40H ;C8051F交叉開關使能
ACALL SEND ;傳送子程序,在RAM71H-76H中分別存入1,2,3,4,5,6
DD: ACALL DISP ; 顯示六位數字:'1', '2', '3', '4,' '5', '6'
AJMP DD
;顯示子程序:顯示固定存儲區(即CPU RAM 71H~76H)中存放的數值
DISP: MOV R2,#01H ; 字位碼在R2中,(R2)= #1,#2,#4,#8
MOV R5,#6 ;顯示6個數。
MOV R0,#71H ;71H為數據區首地址
DSP1: MOV A,R2
ACALL WRITEB ;B口輸出作為六位數碼管的位選
MOV A,@R0 ;將要顯示的數值送入A中
DSP2: MOV DPTR,#BCD ;查表
MOVC A,@A+DPTR ;查表,查出要顯示的數值的字形碼
ACALL WRITEC ;C口輸出字形碼
ACALL DEL0 ;延時
MOV A,R2
RL A
MOV R2,A ; 字位碼指向下一位
INC R0 ;準備顯示下一位
DJNZ R5, DSP1
RET
BCD: DB 3FH,06H,5BH,4FH ;顯示數值0,1,2,3
DB 66H,6DH,7DH,07H ;4,5,6,7
DB 7FH,6FH,77H,7CH ;8,9,A,B
DB 39H,5EH,79H,71H ;C,D,E,F
DB 73H,3EH,31H,6EH ;P,U,Z,Y
DB 40H,00H ;- ,滅
DEL0: MOV R6,#00H ;延時子程序
TM: MOV R7,#01
DJNZ R7,$
DJNZ R6,TM
RET
;傳送子程序, 在RAM 71H-76H中分別存入六位數字:'1', '2', '3', '4,' '5', '6'
SEND: MOV R7,#6
MOV R0, #71H
MOV A,#1
SS: MOV @R0,A
INC A
INC R0
DJNZ R7,SS
RET
WRITEB: MOV SLAW,#SLA2W ;將數據送器件B
MOV SLAR,#SLA2R
ACALL WRBC
RET
WRITEC: MOV SLAW,#SLA3W ;將數據送器件C
MOV SLAR,#SLA3R
ACALL WRBC
RET
WRBC: MOV MTD,A
MOV SLA,SLAW
MOV NUMBYT,#1
LCALL WRNBYT
RET
;發送一個字節數據(WRBYT)子程序,該子程序是向虛擬IIC總線的數據線VSDA上發送
;一個字節數據的操作。調用本子程序前將要發送的數據送入A中。占用資源:R0,C。
WRNBYT: MOV R3,NUMBYT
LCALL STAA ;啟動IIC總線
MOV A,SLA ;發送SLAW字節
LCALL WRBYT
LCALL CACK ;檢查應答位
JB F0,WRNBYT ;非應答位則重發
MOV R1,#MTD
WRDA: MOV A,@R1
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
INC R1
DJNZ R3,WRDA
LCALL STOP
RET
;向被控器件發送N個字節數據(WRNBYT)子程序
WRBYT: MOV R0,#08H ;8為數據長度送R0中
WLP: RLC A ;發送數據左移,使發送位入C
JC WR1 ;判斷發送"1"還是"0",發送"1"轉WR1
AJMP WR0 ;發送"0"轉WR0
WLP1: DJNZ R0,WLP ;8位是否發送完,未完轉WLP
RET ;8位發送完結束
WR1: SETB VSDA ;發送"1"程序段
SETB VSCL
NOP
NOP
CLR VSCL
CLR VSDA
AJMP WLP1
WR0: CLR VSDA ;發送"0"程序段
SETB VSCL
NOP
NOP
CLR VSCL
AJMP WLP1
;通用N字節接收子程序(RDNBYT)
RDNBYT:MOV R3,NUMBYT
LCALL STAA ;發送啟動位
MOV A,SLA ;發送尋址字節(讀)
LCALL WRBYT
LCALL CACK ;檢查應答位
JB F0,RDNBYT ;非正常應答時重新開始
RDN: MOV R1,#MRD ;接收數據緩沖區首址MDR入R1
RDN1: LCALL RDBYT ;讀入一個字節到接收數據緩沖中
MOV @R1,A
DJNZ R3,ACK ;N節讀完否?未完轉ACK
LCALL MNACK ;N個字節讀完發送非應答位
LCALL STOP ;發送停止信號
RET ;子程序結束
ACK: LCALL MACK ;發送應答位
INC R1 ;指向下一個接收數據緩沖單元
SJMP RDN1 ;轉讀入下一個字節數據
CACK: SETB VSDA ;置VSDA為輸入方式
SETB VSCL ;使VSDA上數據有效
CLR F0 ;預設F0=0
MOV C,VSDA ;輸入VSDA引腳狀態
JNC CEND ;檢查VSDA狀態,正常應答轉CEND,且F0=0
SETB F0 ;無正常應答,F0=1
CEND: CLR VSCL ;子程序結束,使VSCL=0
RET
MACK: CLR VSDA;發送應答位MACK子程序
SETB VSCL
NOP
NOP
CLR VSCL
SETB VSDA
RET
MNACK: SETB VSDA ;發送非應答位 MNACK子程序
SETB VSCL
NOP
NOP
CLR VSCL
CLR VSDA
RET
;從VSDA上接收一個字節數據(RDBYT)子程序,該子程序用來從VSDA上讀取一個字節數據.執行本程序后,從VSDA上讀取的一個字節存放在R2或A中。資源占用:R0,R2,C。
RDBYT: MOV R0,#08H ;8位數據長度如R0
RLP: SETB VSDA ;置VSDA為輸入方式
SETB VSCL ;使VSDA上數據有效
MOV C,VSDA ;讀入VSDA引腳狀態
MOV A,R2 ;讀入"0"程序段,由C拼裝入R2中
RLC A
MOV R2,A
CLR VSCL ;使VSCL=0可繼續接收數據位
DJNZ R0,RLP ;8位讀完否?未讀完轉RLP
RET
STAA: SETB VSDA;啟動STAA子程序
SETB VSCL
NOP
NOP
CLR VSDA
NOP
NOP
CLR VSCL
RET
STOP:CLR VSDA;停止(STOP)子程序
SETB VSCL
NOP
NOP
SETB VSDA
NOP
NOP
CLR VSDA
CLR VSCL
RET
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -