AVR TWI/I2C

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
MiLe
Příspěvky: 123
Registrován: 18 říj 2005, 02:00

AVR TWI/I2C

#1 Příspěvek od MiLe »

Ahojte, snazim sa rozchodit TWI na ATmega8 ale vobec sa mi nedari. Nedokazem vyslat ani startovaciu sekvenciu :(
Nemohol by tu niekto dat fragment programu kde je tato komunikacia vyuzita? Alebo link na program?
Jasne, ze som hladal v googli ale nasiel som len pisane v Ccku a ja to chcem pisat v assembleri.
VDAKA

v pripade potreby upresnim...

Uživatelský avatar
caven
Příspěvky: 417
Registrován: 15 srp 2006, 02:00

#2 Příspěvek od caven »

Dám ti sem jeden muj hodně starý program, komunikace I2C funguje na 100% Tak si to zkus osekat a vzkoušet..

Kód: Vybrat vše

	.NOLIST
	.INCLUDE "m8def.inc"
	.include "macros.asm"
	.LIST
	
	.equ	XTAL=16000000

	.DEF 	reg=r16
	.def	treg=r17	;definice I2C
	.def	Citac=r18	;Pomocná proměná
	.def	Hodnota_Manualni=r19 ;registr pro nastavenou manuální hodnotu
	.def	LED0=r20
	.def	LED1=r21
	.def	LED2=r22
	.def	LED3=r23
	.def	LED4=r24
	.def	Poc=r27
	.equ	Smer=4		;druhý vývod z rotačního enkodéru je na PD4
	.equ	Tlacitko=2	;tlačítko je připojeno na PD2
	.equ	delicka=3	
	.equ	T1H=155		;155
	.equ	T1L=220		;200
	.equ 	start=$08	;definice I2C START
	.equ 	mt_sla_ack=$18	;adresa slave
	.equ 	mt_data_ack=$28	;data

;===========================================================
;Obvod TDA8444 8x6bitová DA převodník
;===========================================================
	.equ	Adresa_TDA8444=0b01000000;adesa obvodu TDA8444, uzemnneny adresy A2,A1,A0
	.equ	TDA8444_DA0=0b11110000	;prvni DA převodník
	.equ	TDA8444_DA1=0b11110001	;druhy DA převodník
	.equ	TDA8444_DA2=0b11110010	;treti DA převodník
	.equ	TDA8444_DA3=0b11110011	;ctvrty DA převodník
	.equ	TDA8444_DA4=0b11110100	;paty DA převodník
	.equ	TDA8444_DA5=0b11110101	;sesty DA převodník
	.equ	TDA8444_DA6=0b11110110	;sedmy DA převodník
	.equ	TDA8444_DA7=0b11110111	;osmy DA převodník


;*******************************************************************
;Začátek programu
;*******************************************************************

	.cseg
	.org	$0000
	rjmp	Reset

	.org	INT0addr
	rjmp	INT_Switch

	.org	INT1addr
	rjmp	INT_Smer

Reset:	ldi	r16,high(ramend)
	ldi	r17,low(ramend)
	out	sph,r16
	out	spl,r17

;********************************************************
;nastavení IO
;********************************************************
;	ldi	reg,$00
;	out	ddrd,reg	;portD,B jako vstup
;	out	ddrb,reg
;	ldi	reg,$ff
;	out	portd,reg	;zdvikací odpory připojeny
;	out	portb,reg	
;	out	ddrc,reg	;portC jao výstup

	

	ldi	reg,$00
	out	ddrc,reg
	out	ddrd,reg
	ldi	reg,$ff
	out	portc,reg
	out	ddrb,reg
	out	portd,reg

;********************************************************
;Nastavení přenosové rychlosti pro TWI sběrnici cca 100kHz
;********************************************************
	ldi	reg,$00
	out	twsr,reg
	ldi	reg,72
	out	twbr,reg

;********************************************************
;test zda se bude provádět automatický nebo manuální režim
;testuje se při startu programu, tzn. pro změnu režimu je potřebný reset!!!!!
;přepínač je připojen na PD0
;+5V - Manuální režim
;GND - Automatický reřim
;********************************************************

Test_ON:sbis	pind,0
	rjmp	Automatika
	rjmp	Manual

;********************************************************
;Mannuální režim ovládá se připojeným rotačním enkodérem. nejdříve se stiskem tlačítka kterým je vybaven
;vebere kanál na který se bude zapisovat a poté se natočí hodnota která se uloží a zapíše do DA převodníku
;Tlačítko je připojeno na INT0 (PD2) a výstupy z enkodéru jsou připojeny na INT1(PD3) a PD4
;Přerušení je vyvoláno na sestupnou hranu 1->0 = INT :-)
;********************************************************	
Manual: ldi	reg,10		;nastavení přerušení
	out	mcucr,reg
	ldi	reg,0b11000000
	out	gicr,reg
	ldi	reg,255		;nastavení hodnot pro test jestli nebylo nastaveno 
	mov	r0,reg		;více nebo méně 
	ldi	reg,64
	mov	r1,reg
	ldi	reg,6
	mov	r7,reg

	sei	

Ovladej_Manual:	cpi	Citac,1
	breq	Priprav_Nula
	cpi	Citac,2
	breq	Priprav_Jedna
	cpi	Citac,3
	breq	Priprav_Dva
	cpi	Citac,4
	breq	Priprav_Tri
	cpi	Citac,5
	breq	Priprav_Ctyri
	rjmp	Ovladej_Manual

Priprav_Nula:	mov	r20,Hodnota_Manualni
		rjmp	Posli_Ven_Man
Priprav_Jedna:	mov	r21,Hodnota_Manualni
		rjmp	Posli_Ven_Man
Priprav_Dva:	mov	r22,Hodnota_Manualni
		rjmp	Posli_Ven_Man
Priprav_Tri:	mov	r23,Hodnota_Manualni
		rjmp	Posli_Ven_Man
Priprav_Ctyri:	mov	r24,Hodnota_Manualni
		rjmp	Posli_Ven_Man

Posli_Ven_Man:	
	rcall	Zapis_Nulty
	rcall	Zapis_Prvni
	rcall	Zapis_Druhy
	rcall	Zapis_Treti
	rcall	Zapis_Ctvrty
	rjmp	Ovladej_Manual

;--------------------------------------------------------
;přerušení od stisknutí Switche na enkodéru
;--------------------------------------------------------
INT_Switch:push	r16
	in	r16,sreg
	push	r16
	push	r17
	inc	Citac
	rcall	Test_Konec
	rjmp	Konec_INT2
Test_Konec:cpse	Citac,r7
	ret
	ldi	Citac,0
	ret
Konec_INT2:pop	r17
	pop	r16
	out	sreg,r16
	pop	r16
	reti	

;--------------------------------------------------------
;přerušení od změny směru tzn. hodnoty do DAC
;--------------------------------------------------------
INT_Smer:push	r16
	in	r16,sreg
	push	r16
	sbic	pind,Smer
	rjmp	Pricti
	rjmp	Odecti
Pricti:	inc	Hodnota_Manualni
	rcall	Test_Max
	rjmp	Konec_INT
Odecti:	dec	Hodnota_Manualni
	rcall	Test_Min
	rjmp	Konec_INT
Test_Min:cpse	Hodnota_Manualni,r0
	ret
	ldi	Hodnota_Manualni,0
	ret
Test_Max:cpse	Hodnota_Manualni,r1
	ret
	ldi	Hodnota_Manualni,63
	ret
Konec_INT:pop	r16
	out	sreg,r16
	pop	r16
	reti	

;********************************************************
;Automatický režim
;********************************************************
Automatika:nop
Loop2:	ldiw	R30,Tabulka*2	;uloží adresu tabulky
	ldiw	R28,308		;vloží počet kroků 64+64 na každou LED*5
Loop1:	lpm	R20,Z+		;5*načte hodnotu do každého registru zvlášť
	lpm	R21,Z+
	lpm	R22,Z+
	lpm	R23,Z+
	lpm	R24,Z+
	;neco s tim	
	rcall	Zapis_Nulty
	rcall	Zapis_Prvni
	rcall	Zapis_Druhy
	rcall	Zapis_Treti
	rcall	Zapis_Ctvrty
	rcall	cekej		;vyvolá časovou smyčku cca 50ms 
	sbiw	R28,1
	brne	Loop1
	rjmp	Loop2


;********************************************************
;podprogramy pro zapisování do DA převodníku
;********************************************************
Zapis_Nulty:	rcall	I2C_Start
	ldi	treg,Adresa_TDA8444;nastavení pro zapis do tda 8444
	rcall	I2C_Adresa
	ldi	treg,TDA8444_DA0
	rcall	I2C_Data
	mov	treg,r20
	rcall	I2C_Data
	rcall	I2C_Stop
	ret
Zapis_Prvni:	rcall	I2C_Start
	ldi	treg,Adresa_TDA8444;nastavení pro zapis do tda 8444
	rcall	I2C_Adresa
	ldi	treg,TDA8444_DA1
	rcall	I2C_Data
	mov	treg,r21
	rcall	I2C_Data
	rcall	I2C_Stop
	ret
Zapis_Druhy:	rcall	I2C_Start
	ldi	treg,Adresa_TDA8444;nastavení pro zapis do tda 8444
	rcall	I2C_Adresa
	ldi	treg,TDA8444_DA2
	rcall	I2C_Data
	mov	treg,r22
	rcall	I2C_Data
	rcall	I2C_Stop
	ret	
Zapis_Treti:	rcall	I2C_Start
	ldi	treg,Adresa_TDA8444;nastavení pro zapis do tda 8444
	rcall	I2C_Adresa
	ldi	treg,TDA8444_DA3
	rcall	I2C_Data
	mov	treg,r23
	rcall	I2C_Data
	rcall	I2C_Stop
	ret	
Zapis_Ctvrty:	rcall	I2C_Start
	ldi	treg,Adresa_TDA8444;nastavení pro zapis do tda 8444
	rcall	I2C_Adresa
	ldi	treg,TDA8444_DA4
	rcall	I2C_Data
	mov	treg,r24
	rcall	I2C_Data
	rcall	I2C_Stop
	ret

;*********************************************************	
;rutina na obsluhu I2C sběrnice
;*********************************************************
;vyšle START stav
I2C_Start:ldi	treg,(1<<twint)|(1<<twsta)|(1<<twen)
	out	twcr,treg
	rcall	I2C_Ready
	in	treg,twsr
	andi	treg,$f8
	cpi	treg,$08
	ret
;čeká na dokončení přenosu
I2C_Ready:in	treg,twcr
	sbrs	treg,twint
	rjmp	I2C_Ready
	ret
;odešle adresu z TREG
I2C_Adresa:out	twdr,treg
	ldi	treg,(1<<twint)|(1<<twen)
	out	twcr,treg
	rcall	I2C_Ready
	in	treg,twsr
	andi	treg,$f8
	cpi	treg,$18
	ret
;odešle data z TREG
I2C_Data:out	twdr,treg
	ldi	treg,(1<<twint)|(1<<twen)
	out	twcr,treg
	rcall	I2C_Ready
	in	treg,twsr
	andi	treg,$f8
	cpi	treg,$28
	ret
;vyšle stop stav
I2C_Stop:ldi	treg,(1<<twint)|(1<<twsto)|(1<<twen)
	out	twcr,treg
stopt:	in	treg,twcr
	sbrc	treg,twsto
	rjmp	stopt
	ret
;*********************************************************
;čekací smyčka pro automatický režim
;čeká cca 50ms
;*********************************************************
CEKEJ:	push	r17
	push	r18
	push	r19
	LDI 	R17,4	
	LDI 	R18,0	
	LDI 	R19,0	
CEKEJA:	DEC 	R19	
	BRNE 	CEKEJA	;smyčka 1
	DEC 	R18	
	BRNE 	CEKEJA	;smyčka 2
	DEC 	R17	
	BRNE 	CEKEJA	;smyčka 3
	pop	r19
	pop	r18
	pop	r17
	RET	;návrat


Tabulka:.db	0,0,0,0,0,2,0,0,0,0
	.db	4,0,0,0,0,6,0,0,0,0
	.db	8,0,0,0,0,10,0,0,0,0
	.db	12,0,0,0,0,14,0,0,0,0
	.db	16,0,0,0,0,18,0,0,0,0
	.db	20,0,0,0,0,22,0,0,0,0
	.db	24,0,0,0,0,26,0,0,0,0
	.db	28,0,0,0,0,30,0,0,0,0
	.db	32,0,0,0,0,34,0,0,0,0
	.db	36,0,0,0,0,38,0,0,0,0
	.db	40,0,0,0,0,42,0,0,0,0
	.db	44,0,0,0,0,46,0,0,0,0
	.db	48,0,0,0,0,50,0,0,0,0
	.db	52,0,0,0,0,54,0,0,0,0
	.db	56,0,0,0,0,58,0,0,0,0
	.db	60,0,0,0,0,62,0,0,0,0	;konec rozsvicení první diody 
	.db	62,2,0,0,0,62,4,0,0,0
	.db	62,6,0,0,0,62,8,0,0,0
	.db	62,10,0,0,0,62,12,0,0,0
	.db	62,14,0,0,0,62,16,0,0,0
	.db	62,18,0,0,0,62,20,0,0,0
	.db	62,22,0,0,0,62,24,0,0,0
	.db	62,26,0,0,0,62,28,0,0,0
	.db	62,30,0,0,0,62,32,0,0,0
	.db	62,34,0,0,0,62,36,0,0,0
	.db	62,38,0,0,0,62,40,0,0,0
	.db	62,42,0,0,0,62,44,0,0,0
	.db	62,46,0,0,0,62,48,0,0,0
	.db	62,50,0,0,0,62,52,0,0,0
	.db	62,54,0,0,0,62,56,0,0,0
	.db	62,58,0,0,0,62,60,0,0,0
	.db	62,62,0,0,0,62,62,0,0,0	;26nec r6z, dr4h* d56dy
	.db	62,62,2,0,0,62,62,4,0,0
	.db	62,62,6,0,0,62,62,10,0,0
	.db	62,62,12,0,0,62,62,14,0,0
	.db	62,62,16,0,0,62,62,18,0,0
	.db	62,62,20,0,0,62,62,22,0,0
	.db	62,62,24,0,0,62,62,26,0,0
	.db	62,62,28,0,0,62,62,30,0,0
	.db	62,62,32,0,0,62,62,34,0,0
	.db	62,62,36,0,0,62,62,38,0,0
	.db	62,62,40,0,0,62,62,42,0,0
	.db	62,62,44,0,0,62,62,46,0,0
	.db	62,62,48,0,0,62,62,50,0,0
	.db	62,62,52,0,0,62,62,54,0,0
	.db	62,62,56,0,0,62,62,58,0,0
	.db	62,62,60,0,0,62,62,62,0,0 ;26nec z6zs5cen5 tret5 d56dy
	.db	62,62,62,2,0,62,62,62,4,0
	.db	62,62,62,6,0,62,62,62,8,0
	.db	62,62,62,10,0,62,62,62,12,0
	.db	62,62,62,14,0,62,62,62,16,0
	.db	62,62,62,18,0,62,62,62,20,0
	.db	62,62,62,22,0,62,62,62,24,0
	.db	62,62,62,26,0,62,62,62,28,0
	.db	62,62,62,30,0,62,62,62,32,0
	.db	62,62,62,34,0,62,62,62,36,0
	.db	62,62,62,38,0,62,62,62,40,0
	.db	62,62,62,42,0,62,62,62,44,0
	.db	62,62,62,46,0,62,62,62,48,0
	.db	62,62,62,50,0,62,62,62,52,0
	.db	62,62,62,54,0,62,62,62,56,0
	.db	62,62,62,58,0,62,62,62,60,0
	.db	62,62,62,62,0,62,62,62,62,2	;26nec r6zsv5cen5 ctvrty d56dxy
	.db	62,62,62,62,4,62,62,62,62,6
	.db	62,62,62,62,8,62,62,62,62,10
	.db	62,62,62,62,12,62,62,62,62,14
	.db	62,62,62,62,16,62,62,62,62,18
	.db	62,62,62,62,20,62,62,62,62,22
	.db	62,62,62,62,24,62,62,62,62,26
	.db	62,62,62,62,28,62,62,62,62,30
	.db	62,62,62,62,32,62,62,62,62,34
	.db	62,62,62,62,36,62,62,62,62,38
	.db	62,62,62,62,40,62,62,62,62,42
	.db	62,62,62,62,44,62,62,62,62,46
	.db	62,62,62,62,48,62,62,62,62,50
	.db	62,62,62,62,52,62,62,62,62,54
	.db	62,62,62,62,54,62,62,62,62,56
	.db	62,62,62,62,58,62,62,62,62,60
	.db	62,62,62,62,62,62,62,62,62,62	;sv5t5 vsechn6
	.db	60,62,62,62,62,58,62,62,62,62
	.db	56,62,62,62,62,54,62,62,62,62
	.db	52,62,62,62,62,50,62,62,62,62
	.db	48,62,62,62,62,46,62,62,62,62
	.db	44,62,62,62,62,42,62,62,62,62
	.db	40,62,62,62,62,38,62,62,62,62
	.db	36,62,62,62,62,34,62,62,62,62
	.db	32,62,62,62,62,30,62,62,62,62
	.db	28,62,62,62,62,26,62,62,62,62
	.db	24,62,62,62,62,22,62,62,62,62
	.db	20,62,62,62,62,18,62,62,62,62
	.db	16,62,62,62,62,14,62,62,62,62
	.db	12,62,62,62,62,10,62,62,62,62
	.db	8,62,62,62,62,6,62,62,62,62
	.db	4,62,62,62,62,2,62,62,62,62
	.db	0,62,62,62,62,0,60,62,62,62	;26nec zhas5nan5 -rvn5
	.db	0,58,62,62,62,0,56,62,62,62
	.db	0,54,62,62,62,0,50,62,62,62
	.db	0,48,62,62,62,0,44,62,62,62
	.db	0,42,62,62,62,0,40,62,62,62
	.db	0,38,62,62,62,0,36,62,62,62
	.db	0,34,62,62,62,0,32,62,62,62
	.db	0,30,62,62,62,0,28,62,62,62
	.db	0,26,62,62,62,0,24,62,62,62
	.db	0,22,62,62,62,0,20,62,62,62
	.db	0,18,62,62,62,0,16,62,62,62
	.db	0,14,62,62,62,0,12,62,62,62
	.db	0,10,62,62,62,0,8,62,62,62
	.db	0,6,62,62,62,0,4,62,62,62
	.db	0,2,62,62,62,0,0,62,62,62	;26nec zhas dr4hy
	.db	0,0,60,62,62,0,0,58,62,62
	.db	0,0,56,62,62,0,0,54,62,62
	.db	0,0,52,62,62,0,0,50,62,62
	.db	0,0,48,62,62,0,0,44,62,62
	.db	0,0,42,62,62,0,0,40,62,62
	.db	0,0,38,62,62,0,0,36,62,62
	.db	0,0,34,62,62,0,0,32,62,62
	.db	0,0,30,62,62,0,0,28,62,62
	.db	0,0,26,62,62,0,0,24,62,62
	.db	0,0,22,62,62,0,0,20,62,62
	.db	0,0,18,62,62,0,0,16,62,62
	.db	0,0,14,62,62,0,0,12,62,62
	.db	0,0,10,62,62,0,0,8,62,62
	.db	0,0,6,62,62,0,0,4,62,62
	.db	0,0,2,62,62,0,0,0,62,62 	;26nec zahs5nan5 tret5
	.db	0,0,0,60,62,0,0,0,58,62
	.db	0,0,0,54,62,0,0,0,50,62
	.db	0,0,0,48,62,0,0,0,46,62
	.db	0,0,0,44,62,0,0,0,42,62
	.db	0,0,0,40,62,0,0,0,38,62
	.db	0,0,0,36,62,0,0,0,34,62
	.db	0,0,0,32,62,0,0,0,30,62
	.db	0,0,0,28,62,0,0,0,26,62
	.db	0,0,0,24,62,0,0,0,22,62
	.db	0,0,0,20,62,0,0,0,18,62
	.db	0,0,0,16,62,0,0,0,14,62
	.db	0,0,0,12,62,0,0,0,10,62
	.db	0,0,0,8,62,0,0,0,6,62
	.db	0,0,0,4,62,0,0,0,2,62
	.db	0,0,0,0,62,0,0,0,0,60		;26nec zhas5nan5 ctrvty
	.db	0,0,0,0,58,0,0,0,0,56
	.db	0,0,0,0,54,0,0,0,0,52
	.db	0,0,0,0,50,0,0,0,0,48
	.db	0,0,0,0,46,0,0,0,0,44
	.db	0,0,0,0,42,0,0,0,0,40
	.db	0,0,0,0,38,0,0,0,0,36
	.db	0,0,0,0,34,0,0,0,0,32
	.db	0,0,0,0,30,0,0,0,0,28
	.db	0,0,0,0,26,0,0,0,0,24
	.db	0,0,0,0,20,0,0,0,0,18
	.db	0,0,0,0,16,0,0,0,0,14
	.db	0,0,0,0,12,0,0,0,0,10
	.db	0,0,0,0,8,0,0,0,0,6
	.db	0,0,0,0,4,0,0,0,0,2
	.db	0,0,0,0,0,0,0,0,0,0


