Mam taki mały problem z którym się nie mogę uporać. Otóż robię sobie zegarek z wyświetlaczem LED, na procesorze ATmega8 i z zewnętrznym zegarem RTC. Wszystko idzie ładnie, gładko i świątecznie, ale nie mogę się uporać z jedną drobnostką - przesyłaniem I2C. Mam układ RTC - DS1340. Czy mógłby ktoś mi wytłumaczyć jak napisać prawidłowo komunikację i2c w bascomie?
Załączam tabelę rejestrów w zegarze DS1340 i kod mojego programu. Procedura przetwarzania danych z RTC (kod BCD itd) jest dobra, bo jak się poda jej dane w formie takiej, jakie powinna przykładowo otrzymać z i2c, to wyświetla cyfry dobrze. Jak sądzę, to RTC po włączeniu do zasilania powinien zliczać od godziny 00:00:00 (nie jestem tego pewien, może to jest przyczyną złego działania całego układu). Nie ustawiałem jeszcze tego zegarka, tylko próbuję go uruchomić. Układ ma wyświetlać godziny, minuty i sekundy. Na wyświetlaczu po włączeniu układu pojawiają się zupełnie dziwne znaki, których nie ma w tablicy cyfr, którą zdefiniowałem na początku kodu. Nie wiem dlaczego tak się dzieje. Czy mógłby ktoś mi pomóc?
Kod: Zaznacz cały
$regfile = "m8def.DAT"
$crystal = 8000000
Config Portb = Output
Config Portc = Output
Config Scl = Portd.2
Config Sda = Portd.3
I2cinit
Declare Sub Wyswietl(c1 As Byte , C2 As Byte , C3 As Byte , C4 As Byte , C5 As Byte , C6 As Byte , Lp As Byte , Po1 As Byte , Po2 As Byte)
' Tablica znaków na wyświetlaczu 7-segmentowym
Dim Led_c(10) As Byte
Led_c(1) = &B11000000
Led_c(2) = &B11111001
Led_c(3) = &B10100100
Led_c(4) = &B10110000
Led_c(5) = &B10011001
Led_c(6) = &B10010010
Led_c(7) = &B10000010
Led_c(8) = &B11111000
Led_c(9) = &B10000000
Led_c(10) = &B10010000
' PROCEDURA GŁÓWNA
Do
Dim I_sec As Byte , I_min As Byte , I_hou As Byte , I1_sec As Byte , I1_min As Byte , I1_hou As Byte
' VVV - Z tym mam problem - odbiór danych przez I2C
I_sec = 1
I_min = 2
I_hou = 3
I2creceive &B1101000 , I_sec , 1 , 1
I2creceive &B1101000 , I_min , 1 , 1
I2creceive &B1101000 , I_hou , 1 , 1
' wiem, że te shifty trochę głupio wyglądają, ale dobrze dzielą kod bcd na poszczególne cyfry
I1_sec = I_sec
I1_min = I_min
I1_hou = I_hou
Shift I1_sec , Left , 1
Shift I1_sec , Right , 5
Shift I_sec , Left , 4
Shift I_sec , Right , 4
Shift I1_min , Left , 1
Shift I1_min , Right , 5
Shift I_min , Left , 4
Shift I_min , Right , 4
Shift I1_hou , Left , 2
Shift I1_hou , Right , 6
Shift I_hou , Left , 4
Shift I_hou , Right , 4
Dim Nul As Byte , Tr As Byte
Nul = 0
Tr = 1
Call Wyswietl(i1_hou , I_hou , I1_min , I_min , I1_sec , I_sec , Tr , Nul , Nul)
Loop
'Koniec PROCEDURY GŁÓWNEJ
Sub Wyswietl(c1 As Byte , C2 As Byte , C3 As Byte , C4 As Byte , C5 As Byte , C6 As Byte , Lp As Byte , Po1 As Byte , Po2 As Byte)
'a to jest procedura wyświetlania cyfr na wyświetlaczu LED
' ta procedura musi być wywoływana co chwilę
Local Led_addr As Byte
Local Led_enn As Byte
Incr C1
Incr C2
Incr C3
Incr C4
Incr C5
Incr C6
Led_addr = &B11111110
For Led_enn = 1 To 7
Portb = &B11111111
Portc = Led_addr
Select Case Led_enn
Case 1 : Portb = Led_c(c1)
Case 2 : Portb = Led_c(c2)
Case 3
Portb = Led_c(c3)
If Lp = 1 Then Portb.7 = 0
Case 4
Portb = Led_c(c4)
If Lp = 1 Then Portb.7 = 0
Case 5
Portb = Led_c(c5)
If Po1 = 1 Then Portb.7 = 0
Case 6
Portb = Led_c(c6)
If Po2 = 1 Then Portb.7 = 0
End Select
Rotate Led_addr , Left , 1
Next Led_enn
End Sub
End