?? slave.asm
字號:
;;;;;;;;;;;;;;;;I2C讀寫的子程序是老外寫的,俺們只是看明白了,然后調用。;;;;;;;;;;;;;;;;;;;;;;;;;
SDA BIT P3.7 ;THE SDA BIT IS PORT 1 BIT 0
SCL BIT P3.5 ;THE SCL BIT IS PORT 1 BIT 1
IIC_ADL EQU 70H ;LOCATION FOR 2404 ADDRESS TO ACCESS
IIC_ADH EQU 71H
IIC_CT EQU 72H ;COUNTER VARIABLE
IIC_TP EQU 73H ;SCRATCH PAD BYTE
IIC_CT2 EQU 74H ;COUNTER FOR ACK POLLING
ORG 0000H
jmp BEGIN
org 0003h ;外部中斷0的中斷響應地址。
EXT_INT0: jmp INT0ADDRESS ;
org 0023h ;串行中斷的中斷響應地址。
COMM_INT: jmp INTCOMM ;
org 0100h ;
BEGIN: MOV SP,#80H ;
call COMMINITIALIZATION ;
call ENABLEINT0 ;
clr c ;
mov p3.4,c ;AT89C52控制串口。
JMP $
COMMINITIALIZATION:
mov TMOD,#20h ;設置定時器T1工作方式2。
mov TL1,#0F3h ;定時器計數初值,波特率2400。
mov TH1,#0F3h ;定時器重裝值。
setb EA ;允許總的中斷。
setb ES ;允許串行中斷。
mov PCON,#00h ;波特率不倍增。
mov SCON,#50h ;設置串口工作方式1,REN=1,允許接收。
setb TR1 ;定時器開始工作。
ret ;返回。
ENABLEINT0: clr IE0 ;清除外部中斷0標志。
setb IT0 ;設置外部中斷0為負脈沖觸發方式。
setb EX0 ;允許外部中斷0。
setb EA ;允許全部中斷。
ret ;
INTCOMM: clr ES ;屏蔽串口中斷。
clr EA ;屏蔽所有中端。
mov a,SBUF ;讀數,清空接收緩沖區。
clr RI ;清除串口接收標志。
mov b,a ;暫存。
clr c ;清除c。
mov a,b ;
subb a,#0CCh ;
jz WRIREI2C; ;
clr c ;清除c。
mov a,b ;
subb a,#0CDh ;
jz READI2C ;
setb EA ;
reti ;
WRIREI2C: jnb RI,WRIREI2C ;
mov a,SBUF ;
clr RI ;
mov IIC_ADL,a ;
WRIREI2C_1: jnb RI,WRIREI2C_1 ;
mov a,SBUF ;
clr RI ;
call WRBYT ;
call ACKPOL ;
clr c ;
mov p3.4,c ;釋放串口。
setb ES ;
setb EA ;
reti ;
READI2C: jnb RI,READI2C ;
mov a,SBUF ;
clr RI ;
mov IIC_ADL,a ;
call RDBYT ;
mov SBUF,a ;
READI2C_1: jnb TI,READI2C_1 ;
clr TI ;
clr c ;
mov p3.4,c ;釋放串口。
setb ES ;
setb EA ;
reti ;
INT0ADDRESS: setb c ;
mov p3.4,c ;AT89C4051控制串口。
nop ;
nop ;
reti ;
;*********************************************************************
; READ A BYTE "RANDOM READ SEQUENCE". THE ADDRESS TO READ IS STORED *
; IN IIC_AD. THE DATA FROM THE DUT IS STORED IN IIC_DA. *
;*********************************************************************
RDBYT: LCALL START ; READ A BYTE FROM THE ADDRESS INDICATED
MOV A,IIC_ADH ; IN 'IIC_AD'
CLR C
RLC A
ORL A,#0A0H ; BUILD SLAVE ADDRESS FOR WRITE
MOV IIC_TP,A
LCALL OUTBYT ; SEND SLAVE ADDRESS
LCALL ACK ; SEND ACKNOWLEDGE
MOV A,IIC_ADL
LCALL OUTBYT ; SEND WORD ADDRESS
LCALL ACK ; SEND ACKNOWLEDGE
LCALL START ; SEND START COMMAND
MOV A,IIC_TP ; BUILD SLAVE ADDRESS FOR READ
ORL A,#01H ; R/W BIT = 1
LCALL OUTBYT ; SEND SLAVE ADDRESS
LCALL ACK ; SEND ACKNOWLEDGE
LCALL INBYT ; READ DATA FROM 2404
LCALL NACK ; CLOCK WITHOUT ACKNOWLEDGE
LCALL STOP ; SEND STOP COMMAND
RET
;**********************************************************************
; WRITE A BYTE "BYTE WRITE SEQUENCE". THE ADDRESS TO WRITE IS STORED *
; IN IIC_AD. THE DATA TO WRITE IS STORED IN IIC_DA. *
;**********************************************************************
WRBYT: ; WRITE TO BYTE POINTED TO BY ADDR THE
MOV IIC_TP,A ; VALUE IN LOCATION 'DATA'
LCALL START ; SEND START COMMAND
MOV A,IIC_ADH ; BUILD SLAVE ADDRESS FOR WRITE
CLR C
RLC A
ORL A,#0A0H
LCALL OUTBYT ; SEND SLAVE ADDRESS
LCALL ACK ; SEND ACKNOWLEDGE
MOV A,IIC_ADL
LCALL OUTBYT ; SEND WORD ADDRESS
LCALL ACK ; SEND ACKNOWLEDGE
MOV A,IIC_TP
LCALL OUTBYT ; SEND WRITE DATA
LCALL ACK ; SEND ACKNOWLEDGE
LCALL STOP ; SEND STOP
RET
;***************************************************************
; READ 8 BITS FROM THE DUT. THE RESULTS ARE RETURNED IN IIC_DA. *
;***************************************************************
INBYT: SETB SDA ; READ 8 BITS, MAKE SDA AN INPUT
MOV IIC_CT,#08H
LOOPI: LCALL CLOCK ; CLOCK DATA
RLC A ; ROLL IN NEXT BIT FROM DUT
DJNZ IIC_CT,LOOPI ; LOOP UNTIL 8 BITS ARE READ
RET
;*********************************************************
; WRITE 8 BITS TO THE DUT. THE DATA TO SEND IS IN IIC_DA. *
;*********************************************************
OUTBYT: MOV IIC_CT,#08H ; PREPARE TO SHIFT OUT 8 BITS
LOOPO: RLC A ; ROTATE BIT TO SEND INTO CARRY FLAG
MOV SDA,C ; SEND CARRY TO SDA
LCALL CLOCK ; SEND CLOCK SIGNAL TO DUT
DJNZ IIC_CT,LOOPO ; LOOP UNTIL ALL 8 BITS HAVE BEEN SENT
RET
;*********************************************************************
; PERFORM ACKNOWLEDGE POLLING TO DETERMINE WHEN THE WRITE CYCLE *
; COMPLETES. UPON RETURN FROM THIS ROUTINE THE CARRY BIT INDICATES *
; WHETHER THE DUT EVER ACKNOWLEDGED THE WRITE. CARRY=0 PART *
; ACKNOWLEDGED, CARRY=1 NO ACKNOWLEDGE RECEIVED. *
;*********************************************************************
ACKPOL: MOV IIC_CT2,#080H ; MAX NUMBER OF TIMES TO CHECK THE PART
AKLOOP: DJNZ IIC_CT2,LOOK ; RETURN IF THE PART
SJMP OUTACK ; NEVER ISSUES AN ACKNOWLEDGE.
LOOK: LCALL START ; SET UP FOR A READ
MOV A,#0A0H ; MAKE SLAVE ADDRESS FOR A READ
LCALL OUTBYT ; SEND SLAVE ADDRESS
LCALL NACK ; SEND ACKNOWLEDGE
JC AKLOOP ; LOOP IF NO ACKNOWLEDGE RECEIVED
OUTACK: LCALL STOP ; ISSUE A STOP BEFORE RETURNING
RET
;***********************
; ISSUE A STOP COMMAND *
;***********************
STOP: CLR SDA ; SEND STOP CONDITION TO DUT, SDA LOW
SETB SCL ; SCL HIGH
NOP ; MAKE SUTE THE SET UP TIME IS VALID
NOP
NOP
NOP
SETB SDA ; SDA HIGH
RET
;************************
; ISSUE A START COMMAND *
;************************
START: SETB SDA ; SEND START CONDITION TO DUT, SDA HIGH
SETB SCL ; SCL HIGH
NOP ; MAKE SURE SCL SET UP TIME IS VALID
NOP
NOP
NOP
CLR SDA ; SDA LOW
NOP ; MAKE SURE THE SET UP TIME IS VALID
NOP
NOP
NOP
CLR SCL ; SCL LOW
RET
;********************************************************
; ISSUE AN ACKNOWLEDGE. THE ACK ROUTINE DOES NOT CHECK *
; TO SEE IF THE DUT ACTUALLY ISSUES AN ACKNOWLEDGE. *
;********************************************************
ACK: CLR SDA ; PERFORM AN ACKNOWLEDGE, SDA LOW
LCALL CLOCK ; GENERATE A CLOCK PULSE
RET
;*********************************************
; CLOCK IN A 1 TO THE DUT. THIS ROUTINE IS *
; CALLED WHEN A READ SEQUENCE HAS FINISHED. *
;*********************************************
NACK: SETB SDA ; CLOCK A 1 INTO THE DUT, SDA HIGH
LCALL CLOCK ; GENERATE A CLOCK PULSE
RET
;*****************************************************************
; ISSUE A CLOCK PULSE. WHILE THE CLOCK IS HIGH THE VALUE ON THE *
; SDA LINE IS PLACED IN THE CARRY FLAG. WHEN A READ IS TAKING *
; PLACE THE CARRY FLAG WILL INDICATE THE VALUE FROM THE DUT. *
;*****************************************************************
CLOCK: NOP ; MAKE SURE THE DATA SET UP TIME IS VALID
SETB SCL ; GENERATE A CLOCK PULSE, SCL HIGH
NOP ; MAKE SURE CLOCK HIGH TIME IS VALID
NOP
NOP
MOV C,SDA ; READ STATE ON SDA, SAVE IN CARRY FLAG
CLR SCL ; SCL LOW
RET
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -