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

📄 i2cmstr.asm

📁 ADuc812的例程
💻 ASM
字号:
;======================================================================
;
; Author        : ADI - Apps              www.analog.com/MicroConverter
;
; Date          : Oct 2000
;
; File          : i2Cmstr.asm
;
; Hardware      : ADuC812 (commented out = ADuC824/ADuC816)
;
; Description   : Code for a master in an I2C system. This code will
;               continuously receive and transmit a byte over the I2C
;               interface, then send the received byte out the UART,
;               then check if a character had been entered in the UART,
;               if so, it will send the ASCII value of the character
;               entered to the slave, the next time it transmits a byte.
;
; Reference     : Tech Note, uC001: "MicroConverter I2C Compatible
;               Interface" find it at www.analog.com/microconverter

;
;======================================================================

$MOD812                         ; use ADuC812 & 8052 predefined symbols
;$MOD816
;$MOD824

;____________________________________________________________________
                                   ; DEFINE VARIABLES IN INTERNAL RAM

BITCNT          DATA    30h     ; bit counter for I2C routines
SLAVEADD        DATA    31h     ; slave address for I2C routines
INPUT           DATA    32h     ; data recieved from the slave
OUTPUT          DATA    33h     ; data to be transmitted to slave

NOACK           BIT     00h     ; I2C no acknowledge flag
ERR		BIT     00h     ; I2C error flag

LED	        EQU     P3.4

;____________________________________________________________________
                                                  ; BEGINNING OF CODE
CSEG
ORG 0000h
	JMP MAIN
;____________________________________________________________________
                                                           ; INT0 ISR
ORG 0003h
        INC     OUTPUT
        RETI
;____________________________________________________________________
                                                       ; MAIN PROGRAM
ORG 0060h
MAIN:

; configure the UART ADuC812
        MOV     SCON,#52h       ; configure UART for 9600baud..
        MOV     TMOD,#20h       ; ..assuming 11.0592MHz crystal
        MOV     TH1,#-3
        SETB    TR1

; configure the UART ADuC824/ADuC816
;        MOV     RCAP2H,#0FFh   ; config UART for 9830baud
;        MOV     RCAP2L,#-5     ; (close enough to 9600baud)
;        MOV     TH2,#0FFh
;        MOV     TL2,#-5
;        MOV     SCON,#52h
;        MOV     T2CON,#34h

; configure & enable interrupts
        SETB    EX0             ; enable INT0
        SETB    IT0             ; INT0 edge triggered
        SETB    EA              ; allow all the interrupts

; initialise settings
        MOV     SLAVEADD,#88H   ; clear RW bit
        MOV     I2CCON,#0A8h    ; sets SDATA & SCLOCK, and
				; selects master mode
        MOV     OUTPUT,#0       ; TX 0 as default
        CLR     NOACK
	CLR     ERR
	

RXTXLOOP:    
; code for a read mode ( master recieves one byte from slave )
        CALL    RCVDATA         ; sends start bit
                                ; sends address byte
				; checks acknowledge
				; receives byte into ACC
                                ; checks ACK
				; sends stop bit

; code for write mode ( master transmits one byte to slave )
        CALL    SENDDATA        ; sends start bit
                                ; sends address byte
				; checks acknowledge
				; transmits ACC
                                ; checks ACK
				; sends stop bit

; Check for Error message
	JB	ERR,SENDERR	; if error, send error message

; Transmit received byte (INPUT) up UART to PC (hyperterminal)
	MOV	A,INPUT		; put value recieved into ACC
	CALL	SENDVAL		; send value recieved out the UART
	JMP	SKIP

SENDERR:
        CALL	ERROR		; send error message out the UART
	CLR     ERR		; clear error flag

SKIP:
	MOV	A,#10           ; send LF+CR
	CALL    SENDCHAR
	MOV	A,#13
	CALL    SENDCHAR

; Toggle LED (1s delay so that LED can be seen toggle)
	MOV	A, #10
	CALL    DELAY
	CPL	LED

; Check for new OUTPUT
	JNB     RI, RXTXLOOP    ; repeat (unless UART data received)


; If UART data received, then save to OUTPUT
        MOV     OUTPUT,SBUF     ; update OUTPUT byte to new value
        CLR     RI              ; must clear RI
        JMP     RXTXLOOP        ; back to main loop

	

;====================================================================
;                             SUBROUTINES
;====================================================================

;____________________________________________________________________
                                                           ; SENDDATA
; Send all the sequence to the slave (slave address + data (OUTPUT))

SENDDATA:
        ; send start bit
        CALL    STARTBIT        ; acquire bus and send slave address

        ; send slave address
        MOV     A, SLAVEADD
        CALL    SENDBYTE        ; sets NOACK if NACK received

        JB      NOACK, STOPSEND	; if no acknowledge send stop

        ; send OUTPUT byte
        MOV     A, OUTPUT
        CALL    SENDBYTE        ; sets NOACK if NACK received

STOPSEND:  
        CALL    STOPBIT         ; sends stop bit
        JNB     NOACK, SENDRET  ; if slave sends no-acknowedge send error
        SETB    ERR             ; sets the error flag
        SETB    I2CRS           ; this resets the I2C interface
SENDRET:
	 RET


;____________________________________________________________________
                                                            ; RCVDATA
; receives one or more bytes of data from an I2C slave device.

RCVDATA:   
	INC     SLAVEADD       	; Set RW for reception

        ; send start bit
        CALL    STARTBIT        ; acquire bus and send slave address

        ; send slave address
        MOV     A, SLAVEADD
        CALL    SENDBYTE        ; sets NOACK if NACK received

        DEC     SLAVEADD       	; put slave back in transmit mode

        JB      NOACK, STOPRCV  ; Check for slave not responding.
	CALL	DELAY5		; this lets slave get data ready 
        CALL    RCVBYTE         ; Receive next data byte.
        MOV     INPUT,A        	; Save data byte in buffer.
        
STOPRCV:      
        CALL    STOPBIT
        JNB     NOACK, RCVRET   ; if slave sends NACK send error
        SETB    ERR             ; sets the error flag
        SETB    I2CRS           ; this resets the I2C interface
RCVRET:	
        RET


;____________________________________________________________________
                                                           ; STARTBIT
; Sends the start bit to initiate an I2C communication

STARTBIT:

        SETB    MDE             ; enable SDATA pin as an output
        CLR     NOACK
        CLR     MDO             ; low O/P on SDATA 
        CALL    DELAY5          ; delay 5 Machine cycles
        CLR     MCO             ; start bit
        RET


;____________________________________________________________________
                                                            ; STOPBIT
; Sends the stop bit to end an I2C transmission

STOPBIT:

        SETB    MDE             ; to enable SDATA pin as an output
        CLR     MDO             ; get SDATA ready for stop
        SETB    MCO             ; set clock for stop
        CALL    DELAY5
        SETB    MDO             ; this is the stop bit
        RET



;____________________________________________________________________
                                                           ; SENDBYTE
; Send 8-bits in ACC to the slave

SENDBYTE:

        MOV     BITCNT,#8       ; 8 bits in a byte
        SETB    MDE             ; to enable SDATA pin as an output	
        CLR     MCO             ; make sure that the clock line is low
SENDBIT:
	RLC     A               ; put data bit to be sent into carry
        MOV     MDO,C           ; put data bit on SDATA line
        SETB    MCO             ; clock to send bit
        CLR     MCO             ; clear clock 
        DJNZ    BITCNT,SENDBIT	; jump back and send all eight bits

        CLR     MDE             ; release data line for acknowledge
        SETB    MCO             ; send clock for acknowledge
	CALL    DELAY5
        JNB     MDI,NEXT        ; this is a check for acknowledge
        SETB    NOACK           ; no acknowledge, set flag		
NEXT:   CLR     MCO             ; clear clock 
	RET



;____________________________________________________________________
                                                            ; RCVBYTE
; receives one byte of data from an I2C slave device.

RCVBYTE:
        MOV     BITCNT,#8       ; Set bit count.
        CLR     MDE             ; to enable SDATA pin as an input	
        CLR     MCO		; make sure the clock line is low
RCVBIT:  
	SETB    MCO		; clock to recieve bit
        CLR     MCO		; clear clock
        MOV     C,MDI           ; read data bit into carry.
        RLC     A               ; Rotate bit into result byte.

        DJNZ    BITCNT,RCVBIT   ; Repeat until all bits received.
				; recieved byte is in the accumulator

        SETB    MDE             ; Data pin of the master must be an..
                                ; ..output for the acknowledge	
        SETB    MDO             ; Send no acknowledge, last byte.
       
	SETB    MCO             ; Send no-acknowledge clock.
        CALL    DELAY5
        CLR     MCO		; clear clock
        RET


;____________________________________________________________________
                                                             ; DELAY5
; Short delay (5 machine cycles incl CALL time) for the main signals
; (SCLOCK , SDATA)

DELAY5:
        NOP
        RET

;____________________________________________________________________
                                                              ; DELAY
; DELAY ROUTINE FOR THE ADuC812/ADuC816/ADuC824
DELAY:			  ; Delays by 100ms * A

; ADuC812 100ms based on 11.0592MHz Core Clock
; ADuC824 100ms based on 1.573MHz Core Clock 

	  MOV   R2,A	   ; Acc holds delay variable
DLY0:	  MOV   R3,#200    ; Set up delay loop0
DLY1:	  MOV   R4,#229    ; Set up delay loop1
;DLY0:	  MOV	R3,#50     ; Set up delay loop0
;DLY1:	  MOV	R4,#131    ; Set up delay loop1
	  DJNZ  R4,$	   ; Dec R4 & Jump here until R4 is 0
                           ; wait here for 131*15.3us=2ms
	  DJNZ  R3,DLY1    ; Dec R3 & Jump DLY1 until R3 is 0
                           ; Wait for 50*2ms
	  DJNZ  R2,DLY0    ; Dec R2 & Jump DLY0 until R2 is 0
                           ; wait for ACC*100ms
	  RET		   ; Return from subroutine

;____________________________________________________________________
                                                              ; ERROR
; this subroutine is run if a NACK is recieved from the slave

ERROR:

	MOV 	A,#45h	
	ACALL	SENDCHAR	; send the letter E out the UART
	RET

;____________________________________________________________________
                                                           ; SENDCHAR
; sends ASCII value contained in A to UART

SENDCHAR:       

        JNB     TI,$            ; wait til present char gone
        CLR     TI              ; must clear TI
        MOV     SBUF,A
        RET


;____________________________________________________________________
                                                          ; HEX2ASCII
; converts A into the hex character representing the value of A's 
; least significant nibble

HEX2ASCII:      

        ANL     A,#00Fh
        CJNE    A,#00Ah,$+3
        JC      IO0030
        ADD     A,#007h
IO0030: ADD     A,#'0'
        RET

        
;____________________________________________________________________
                                                            ; SENDVAL
; converts the hex value of A into two ASCII chars, and then spits 
; these two characters up the UART. does not change the value of A.

SENDVAL: 
        PUSH    ACC
        SWAP    A
        CALL    HEX2ASCII
        CALL    SENDCHAR        ; send high nibble
        POP     ACC
        PUSH    ACC
        CALL    HEX2ASCII
        CALL    SENDCHAR        ; send low nibble
        POP     ACC

        RET

END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -