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

📄 i2c_avr.asm

📁 AVR单片机的典型程序
💻 ASM
字号:
; File Name		I2c_avr.asm"
; Support Email	Per@hum.au.dk
;* Target		: AT90Sxxxx (any AVR device)

;	R e v i s i o n   H I S T O R Y 

;	rev.	date			who	why
;	----	--------------	---	------------------------------------------
;	0.01	May 14, 2001		PB	Start with Atmel app. note
;	0.02	May 19, 2001		PB	Fixing a few bugs with multi byte reads
;	0.10	May 19, 2001		PB	Apperently it works


;*	Main I2C functions :
;*	'i2c_start' -		Issues a start condition and sends address
;*				and transfer direction.
;*	'i2c_rep_start' -	Issues a repeated start condition and sends
;*				address and transfer direction.
;*	'i2c_do_transfer' -	Sends or receives data depending on
;*				direction given in address/dir byte.
;*	'i2c_stop' -		Terminates the data transfer by issue a
;*				stop condition.
;*
;* NOTES
;*	The I2C routines can be called either from non-interrupt or
;*	interrupt routines, not both.
;*
;* STATISTICS
;*	Code Size	: 81 words (maximum)
;*	Register Usage	: 4 High, 0 Low
;*	Interrupt Usage	: None
;*	Other Usage	: Uses two I/O pins on port C
;*	XTAL Range	: N/A

;***************************************************************************
;*
;* FUNCTION
;*	i2c_hp_delay
;*	i2c_qp_delay
;*
;* DESCRIPTION
;*	hp - half i2c clock period delay (normal: 5.0us / fast: 1.3us)
;*	qp - quarter i2c clock period delay (normal: 2.5us / fast: 0.6us)
;*
;*	SEE DOCUMENTATION !!!
;*	Xtal = 2.4576 MHz.
;*
;* USAGE
;*	no parameters
;*
;* RETURN
;*	none
;*
;***************************************************************************

i2c_hp_delay:
		ldi	i2cdelay,3
i2c_hp_delay_loop:
		dec	i2cdelay
		brne	i2c_hp_delay_loop
i2c_qp_delay:
		nop
		ret

;***************************************************************************
;*
;* FUNCTION
;*	i2c_rep_start
;*
;* DESCRIPTION
;*	Assert repeated start condition and sends slave address.
;*
;* USAGE
;*	i2cadr - Contains the slave address and transfer direction.
;*
;* RETURN
;*	Carry flag - Cleared if a slave responds to the address.
;*
;* NOTE
;*	IMPORTANT! : This funtion must be directly followed by i2c_start.
;*
;***************************************************************************

I2c_rep_start:
		sbi	DDRC,SCLP		; force SCL low
		cbi	DDRC,SDAP		; release SDA
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
		rcall	i2c_qp_delay		; quarter period delay

;***************************************************************************
;*
;* FUNCTION
;*	i2c_start
;*
;* DESCRIPTION
;*	Generates start condition and sends slave address.
;*
;* USAGE
;*	i2cadr - Contains the slave address and transfer direction.
;*
;* RETURN
;*	Carry flag - Cleared if a slave responds to the address.
;*
;* NOTE
;*	IMPORTANT! : This funtion must be directly followed by i2c_write.
;*
;***************************************************************************

I2c_start:	mov	i2cdata,i2cadr	; copy address to transmitt register
		sbi	DDRC,SDAP		; force SDA low
		rcall	i2c_qp_delay		; quarter period delay

;***************************************************************************
;*
;* FUNCTION
;*	i2c_write
;*
;* DESCRIPTION
;*	Writes data (one byte) to the I2C bus. Also used for sending
;*	the address.
;*
;* USAGE
;*	i2cdata - Contains data to be transmitted.
;*
;* RETURN
;*	Carry flag - Set if the slave respond transfer.
;*
;* NOTE
;*	IMPORTANT! : This funtion must be directly followed by i2c_get_ack.
;*
;***************************************************************************

I2c_write:	sec				; set carry flag
		rol	i2cdata		; shift in carry and out bit one
		rjmp	i2c_write_first
i2c_write_bit:
		lsl	i2cdata		; if transmit register empty
i2c_write_first:
		breq	i2c_get_ack		; goto get acknowledge (JRZ)
		sbi	DDRC,SCLP		; force SCL low
		brcc	i2c_write_low		; if bit high
		nop				; (equalize number of cycles)
		cbi	DDRC,SDAP		; release SDA
		rjmp	i2c_write_high
i2c_write_low:				; else
		sbi	DDRC,SDAP		; force SDA low
		rjmp	i2c_write_high	; (equalize number of cycles)
i2c_write_high:
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
		rcall	i2c_hp_delay		; half period delay

		rjmp	i2c_write_bit

;***************************************************************************
;*
;* FUNCTION
;*	i2c_get_ack
;*
;* DESCRIPTION
;*	Get slave acknowledge response.
;*
;* USAGE
;*	(used only by i2c_write in this version)
;*
;* RETURN
;*	Carry flag - Cleared if a slave responds to a request.
;*
;***************************************************************************

i2c_get_ack:	sbi	DDRC,SCLP		; force SCL low
		cbi	DDRC,SDAP		; release SDA
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
i2c_get_ack_wait:
		sbis	PINC,SCLP		; wait SCL high 
						;(In case wait states are inserted)
		rjmp	i2c_get_ack_wait
		clc				; clear carry flag
		sbic	PINC,SDAP		; if SDA is high
		sec				; set carry flag
		rcall	i2c_hp_delay		; half period delay
		ret

;***************************************************************************
;*
;* FUNCTION
;*	i2c_do_transfer
;*
;* DESCRIPTION
;*	Executes a transfer on bus. This is only a combination of i2c_read
;*	and i2c_write for convenience.
;*
;* USAGE
;*	i2cadr - Must have the same direction as when i2c_start was called.
;*	see i2c_read and i2c_write for more information.
;*
;* RETURN
;*	(depends on type of transfer, read or write)
;*
;* NOTE
;*	IMPORTANT! : This funtion must be directly followed by i2c_read.
;*
;***************************************************************************

I2c_do_transfer:
		sbrs	i2cadr,b_dir		; if dir = write
		rjmp	i2c_write		; goto write data

;***************************************************************************
;*
;* FUNCTION
;*	i2c_read
;*
;* DESCRIPTION
;*	Reads data (one byte) from the I2C bus.
;*
;* USAGE
;*	Carry flag - 	If set no acknowledge is given to the slave
;*			indicating last read operation before a STOP.
;*			If cleared acknowledge is given to the slave
;*			indicating more data.
;*
;* RETURN
;*	i2cdata - Contains received data.
;*
;* NOTE
;*	IMPORTANT! : This funtion must be directly followed by i2c_put_ack.
;*
;***************************************************************************

I2c_read:
		rol	i2cstat		; store acknowledge
						; (used by i2c_put_ack)
		ldi	i2cdata,0x01		; data = 0x01
i2c_read_bit:				; do
		sbi	DDRC,SCLP		; force SCL low
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
		rcall	i2c_hp_delay		; half period delay
		clc				; clear carry flag
		sbic	PINC,SDAP		; if SDA is high
		sec				; set carry flag
		rol	i2cdata		; store data bit
		brcc	i2c_read_bit		; while receive register not full

;***************************************************************************
;*
;* FUNCTION
;*	i2c_put_ack
;*
;* DESCRIPTION
;*	Put acknowledge.
;*
;* USAGE
;*	(used only by i2c_read in this version)
;*
;* RETURN
;*	none
;*
;***************************************************************************

i2c_put_ack:	sbi	DDRC,SCLP		; force SCL low
		ror	i2cstat		; get status bit
		brcc	i2c_put_ack_low	; if carry goto assert low
		cbi	DDRC,SDAP		; release SDA
		rjmp	i2c_put_ack_high
i2c_put_ack_low:			; else
		sbi	DDRC,SDAP		; force SDA low
i2c_put_ack_high:
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
i2c_put_ack_wait:
		sbis	PINC,SCLP		; wait SCL high
		rjmp	i2c_put_ack_wait
		rcall	i2c_hp_delay		; half period delay
		sbi	DDRC,SCLP		; force SCL low .... MISSING in original code
		cbi	DDRC,SDAP		; Release SDA   .... MISSING in original code
		ret

;***************************************************************************
;*
;* FUNCTION
;*	i2c_stop
;*
;* DESCRIPTION
;*	Assert stop condition.
;*
;* USAGE
;*	No parameters.
;*
;* RETURN
;*	None.
;*
;***************************************************************************

i2c_stop:	sbi	DDRC,SCLP		; force SCL low
		sbi	DDRC,SDAP		; force SDA low
		rcall	i2c_hp_delay		; half period delay
		cbi	DDRC,SCLP		; release SCL
		rcall	i2c_qp_delay		; quarter period delay
		cbi	DDRC,SDAP		; release SDA
		rcall	i2c_hp_delay		; half period delay
		ret

;**** End of File ****

⌨️ 快捷键说明

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