Uživatelský avatar
MiLe
Příspěvky: 123
Registrován: 18 říj 2005, 02:00

#3 Příspěvek od MiLe »

Caven DIKY za inspiraciu! Vyzera to tak, ze minimalne tu startovaciu sekvenciu mam rovnaku ako ty ale ked som to simuloval v AVR studiu tak to nerobilo to co som od toho cakal. Na nejakej diskusii som cital, ze TWI v AVR studiu odsimulovat nejde - nevies nieco o tom? Ak to nejde tak moj problem bude asi tam, ze kod mam sice dobre napisany ale odsimulovat to nejde :( asi budem musiet dat najskor dokopy HW. Ako maju byt nastavene piny SCL SDA? Alebo su nastavene automaticky oko treba ked je pouzita TWI?

Uživatelský avatar
caven
Příspěvky: 417
Registrován: 15 srp 2006, 02:00

#4 Příspěvek od caven »

tak jsem to zkoušel v tom AVR studiu a nevypadá že by so otomu chtělo simulovat... Zkus to na konkrétním zapojení.. Mohu se zeptat co to má dělat ???

Uživatelský avatar
MiLe
Příspěvky: 123
Registrován: 18 říj 2005, 02:00

#5 Příspěvek od MiLe »

zatial to nema robit nic konkretne - iba sa chcem naucit robit s tym TWI... asi to vyskusam na takom module kde mam obvod SAA1066, ktory riadi (multiplexuje) 4x7segmentovky... Len neviem kedy sa k tomu dostanem.

Uživatelský avatar
MiLe
Příspěvky: 123
Registrován: 18 říj 2005, 02:00

#6 Příspěvek od MiLe »

oprava SAA1064

Uživatelský avatar
MiLe
Příspěvky: 123
Registrován: 18 říj 2005, 02:00

#7 Příspěvek od MiLe »

Huraaa uz mi to "chodi". Po niekolkohodinovom pozerani datasheetu, testovani, skusani a pozerania inych programov som zistil, ze v programe mi chyba test - podprogram, ktory je v programe vyzsie uvedeny ako I2C_ready... no co uz, ale PODARILO sa :)

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“