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

📄 iicmstr.asm

📁 MICROCHIP 實現I2C的 Master 端 (Firmware) 及 Slave 端 (Hardware) 相對應的程式範例
💻 ASM
字号:
        LIST P=16C74A
	TITLE "I2C interface PICmicro to serial EEPROM"
;
;
;*****************************************************************************
;**  Two wire/I2C Bus READ/WRITE Sample Routines of Microchip's
;**  24Cxx / 85Cxx serial CMOS EEPROM interfacing to a 
;**  PIC16C74 8-bit CMOS single chip microcomputer
;**  Revised Version  (3/1/94).
;**
;**  Note:  1) All timing is based on a reference crystal frequency of 4MHz
;**            which is equivalent to an instruction cycle time of 1 usec.
;**         2) Address and literal values are read in hexidecimal unless 
;**            otherwise specified.
;*****************************************************************************
;
;-----------------------------------------------------------------------------
;       Register File Assignment
;-----------------------------------------------------------------------------
;
	#include <P16C74a.INC>
;
FLAG    equ     20              ; Common flag bits register
EEPROM  equ     21              ; Bit buffer
ERCODE  equ     22              ; Error code (to indicate bus status)
ADDR    equ     23              ; Address register
DATAI   equ     24              ; Stored data input register
DATAO   equ     25              ; Stored data output register
SLAVE   equ     26              ; Device address (1010xxx0)
TXBUF   equ     27              ; TX buffer
RXBUF   equ     28              ; RX buffer
COUNT   equ     29              ; Bit counter
TEMP	equ	2A		; Temporary storage
TEMP1	equ	2B		; More Temporary storage
;
;-----------------------------------------------------------------------------
;                     Bit Assignments
;-----------------------------------------------------------------------------
;
; FLAG Bits
;
ERRORFLG EQU     0               ; Error flag
;
; EEPROM Bits
;
DI      EQU     7               ; EEPROM input
DO      EQU     6               ; EEPROM output
;
; I2C Device Bits
;
SDA     EQU     4               ; RB7, data in/out
SCL     EQU     3               ; RB6, serial clock

;------------------------------------------------------------------------------
;			Vector Assignment
;------------------------------------------------------------------------------

	ORG	00h		; Reset Vector
	goto	Start
;
	ORG	04h		; Interrupt Vector
	goto	Service_int	; Not actually used by this program
;
	ORG	10h		; Begining of Program space

;------------------------------------------------------------------------------
;			Main Program
;------------------------------------------------------------------------------
Start
	clrf	FLAG
	clrf	ERCODE
	bsf	STATUS,RP0	; Select Page 1
	clrf	TRISB		; Set PORT_B as all outputs
	movlw	0FFh		; Set PORT_B as all inputs
	movwf	TRISC
	bcf	STATUS,RP0	; Select Page 0
	movlw	01h		
	movwf	PORTB		; Light first LED
 	movlw	B'00111011'	; I2C master mode enabled
 	movwf	SSPCON
	movlw	B'00000000'	; Disable interrupts
	movwf	INTCON
	movlw	B'00000000'	; Disable all interrupts
	movwf	PIE1
	clrf 	PORTC		; Set SCL, SDA to low when not in tri-state
Bigloop
	movf    PORTB,W	
	movwf	DATAO		; Output Data
;	movlw	00h		; EEPROM data address
;	movwf	ADDR
;	movlw	B'10100000'	; EEPROM I2C address
	movlw	B'00001110'
	movwf	SLAVE
Wrtloop
	call 	WRBYTE		; Output byte to EEPROM
	btfsc	FLAG,ERRORFLG	; Check for error
	goto	Errorloop
	call	Delay		; 10mS Delay for 24LC01 EEPROM write delay
;	incf	ADDR, F   	; Point to next address
;	btfss	ADDR,7		; Check if at end of EEPROM
;	goto	Wrtloop

	bcf	STATUS,RP0	; Address page 1
;	movlw	00h		; EEPROM data address
;	movwf	ADDR		
;	movlw	B'10100000'	; EEPROM I2C address
	movlw	B'00001111'
	movwf	SLAVE
Rdloop
	call	RDBYTE		; Input byte from EEPROM
	btfsc	FLAG,ERRORFLG	; Check for error
	goto	Errorloop	
	movf	DATAI,W		; Get received byte
	xorlw	B'11111111'	; Add by Steven Lin 032099
	subwf	PORTB,W	        ; Make sure correct data read
	btfss	STATUS,Z
	goto	Errorloop
;	incf	ADDR, F		; Point to next address
;	btfss	ADDR,7		; Check if at end of EEPROM;
;	goto	Rdloop	
	incf	PORTB, F	; Increment value displayed on LEDs
	goto	Bigloop

Errorloop
	clrf	PORTB		; Turn off all LEDs
Errloop1
	call	Delay		; Delay so that flashing of LEDs 
	call	Delay		;	is apparent
	call	Delay
	call	Delay
	call	Delay
	call	Delay
	comf	PORTB, F	; Change state of all LEDs
	goto	Errloop1

Service_int			; Interrupts are not used
	return


;-----------------------------------------------------------------------------
;       BYTE-WRITE, write one byte to EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       DATAO   = data to be written
;                       ADDR    = EEPROM data address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       Data written to EEPROM device
;-----------------------------------------------------------------------------
 
WRBYTE
	bcf	STATUS,RP0
	movf    SLAVE,W         ; Put SLAVE address
	movwf   TXBUF           ;  in xmit buffer
	call    BSTART          ; Generate START bit
	call    TX              ; Output SLAVE address
;	bcf	STATUS,RP0
;	movf    ADDR,W          ; Put WORD address
;	movwf   TXBUF           ;  in xmit buffer
;	call    TX              ; Output WORD address
	bcf	STATUS,RP0
	movf    DATAO,W         ; Move DATA 
	movwf   TXBUF           ; into buffer
	call    TX              ; Output DATA and detect acknowledgement
	call    BSTOP           ; Generate STOP bit
	return

;-----------------------------------------------------------------------------
;       TRANSMIT 8 data bits subroutine
;-----------------------------------------------------------------------------
;       Input   :       TXBUF
;       Output  :       Data transmitted to EEPROM device
;-----------------------------------------------------------------------------
 
TX
	bcf	STATUS,RP0
	movlw   .8		; Set counter for eight bits
	movwf   COUNT

TXLP
	bcf     EEPROM,DO       ; Default 0 bit out
	btfsc   TXBUF,7         ; If shifted bit = 0, data bit = 0
	bsf     EEPROM,DO       ;  otherwise data bit = 1
	call    BITOUT          ; Send bit
	bcf	STATUS,RP0
	rlf     TXBUF, F        ; Rotate TXBUF left
	skpc                    ; f(6) ---> f(7)
	bcf     TXBUF,0         ; f(7) ---> carry
	skpnc                   ; carry ---> f(0)
	bsf     TXBUF,0
	decfsz  COUNT, F        ; 8 bits done?
	goto    TXLP            ; No.
	call    BITIN           ; Read acknowledge bit
	bcf	STATUS,RP0
	movlw   3
	btfsc   EEPROM,DI       ; Check for acknowledgement
	call    ERR             ; No acknowledge from device
	bcf	STATUS,RP0
	retlw   0


;-----------------------------------------------------------------------------
;       Single bit data transmit from PIC to serial EEPROM 
;-----------------------------------------------------------------------------
;       Input   :       EEPROM register, bit DO
;       Output  :       Bit transmitted over I2C
;			Error bits set as necessary
;-----------------------------------------------------------------------------

BITOUT
	btfss   EEPROM,DO
	goto    BIT0
	bsf	STATUS,RP0
	bsf     TRISC,SDA	; Output bit 0
	nop
	movlw   2
	bcf	STATUS,RP0
	btfsc   PORTC,SDA	; Check for error code 2
	goto    CLK1
	call	ERR
	goto    CLK1		; SDA locked low by device

BIT0
	bsf	STATUS,RP0
	bcf	TRISC,SDA	; Output bit 0
	nop			; Delay
CLK1
	bsf	STATUS,RP0
	bsf     TRISC,SCL	; Attempt to set SCL high
	NOP			;STEVEN LIN
	NOP
	NOP
	NOP			
	NOP
	NOP
	movlw   1         	; Error code 1
	bcf	STATUS,RP0
	btfsc    PORTC,SCL	; SCL locked low?
	goto    BIT2		; No.
	call 	ERR		; Yes, set error
BIT2
	nop			; Timing delay
	nop
	bsf	STATUS,RP0
	bcf     TRISC,SCL      ; Return SCL to low
	nop
	bcf	STATUS,RP0
	retlw   0

;-----------------------------------------------------------------------------
;       BYTE-READ, read one byte from serial EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       ADDR    = source address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       DATAI   = data read from serial EEPROM
;-----------------------------------------------------------------------------
;
RDBYTE
	bcf	STATUS,RP0
	movf    SLAVE,W         ; Move SLAVE address 
	movwf   TXBUF           ;  into xmit buffer (R/W = 0)
	call    BSTART          ; Generate START bit
	call    TX              ; Output SLAVE address. Check ACK.
;	bcf	STATUS,RP0
;	movf    ADDR,W          ; Move WORD address
;	movwf   TXBUF		;  into xmit buffer
;	call    TX              ; Output WORD address. Check ACK.
;	call    BSTART          ; START READ (if only one device is
;	bcf	STATUS,RP0	; connected to the I2C bus)
;	movf    SLAVE,W         
;	movwf   TXBUF
;	bsf     TXBUF,0         ; Specify READ mode (R/W = 1)
;	call    TX              ; Output SLAVE address
	call    RX              ; READ in data and acknowledge
	call    BSTOP           ; Generate STOP bit
	bcf	STATUS,RP0
	movf    RXBUF,W         ; Save data from buffer
	movwf   DATAI           ; to DATAI file register.
	return

;
;-----------------------------------------------------------------------------
;       RECEIVE eight data bits subroutine
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       RXBUF = 8-bit data received
;-----------------------------------------------------------------------------
;
RX
	bcf	STATUS,RP0
	movlw   .8              ; 8 bits of data
	movwf   COUNT
	clrf    RXBUF
;
RXLP
	rlf     RXBUF, F        ; Shift data to buffer
	skpc
	bcf     RXBUF,0         ; carry ---> f(0)
	skpnc
	bsf     RXBUF,0
	call    BITIN
	bcf	STATUS,RP0
	btfsc   EEPROM,DI
	bsf     RXBUF,0         ; Input bit =1
	decfsz  COUNT, F        ; 8 bits?
	goto    RXLP
	bsf     EEPROM,DO       ; Set acknowledge bit = 1
	call    BITOUT          ; to STOP further input
	retlw   0

;
;-----------------------------------------------------------------------------
;       Single bit receive from serial EEPROM to PIC
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       Data bit received
;-----------------------------------------------------------------------------
;
BITIN
	bsf	STATUS,RP0
	bsf     TRISC,SDA  	; Set SDA for input
	nop
	bcf	STATUS,RP0
	bcf     EEPROM,DI
	bsf	STATUS,RP0
	bsf     TRISC,SCL  	; Clock high
	nop
	movlw   1
	bcf	STATUS,RP0
	btfsc   PORTC,SCL   	; Skip if SCL  is high
	goto    BIT1
	call 	ERR
