?? i^2c.asm
字號:
SCL EQU P2.1 ;串行時鐘線
SDA EQU P2.0 ;串行數據線
ANSW BIT 10H ;應答信號
SEND_BUF EQU 30H ;發送緩沖區
RECV_BUF EQU 40H ;發送緩沖區
IC_ADDR EQU 50H ;器件地址
IC_SUB_ADDR EQU 51H ;器件子地址
BYTE_NUM EQU 52H ;發送字節數
ATMEL24C02 EQU 0A0H
ORG 0000H
AJMP MAIN
ORG 0080H
START: MOV R4,#0F0H
DJNZ R4,$
MOV 60H,#3
;
MAIN:
MOV IC_ADDR,#ATMEL24C02
MOV IC_SUB_ADDR,#30H
MOV BYTE_NUM,#01H
MOV SEND_BUF,#58H
LCALL WR_N_BYTE
MOV IC_SUB_ADDR,#30H
MOV BYTE_NUM,#01H
MOV SEND_BUF,#58H
LCALL RD_N_BYTE
MOV A,RECV_BUF
XRL A,#58H
JZ EXIT1
CLR P2.3
LCALL DELAY
SETB P2.3
SJMP MAIN
EXIT1: CLR P2.3
LCALL DELAY
SETB P2.3
LCALL DELAY
CLR P2.3
LCALL DELAY
SETB P2.3
MOV R0,60H
DEC R0
MOV 60H,R0
CJNE R0,#0,START
SJMP MAIN
;---------------------------------------------
;向器件指定地址發送N個數據
;入口參數:器件地址:IC_ADDR,器件子地址:IC_SUB_ADDR,發送緩沖區:SEND_BUF ,發送字節數:BYTE_NUM
;占用 A R0 R1 R3 CY
WR_N_BYTE:
LCALL DELAY
MOV R3,BYTE_NUM ;發送字節數
LCALL S_START ;啟動總線
MOV A,IC_ADDR ;送器件地址
LCALL WR_BYTE ;發送器件地址
LCALL CHK_ANSW
JNB ANSW,WR_EXIT ;無應答,退出
MOV A,IC_SUB_ADDR ;發送器件存儲地址
LCALL WR_BYTE
LCALL CHK_ANSW
JNB ANSW,WR_EXIT ;無應答,退出
LCALL DELAY
CPL p1.0
MOV R1,#SEND_BUF ;發送緩沖區地址
WR_DATA: MOV A,@R1
LCALL WR_BYTE ;寫數據
LCALL CHK_ANSW
LCALL DELAY
CPL P1.2
JNB ANSW,WR_N_BYTE
INC R1
LCALL DELAY
CPL P1.4
DJNZ R3,WR_DATA ;判斷是否發送完
WR_EXIT: LCALL DELAY
CPL p1.6
LCALL S_STOP
CLR P2.3
LCALL DELAY
SETB P2.3
RET
;---------------------------------------------
;向器件指定地址讀取N個數據
;入口參數:器件地址:IC_ADDR,器件子地址:IC_SUB_ADDR,接收字節數:BYTE_NUM
;出口參數:接收緩沖區:RECV_BUF
;占用 A R0 R1 R2 R3 CY
RD_N_BYTE: MOV R3,BYTE_NUM
LCALL DELAY
LCALL S_START ;啟動總線
MOV A,IC_ADDR
LCALL WR_BYTE ;發送器件地址
LCALL CHK_ANSW
JNB ANSW,RD_EXIT ;無應答,退出
LCALL DELAY
CPL P1.1
MOV A,IC_SUB_ADDR ;發送器件存儲地址
LCALL WR_BYTE
LCALL CHK_ANSW
JNB ANSW,RD_EXIT ;無應答,退出
LCALL DELAY
CPL P1.3
LCALL S_START ;重新啟動總線
MOV A,IC_ADDR
INC A ;地址加一,變為讀地址
LCALL WR_BYTE
LCALL CHK_ANSW
JNB ANSW,RD_EXIT
LCALL DELAY
CPL P1.5
MOV R1,#RECV_BUF ;接收緩沖區地址
MOV A,@R1
RD_DATA: LCALL RD_BYTE ;讀操作開始
MOV @R1,A
DJNZ R3,RD_ANSW ;判斷是否完
LCALL SEND_NANSW ;最后一個字節發非應答信號
SJMP RD_EXIT
RD_ANSW: LCALL SEND_ANSW ;發送應答信號
INC R1
SJMP RD_DATA
RD_EXIT: LCALL S_STOP ;結束總線
LCALL DELAY
CPL P1.7
RET
WR_BYTE: MOV R0,#8 ;發送一個字節
WR_LOOP: RLC A
JC WR_1
WR_0: CLR SDA ;發送0
NOP
SETB SCL
LCALL NOP_5
CLR SCL
NOP
SJMP WR_LOOP1
WR_1: SETB SDA ;發送1
NOP
SETB SCL
LCALL NOP_5
CLR SCL
NOP
WR_LOOP1: DJNZ R0,WR_LOOP
NOP
RET
RD_BYTE: MOV R0,#8 ;接收一個字節,暫存于R2
RD_LOOP: SETB SDA
NOP
SETB SCL ;時鐘線置高,接收數據
NOP
NOP
MOV C,SDA ;讀取數據
MOV A,R2
CLR SCL ;拉低時鐘線
RLC A
MOV R2,A
NOP
NOP
NOP
DJNZ R0,RD_LOOP
RET
S_START: SETB SDA ;啟動總線
NOP
SETB SCL
LCALL NOP_5
CLR SDA
LCALL NOP_5
CLR SCL ;鉗住總線,準備發送
NOP
RET
S_STOP: CLR SDA ;結束總線
NOP
SETB SCL
LCALL NOP_5
SETB SDA
LCALL NOP_5
RET
SEND_ANSW: CLR SDA ;應答信號
NOP
NOP
SETB SCL
LCALL NOP_5
CLR SCL
NOP
RET
SEND_NANSW: SETB SDA ;非應答信號
NOP
NOP
SETB SCL
LCALL NOP_5
CLR SCL
NOP
RET
CHK_ANSW: SETB SDA ;檢查應答信號
CLR ANSW
MOV R0,#3
SETB SCL
CHKLOOP: MOV C,SDA
JNC CHK1
DJNZ R0,CHKLOOP
SJMP CHK_OVER
CHK1: SETB ANSW
CHK_OVER: NOP
CLR SCL
RET
NOP_5: NOP
NOP
NOP
NOP
RET
DELAY: MOV R7,#10
DL1: MOV R6,#200
DL2: MOV R5,#250
DL3: DJNZ R5,DL3
DJNZ R6,DL2
DJNZ R7,DL1
RET
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -