⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slave.asm

📁 51开发板典藏版源代码+升级 里面有源代码
💻 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 + -