Witam wszystkich forumowiczów.
Zmagam się z nawiązaniem komunikacji poprzez I2C procesora ATmega8 oraz układu RTC PCF8583.
Na wstępie napiszę, że linie SDA i SCL są podciągnięte do VCC przez rezystory 1K.
Układ pracuje z kwarcem wewnętrznym 1MHz.
Podprogram "dwiems" generuje opóźnienie rzędu 2ms.
Podprogram "blad" wywołuje pętle, która zapala diode i program zostaje w tej pętli.
Pin A0 układu RTC jest podłączony do GND, więc adres układu to 160 dla zapisu a 161 dla odczytu.
Napisałem procedury do obsługi szyny I2C.
Oto one:
Domyślam się, że procedury start,stop i write są poprawne. Podczas zapisu do danej komórki układ nie zapala diody, więc bit ACK jest poprawnie rozpoznawany. Jak wyjmę układ z podstawki to procesor zapala diodę.
Problem tkwi w tym, że przy odczycie niezależnie od komórki, którą chce odczytać zawsze zwraca 0x00.
Procedurę odczytu wykonuję w następujący sposób:
1.Procedura start.
2.Procedura zapisu na szynę I2C adresu slave'a do zapisu czyli 160.
3.Procedura zapisu na szynę I2C adresu komóki czyli np $2 (rejestr sekund).
4.Procedura startu.
5.Procedura zapisu na szynę I2C adresu slave'a do odczytu czyli 161.
6.Procedura odczytu danych z szyny I2C i zapis do ACC(rejestr roboczy R20).
7.Procedura stop.
Następnie wynik z ACC konwertuję z BCD i ślę na LCD.
Algorytm dekodowania jest poprawny, bo jak ręcznie wpiszę do ACC wartość np. 0b00010010 to na LCD trafia wynik 12.
Proszę o pomoc. Osobie, która pomoże mi odnaleźć błąd oddam wszystkie punkty
Zmagam się z nawiązaniem komunikacji poprzez I2C procesora ATmega8 oraz układu RTC PCF8583.
Na wstępie napiszę, że linie SDA i SCL są podciągnięte do VCC przez rezystory 1K.
Układ pracuje z kwarcem wewnętrznym 1MHz.
Podprogram "dwiems" generuje opóźnienie rzędu 2ms.
Podprogram "blad" wywołuje pętle, która zapala diode i program zostaje w tej pętli.
Pin A0 układu RTC jest podłączony do GND, więc adres układu to 160 dla zapisu a 161 dla odczytu.
Napisałem procedury do obsługi szyny I2C.
Oto one:
;==========================================================
I2cstart:
;==========================================================
sbi i2cddr,sda ;sda jako wyj
sbi i2cddr,scl ;scl jako wyj
nop
sbi I2CPORT,sda ;sda stan wysoki
nop
sbi I2CPORT,scl ;scl stan wysoki
rcall dwiems
cbi I2CPORT,sda ;sda stan niski /procedura start
rcall dwiems
cbi I2CPORT,scl ;scl stan niski zeby potem mogl byc narastajacy
ret
;==========================================================
I2cstop:
;==========================================================
sbi i2cddr,sda ;sda jako wyj
sbi i2cddr,scl ;scl jako wyj
nop
cbi I2CPORT,sda ;stan niski sda
nop
sbi I2CPORT,scl ;stan wysoki scl
rcall dwiems
sbi I2CPORT,sda ;stan wysoki sda
rcall dwiems
ret
;==========================================================
i2cwrite: ;PROCEDURA ZAPISU BAJTU NA LINIĘ I2C
;==========================================================
sbi I2CDDR, SDA ; SDA jako wyjście
ldi licznik, 8 ; ustaw ilość powtórzeń pętli
petla1:
sbrs acc, 7 ; jeśli bit 7 w acc jest ustawiony, to pomiń następną instrukcję
cbi I2CPORT, SDA ; ustaw na SDA stan niski
sbrc acc, 7 ; jeśli bit 7 w acc jest wyzerowany, to pomiń następną instrukcję
sbi I2CPORT, SDA ; ustaw na SDA stan wysoki
sbi I2CPORT, SCL ; ustaw na SCL stan wysoki, ZBOCZE NARASTAJĄCE
rcall DWIEMS ; opóˇnienie
cbi I2CPORT, SCL ; ustaw na SCL stan niski
lsl acc ; przesunięcie w lewo acc
dec licznik ; zmniejsz licznik pętli o 1
brne petla1 ; jeśli niezerowy, to skocz do petla1
; ACK
cbi I2CDDR, SDA ; SDA jako wejście
Cbi I2CPORT, SDA ; ustaw na SDA stan NISKI
RCALL DWIEMS
sbi I2CPORT, SCL ; ustaw na SCL stan wysoki
sbiC I2CPIN, SDA ; jeśli SDA jest w stanie niskim, to pomiń następną instrukcję
RCALL BLAD
Cbi I2CPORT, SCL ; ustaw na SCL stan NISKI
ret
;==========================================================
i2cread: ; procedura odczytu bajtu z szyny I2C
;==========================================================
cbi I2CDDR, SDA ; SDA jako wejście
Cbi I2CPORT, SDA ; ustawienie stanu NISKIEGO na SDA
RCALL DWIEMS
ldi licznik, 8
petla2:
RCALL DWIEMS
sbi I2CPORT, SCL ; stan wysoki na SCL
rcall DWIEMS ; opóˇnienie
sbic I2CPIN, SDA ; jeśli SDA jest w stanie niskim to pomiń następną instrukcję
ori acc,0 ; ustaw bit 0 acc
lsl acc ; przesunięcie acc w lewo
cbi I2CPORT, SCL ; stan niski na SCL
dec licznik ; zmniejsz licznik pętli o 1
brne petla2 ; jeśli niezerowy to skocz do petla2
rcall DWIEMS ; opózninie
; ACK
sbi I2CDDR, SDA ; SDA jako wyjście
RCALL DWIEMS
cbi I2CPORT, SDA ; ustaw na SDA stan niski (ACK)
sbi I2CPORT, SCL ; ustaw na SCL stan wysoki
rcall DWIEMS ; opóˇnienie
cbi I2CPORT, SCL ; ustaw na SCL stan niski
ret
Domyślam się, że procedury start,stop i write są poprawne. Podczas zapisu do danej komórki układ nie zapala diody, więc bit ACK jest poprawnie rozpoznawany. Jak wyjmę układ z podstawki to procesor zapala diodę.
Problem tkwi w tym, że przy odczycie niezależnie od komórki, którą chce odczytać zawsze zwraca 0x00.
Procedurę odczytu wykonuję w następujący sposób:
1.Procedura start.
2.Procedura zapisu na szynę I2C adresu slave'a do zapisu czyli 160.
3.Procedura zapisu na szynę I2C adresu komóki czyli np $2 (rejestr sekund).
4.Procedura startu.
5.Procedura zapisu na szynę I2C adresu slave'a do odczytu czyli 161.
6.Procedura odczytu danych z szyny I2C i zapis do ACC(rejestr roboczy R20).
7.Procedura stop.
Następnie wynik z ACC konwertuję z BCD i ślę na LCD.
Algorytm dekodowania jest poprawny, bo jak ręcznie wpiszę do ACC wartość np. 0b00010010 to na LCD trafia wynik 12.
Proszę o pomoc. Osobie, która pomoże mi odnaleźć błąd oddam wszystkie punkty