Strona 1 z 1

ATMega32 i I2C

: pn 13 mar 2006, 16:33
autor: lionheart
Mam glupi problem z Atmega32 i pamiecia flash 24C64 dzialajaca na i2c.
Napisalem program w assemblerze, podpialem pamiec na Portc,0 i 1 pamietajac o rezystorach podciagajacych 4,7k i uklad nie daje mi potwierdzenia po nadaniu do niego 8 bitow. Wczesniej robilem to pod '51 i bylo ok.Czas tez juz znacznie wydluzylem, nie wiem gdzie jest pies pogrzebany. Bylbym wdzieczny za pomoc.

Kawalek kodu ktory popelnilem:

.include "m32def.inc"
.def temp=r16
.def temp2=r17
.def czas=r18
.def czas2=r19
.def data=r20
.equ slvW=0xA0
.equ alvR=0xA1
; scl - portc,0
; sda - portc,1

ldi r17,LOW(RAMEND)
out spl,r17
ldi r17,HIGH(RAMEND)
out sph,r17

ldi temp, $FF
out ddrc, temp

ldi temp, $FF
out ddra, temp

ldi temp,$FF
out porta,temp

rcall start
ldi data,slvW
rcall sendbyte
; ldi data,$25 sa wyremowane bo i tak wywala sie
; rcall sendbyte przy pierwszym sendbyte
; ldi data,$00
; rcall sendbyte
; ldi data,$EE
; rcall sendbyte
; rcall stop
ldi temp,$F0
out porta,temp

nic: jmp nic


start : sbi portc,0
sbi portc,1
rcall delay
cbi portc,1
rcall delay
cbi portc,0
rcall delay
ret


sendbyte: ldi temp,8
loop: rol data
rcall movc
sbi portc,0
rcall delay
cbi portc,0
dec temp
cpi temp,0
brne loop
sbi portc,1
sbi portc,0
ldi temp,$FD
out ddrc,temp
rcall delay
in temp,pinc
andi temp,0b00000010
sbrc temp,1
rjmp error

end1: ldi temp,$FF
out ddrc,temp
cbi portc,0
rcall delay
ret



movc: brcs ustaw
cbi portc,1
jmp done
ustaw: sbi portc,1
done: ret



delay: ldi czas,$ff
loop2: ldi czas2,$ff
loop5: dec czas2
cpi czas2,0
brne loop5
dec czas
cpi czas,0
brne loop2
ret

: pn 13 mar 2006, 22:57
autor: movzx
Mam wrazenie ze doszlo do malego wywazania otwartych drzwi ;) Przeciez Mega32 ma sprzetowe I2C - po co wiec robic programowe? Swego czasu robilem programowe SPI (zadanie nieco prostsze od I2C) i nie dzialalo to za dobrze... Proponuje zaczac od uzycia sprzetowego interfejsu a potem sie zobaczy...
Pozdr.

: pn 13 mar 2006, 23:10
autor: lionheart
No wlasnie..... :D
Probowalem obsluzyc TWI przy pomocy Atmegi i mialem malego zonka, okazalo sie ze pomimo tego ze sprawdzane flagi przechodza,to przy probie odczytu wywala jakies smieci. Programowa obsluga I2C byla mi potrzebna po to zeby sprawdzic ktora czesc obslugi TWI (zapis czy odczyt) jest wadliwa.
Zeby nie byc goloslownym.......... (nie bardzo wiem czy moge tutaj zamieszczac tez kawalki programu, administratorow prosze wiec o wyrozumialosc i upomnienie)

ZAPIS

.include "m32def.inc"
.def temp=r18


main: ldi temp,LOW(RAMEND)
out spl,temp
ldi temp,HIGH(RAMEND)
out sph,temp
ldi temp,$ff
out ddra,temp

ldi temp,25
out twbr,temp
ldi temp,$0
out twsr,temp

rcall start
rcall wait
rcall rd_status
cpi temp,8
brne error1

ldi temp,0b10100000
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$18
brne error2

ldi temp,$00
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$28
brne error3

ldi temp,$55
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$28
brne error4


ldi temp,$aa
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$28
brne error5

rcall stop

ldi temp,$0
rjmp zapal


error1: ldi temp,$7e
rjmp zapal

error2: ldi temp,$0f
rjmp zapal

error3: ldi temp,$f
rjmp zapal

error4: ldi temp,$f1
rjmp zapal

error5: ldi temp,$1f

zapal: out porta,temp
nic: rjmp nic


wait: in temp,twcr
sbrs temp,twint
rjmp wait
ret

start: ldi temp, (1<<twint)|(1<<twen)|(1<<twsta)|(0<<twsto)
out twcr,temp
ret

stop: ldi temp, (1<<twint)|(1<<twen)|(1<<twsto)
out twcr,temp

rd_status: in temp,twsr
andi temp,$f8
ret
wr_data:out twdr,temp
ldi temp,(1<<twint) | (1<<twen)|(0<<twsta)|(0<<twsto)
out twcr,temp
ret


poszczegolne errory byly mi potrzebne do sprawdzenia w ktorym momencie sie cos wywala, jednak uklad caly niby przechodzi.


ODCZYT


.include "m32def.inc"
.def temp=r18
.def data=r19
.def adresl=r20
.def adresh=r21
.def temp1=r22


main: ldi r17,LOW(RAMEND)
out spl,r17
ldi r17,HIGH(RAMEND)
out sph,r17

ldi temp,$ff
out ddra,temp

ldi temp,10
out twbr,temp
ldi temp,$0
out twsr,temp

rcall start
rcall wait
rcall rd_status
cpi temp,8
brne error1

ldi temp,0b10100000
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$18
brne error2

ldi temp,$00
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$28
brne error3

ldi temp,$00
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$28
brne error4

rcall start
rcall wait
rcall rd_status
cpi temp,$10
brne error5

ldi temp,0b10100001
rcall wr_data
rcall wait
rcall rd_status
cpi temp,$40
brne error6
ldi temp1,twdr
ldi temp, (0<<twea)|(1<<twint)|(0<<twsto)|(0<<twsta)|(1<<twen)
out twcr,temp

rcall wait

rcall rd_status
cpi temp,$58
brne error7

rcall stop

rjmp zapal

error1: ldi temp,$81
rjmp zapal

error2: ldi temp,$f
rjmp zapal

error3: ldi temp,$f0
rjmp zapal

error4: ldi temp,$e
rjmp zapal

error5: ldi temp,$e0
rjmp zapal

error6: ldi temp,$ee
rjmp zapal

error7: ldi temp,$3e
rjmp zapal

error8:ldi temp,$33


zapal: com temp1
out porta,temp1
nic: rjmp nic

wait: in temp,twcr
sbrs temp,twint
rjmp wait
ret

start: ldi temp, (1<<twint)|(1<<twen)|(1<<twsta)
out twcr,temp
ret

stop: ldi temp, (1<<twint)|(1<<twen)|(1<<twsto)
out twcr,temp

rd_status: in temp,twsr
andi temp,$f8
ret

wr_data:out twdr,temp
ldi temp,(1<<twint) | (1<<twen)
out twcr,temp
ret

wait1: ldi r16,$FF
loop: dec r16
cpi r16,0
brne loop
ret