BIT1
	bcf	STATUS,RP0
	nop			;by steven Lin
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	btfss   PORTC,SDA       ; Read SDA pin, for ACK low
	goto 	ACKOK
	bsf     EEPROM,DI       ; DI = 1
ACKOK
	bsf	STATUS,RP0
	nop                     ; Delay
	bcf     TRISC,SCL       ; Return SCL to low
	nop     
	bcf	STATUS,RP0
	retlw   0

;-----------------------------------------------------------------------------
;       DELAY, Provide a 10.78mS delay
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       None
;-----------------------------------------------------------------------------

Delay
	bcf	STATUS,RP0
	movlw	7
	movwf	TEMP1
	clrf    TEMP            ;clear last location
dly1
	nop
	nop
	nop
	decfsz  TEMP, F         ;reduce count
	goto    dly1            ;Inner loop time = 1.54mS
	decfsz	TEMP1, F
	goto	dly1		;Total time = 10.78mS
	retlw   0
 
;-----------------------------------------------------------------------------
;       START bit generation routine
;-----------------------------------------------------------------------------
;       input   : none
;       output  : initialize bus communication
;-----------------------------------------------------------------------------
;
;Generate START bit (SCL is high while SDA goes from high to low transition)
;and check status of the serial clock.
BSTART
	bsf	STATUS,RP0
	bsf     TRISC,SDA	; Make sure SDA is high
	nop
	bsf     TRISC,SCL	; Set clock high
	nop
	movlw   1               ; Ready error status code 1
	bcf	STATUS,RP0
	btfss   PORTC,SCL 	; Locked?
	call    ERR             ; SCL locked low by device, flag error
	bsf	STATUS,RP0
	bcf     TRISC,SDA 	; SDA goes low during SCL high
	nop                     ; Timing adjustment, 1uS @4MHz
	bcf     TRISC,SCL	; Start clock train
	nop
	bcf	STATUS,RP0
	RETLW   0
 
;-----------------------------------------------------------------------------
;       STOP bit generation routine
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       Bus communication, STOP condition
;-----------------------------------------------------------------------------
;
;Generate STOP bit (SDA goes from low to high during SCL high state)
;and check bus conditions.
 
BSTOP
	bsf	STATUS,RP0
	bcf     TRISC,SDA	; Return SDA to low
	nop
	bsf     TRISC,SCL	; Set SCL high
	nop
	movlw   1               ; Ready error code 1
	bcf	STATUS,RP0
	btfss   PORTC,SCL 	; High?
	call    ERR             ; No, SCL locked low by device
	bsf	STATUS,RP0
	bsf     TRISC,SDA  	; SDA goes from low to high during SCL high
	nop
	movlw   4               ; Ready error code 4
	btfss   TRISC,SDA  	; High?
	call    ERR             ; No, SDA bus not release for STOP
	bcf	STATUS,RP0
	retlw   0
;
;-----------------------------------------------------------------------------
;       Two wire/I2C - CPU communication error status table and subroutine
;-----------------------------------------------------------------------------
;  input  :     W-reg   = error code
;  output :     ERCODE  = error code
;           FLAG(ERROR) = 1
;
;         code          error status mode
;       -------         ------------------------------------------------------
;           1   :       SCL locked low by device (bus is still busy)
;           2   :       SDA locked low by device (bus is still busy)
;           3   :       No acknowledge from device (no handshake)
;           4   :       SDA bus not released for master to generate STOP bit
;-----------------------------------------------------------------------------
;
;Subroutine to identify the status of the serial clock (SCL) and serial data
;(SDA) condition according to the error status table. Codes generated are
;useful for bus/device diagnosis.
;
ERR
	bcf	STATUS,RP0
	btfss   FLAG,ERRORFLG   ; If not first error, do not change code
	movwf   ERCODE          ; Save error code
	bsf     FLAG,ERRORFLG   ; Set error flag
	retlw   0

	END

⌨️ 快捷键说明

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