Chyba również jestem maniakiem, gdyż zamiast odpocząć po pracy to siedzę i bawię się tymi czarnymi kosteczkami:)
Mam mały problem i chciałem poprosić was o pomoc.
Zamarzyło mi się napisanie programu w ASM do obsługi układów na szynie I2C. I wszystko fajnie działała ale tylko z portem we/wy pcf8574. Gdy podłączam pod magistralę pamięć 256 bajtową 8582, program opierający się na tych samych procedurach ASM już nie działa. Wygląda na to że nie odbiera żadnych bitów ACK z układu pamięci.
Próbowałem różne czasy opóźnień i kilka takich samych scalaków ale nic nie pomaga.
Może jest jakiś kruczek o którym nic nie wiem....może ktoś z forumowiczów miał podobne problemy.
Oczywiście zamieszczam kod:
Kod: Zaznacz cały
cseg at 0h
ljmp start
;------------------------
org 70h
param1: ds 1
DATA: ds 1
cseg at 100h
start:
lcall serial_init
lcall testsend
lcall serial_put_char
sjmp $
I2C_DELAY:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
I2C_READ: ;reading 8 bits from i2c device
mov r1, #08h
clr a
setb SDA
_loop0302:
setb SCL
acall I2C_DELAY
mov C, SDA
rlc a
clr SCL
acall I2C_DELAY
djnz r1, _loop0302
ret
I2C_WRITE: ;writing 8 bits in to i2c device
mov r1, #08h
_loop0301:
rlc a
mov SDA,C
acall I2C_DELAY
setb SCL
acall I2C_DELAY
clr SCL
acall I2C_DELAY
djnz r1, _loop0301
ret
I2C_START:
setb SCL
setb SDA
acall I2C_DELAY
clr SDA
acall I2C_DELAY
clr SCL
ret
I2C_STOP:
clr SDA
setb SCL
acall I2C_DELAY
setb SDA
acall I2C_DELAY
ret
I2C_RESTART:
setb SDA
setb SCL
acall I2C_DELAY
clr SDA
acall I2C_DELAY
clr SCL
ret
I2C_READ_ACK:
setb SDA
acall I2C_DELAY
setb SCL
acall I2C_DELAY
mov C, SDA
mov a, #0
rlc a
clr SCL
acall I2C_DELAY
ret
I2C_WRITE_ACK:
clr SDA
setb SCL
acall I2C_DELAY
clr SCL
acall I2C_DELAY
ret
I2C_WRITE_NAK:
setb SDA
setb SCL
acall I2C_DELAY
clr SCL
acall I2C_DELAY
ret
I2C_EPROM_WRITE_DELAY:
mov param1, #255
acall std_delay
ret
testsend:
; zapal jeden z LEDów podłączonych na porcie
acall I2C_START
mov a, #01000000b
clr acc.0
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
mov a, #7Fh
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
acall I2C_STOP
; zapis pamięci
acall I2C_START
mov a, #10100000b ;adres ukladu
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
mov a, #67h ;adres w pamieci
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
mov a, #18h ;wartosc
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
acall I2C_STOP
acall I2C_EPROM_WRITE_DELAY
; odczyt pamięci
acall I2C_START
mov a, #10100000b ;adres ukladu
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
mov a, #67h ;adres w pamieci
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
acall I2C_RESTART
mov a, #10100001b ;adres ukladu
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
acall I2C_READ
acall I2C_WRITE_NAK
acall I2C_STOP
mov DATA, a
; zapalenie innego LED'a
acall I2C_START
mov a, #01000000b
clr acc.0
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
mov a, #7Eh
acall I2C_WRITE
acall I2C_READ_ACK
lcall serial_put_char
acall I2C_STOP
mov a, DATA
ret
end
Procedura serial_put_char jest wykorzystywana do wyświetlania odebranych wartości bitów potwierdzeń oraz odczytane zawartości komórki pamięci. Wysyłana jest zawsze wartość z akumulatora.
Nie wiem już co myśleć. Dostaję oczopląsu patrząc po raz setny na ten sam kod. Może potrzebuje świeżego spojrzenia? Będę bardzo wdzięczny za ewentualną pomoc.