Komunikacia I2C na AVR

Moderátori: psichac, Moderátori

wwlado

Komunikacia I2C na AVR

Príspevok od používateľa wwlado » 10 Mar 2014, 17:56

Zdravim.

Potreboval by som poslat a vytiahnut udaje do DS1307 po I2C. V amaro je popisana taka komunikacia medzi PIC a DSkom tym stylom, ze sa odstartuje, posle adresa a nasledne data. V AVR data sheet som nasiel register na adresu. Nemozte mi niekto napisat uplne jednoducho, ako odoslem nieco do DSka a prijimem? Z toho datasheetu som jelen.

popopepe
Stály člen
Stály člen
Príspevky: 404
Dátum registrácie: 22 Jún 2009, 00:00

Re: Komunikacia I2C na AVR

Príspevok od používateľa popopepe » 10 Mar 2014, 18:11

Musíš hledat v datasheetu k tomu DS1307, tam je přesně to, co hledáš, byte za bytem.
0

wwlado

Re: Komunikacia I2C na AVR

Príspevok od používateľa wwlado » 10 Mar 2014, 18:19

To je aj v amare. Len v amare odosle start, data ako adresu, data... Ale v AVR je samostatny register na adresu. Preto sa pytam. Teda by som aj prijal, info, ako prednastavit AVRko.
Twgce pri adrese, twwc je zrejme chyba, TWEA.. Nechapem co je,
Keby bol niekto ochotny blizsie vysvetlit ako sa odoslem byte, alebo len jednoduchy programcek. Zbytok si odvodim.

popopepe
Stály člen
Stály člen
Príspevky: 404
Dátum registrácie: 22 Jún 2009, 00:00

Re: Komunikacia I2C na AVR

Príspevok od používateľa popopepe » 10 Mar 2014, 18:34

Jo, rozumím, ale já píšu programy pro AVR v BASCOM, to ti moc nepomůže. Až se tady ukáže někdo, kdo to mastí v C, nebo v čem to píšeš.
0

wwlado

Re: Komunikacia I2C na AVR

Príspevok od používateľa wwlado » 10 Mar 2014, 18:38

V ASM.

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: Komunikacia I2C na AVR

Príspevok od používateľa peterple » 10 Mar 2014, 18:42

toto používam ja. A predpokladám že máš záujem o asm keď je to v tejto sekcii.

Kód: Vybrať všetko


		call	i2cStart		;make start condition
		brts	GetTimeToBufferEnd
		ldi	al,DS1338ADR		;send adr DS1338 chip (Write operation)
		call	i2cSendAdr 
		brts	GetTimeToBufferEnd
		ldi	al,DS1338SECOND_ADR	;set adr in DS1338 chip to Seconds
		call	i2cSendData
		brts	GetTimeToBufferEnd
		call	i2cStart		;make repeated start condition
		brts	GetTimeToBufferEnd

		ldiw	z,time_buffer		;set pointer to buffer   
		ldi	xh,7			;set readed data count 

		ldi	al,DS1338ADR | 1	;send adr DS1338 chip (Read operation)
		call	i2cSendAdr 
		brts	GetTimeToBufferEnd

   						;loop for read data from RTC (7 byte) 
GetTimeToBufferLoop:
		ldi	al,(1<<TWEA)		;next 
		call	i2cReadData 
		brts	GetTimeToBufferEnd
		st	z+,al 
		

		dec	xh   
		brne	GetTimeToBufferLoop
		call	i2cStop			;make stop condition
GetTimeToBufferEnd:
		ret


.equ	I2C_STATUS_START =  0x08		;Start condition has been transmitted
.equ	I2C_STATUS_RESTART =  0x10		;Repeated Start condition has been transmitted
.equ	I2C_STATUS_MT_SLA_ACK_W =   0x18	;Slave address has been transmitted and ACK from Slave occured
.equ	I2C_STATUS_MT_SLA_NACK_W =  0x20	;Slave address has been transmitted and NOT ACK from Slave occured
.equ	I2C_STATUS_MT_DATA_ACK_W =  0x28	;data has been transmitted and ACK from Slave occured
.equ	I2C_STATUS_MT_DATA_NACK_W = 0x30	;data has been transmitted and NOT ACK from Slave occured
.equ	I2C_STATUS_MT_SLA_ACK_R =   0x40	;Slave address has been transmitted and ACK from Slave occured (READ operation)
.equ	I2C_STATUS_MT_SLA_NACK_R =  0x48	;Slave address has been transmitted and NOT ACK from Slave occured (READ operation)
.equ	I2C_STATUS_MT_DATA_ACK_R =  0x50	;data has been transmitted and ACK from Slave occured (READ operation)
.equ	I2C_STATUS_MT_DATA_NACK_R = 0x58	;data has been transmitted and NOT ACK from Slave occured (READ operation)

;INPUT	none 
;OUTPUT	T - 0 OK
;	    1 Error

i2cStart:
  		ldiw	z,FormatStrI2cStart*2		;send message to debug serial line
		call   printf_P

		clt				;clear error flag
		ldi	al,(1<<TWINT)+(1<<TWSTA)+(1<<TWEN)	;invoke Start condition
		_out	TWCR,al
i2cStartWait:	_in	al,TWCR			;wait while transfer Start condition
		sbrs	al,TWINT
		rjmp	i2cStartWait
		_in	al,TWSR			;read status
		andi	al,0xf8			;mask prescaler bits
		cpi	al,I2C_STATUS_START	;if start condition transmitted
		breq	i2cStartEnd		;OK		 
		cpi	al,I2C_STATUS_RESTART	;if restarted start condition transmitted
		breq	i2cStartEnd		;OK
i2cStartErr:	set				;ERROR
i2cStartEnd:	ret


;INPUT	none 
;OUTPUT	T - 0 OK
;	    1 Error

i2cStop:	clt				;clear error flag
i2cStopNoChangeT:
		ldi	al,(1<<TWINT)+(1<<TWSTO)+(1<<TWEN)	;invoke Stop condition
		_out	TWCR,al
		ret


;INPUT	AL - slaveAdr slave addres (7 bit) + Read/Write bit  
;OUTPUT	T - 0 OK
;	    1 Error, stop condition is transmit to close I2C state to default if it is suitable
;

i2cSendAdr:	bst	al,0			;store R/w bit to T
		_out	TWDR,al
		ldi	al,(1<<TWINT)+(1<<TWEN)
		_out	TWCR,al
i2cSendAdrWait: _in	al,TWCR			;wait while transfer address
		sbrs	al,TWINT
		rjmp	i2cSendAdrWait
		_in	al,TWSR			;read status
		andi	al,0xf8			;mask prescaler bits
		brts	i2cSendAdrRead		;check read status values if operation was READ
		clt				;clear Err flag
		cpi	al,I2C_STATUS_MT_SLA_ACK_W;if send adr and get ACK from slave
		breq	i2cStartEnd		;OK		 

		set				;ERROR

		cpi	al,I2C_STATUS_MT_SLA_NACK_W;if send adr and get NOT ACK from slave
		breq	i2cStopNoChangeT	;invoke stop condition transfer and return error flag set		 

i2cSendAdrEnd:	ret
i2cSendAdrRead:	clt				;clear Err flag
		cpi	al,I2C_STATUS_MT_SLA_ACK_R;if send adr and get ACK from slave
		breq	i2cStartEnd		;OK		 

		set				;ERROR

		cpi	al,I2C_STATUS_MT_SLA_NACK_R;if send adr and get NOT ACK from slave
		breq	i2cStopNoChangeT	;invoke stop condition transfer and return error flag set		 
		rjmp	i2cSendAdrEnd

;INPUT	AL - data   
;OUTPUT	T - 0 OK
;	    1 Error, stop condition is transmit to close I2C state to default if it is suitable
;

i2cSendData:	clt
		_out	TWDR,al
		ldi	al,(1<<TWINT)+(1<<TWEN)
		_out	TWCR,al
i2cSendDataWait: _in	al,TWCR			;wait while transfer data
		sbrs	al,TWINT
		rjmp	i2cSendDataWait
		_in	al,TWSR			;read status
		andi	al,0xf8			;mask prescaler bits
		cpi	al,I2C_STATUS_MT_DATA_ACK_W;if send data and get ACK from slave
		breq	i2cSendDataEnd		;OK		 

		set				;ERROR

		cpi	al,I2C_STATUS_MT_DATA_NACK_W;if send adr and get NOT ACK from slave
		breq	i2cStopNoChangeT	;invoke stop condition transfer and return error flag set		 

i2cSendDataEnd:	ret


;INPUT	AL - 0 data will be received and NOT ACK will be returned (end byte transfer)
;	   - (1<<TWEA) data will be received and ACK will be returned  (next i2cReadData will be follow)
;OUTPUT	AL - data   
;	T - 0 OK
;	    1 Error, stop condition is transmit to close I2C state to default if it is suitable
;

i2cReadData:	clt
		ori	al,(1<<TWINT)+(1<<TWEN)
		_out	TWCR,al
i2cReadDataWait: _in	al,TWCR			;wait while transfer data
		sbrs	al,TWINT
		rjmp	i2cReadDataWait
		_in	al,TWSR			;read status
		andi	al,0xf8			;mask prescaler bits
		cpi	al,I2C_STATUS_MT_DATA_ACK_R;if read data and send ACK to slave
		breq	i2cReadDataEnd		;OK		 


		cpi	al,I2C_STATUS_MT_DATA_NACK_R;if read data and send NOT ACK to slave
		breq	i2cReadDataEnd	;invoke stop condition transfer and return OK error flag		 

		set				;ERROR

i2cReadDataEnd:	_in	al,TWDR			;return received byte
		ret
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

wwlado

Re: Komunikacia I2C na AVR

Príspevok od používateľa wwlado » 10 Mar 2014, 19:42

Presne toto hladam. DAKUJEM.

Inac,je to dobry napad Tcko pouzivat ako chybu procedury. Husty napad. Dufam, ze ho nemas patentovany.. :lol:

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: Komunikacia I2C na AVR

Príspevok od používateľa peterple » 10 Mar 2014, 19:50

za málo. Pozerám že ako som to vysekol z aplikácie tak je tam zopár chýb, ale myslím že si s tým poradíš.
_in _out sú makrá aby som nemusel meditovať ako vekslovať data s IO registrami.
Patentovať si to ihneď dám. Čo keď to to použiješ v miliónovej sériovke.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok