Witam szanowne grono forumowiczów. Od pewnego czasu borykam się z problemem konfiguracji SPI.
Mam połączoną jedną atmegę8 jako master i 4 jako slave w sprzętowym SPI.
Cztery atmegi pracujące w trybie slave zajmują się obsługą wyświetlaczy ledowych (dla każdej atmegi 4 8 segmentowe wyświetlacze obsługiwane multiplekowo). Obsługa samych wyświetlaczy działa bezproblemowo i nie przysparza najmniejszych problemów. Problem polega na samej komunikacji. Jeśli w masterze usunę całą pętlę nieskończoną i wyślę 4 zmienne (do któych wcześniej przypisałem wartości na stałe) do slave'a, w którym PRZED nieskończoną pętlą wczytam z SPI te bajty - wszystko hula jak należy. Wyświetlają się dokładnie takie liczby jakie wysłałem. Nie ma efekt "migania" wyświetlaczy. Problem pojawia się kiedy chcę wykonać taki oto kod:
MASTER:
SLAVE:
Wyświetlacz przez ułamek sekundy wyświetla jakieś liczby (wygenerowane przez pętle for jak się domyślam) i na ok 200ms przygasa. Jeżeli w masterze usunę linię Waitms 200 to wyświetlacz wyświetla liczby tak szybko, że nie jestem w stanie ich odczytać (co jest poprawne wg mnie). Nie rozumiem jednak dlaczego w pierwszym przypadku wyświetlacze są wygaszane na 200 ms i na ułamek sekundy pojawiają się cyfry. Wydaje mi się, że ten kod powinien wyświetlić na wyświetlaczach liczbę 00.0, po 200ms 00.1 itd. Przekopałem już setki stron. Kilkakrotnie czytałem helpa bascoma jak i samą notę Atmela o SPI. Nic nie przychodzi mi do głowy. Próbowałem już wielu konfiguracji SPI - bez zmian. Aha - jeśli chodzi o samą obsługę wyświetlaczy to jestem pewien, że jest ok (lcd'ki są podłączone przez inwerter, stąd takie a nie inne ustawianie stanów na portach). Proszę nie pytać dlaczego akurat tak a nie poprzez zadeklarowane tablice obsługuje lcd - musi zostać tak jak jest. Dla testów podłączam tylko jednego slave'a na razie pod PD7. Za pomoc oczywiście będą punkty.
Mam połączoną jedną atmegę8 jako master i 4 jako slave w sprzętowym SPI.
Cztery atmegi pracujące w trybie slave zajmują się obsługą wyświetlaczy ledowych (dla każdej atmegi 4 8 segmentowe wyświetlacze obsługiwane multiplekowo). Obsługa samych wyświetlaczy działa bezproblemowo i nie przysparza najmniejszych problemów. Problem polega na samej komunikacji. Jeśli w masterze usunę całą pętlę nieskończoną i wyślę 4 zmienne (do któych wcześniej przypisałem wartości na stałe) do slave'a, w którym PRZED nieskończoną pętlą wczytam z SPI te bajty - wszystko hula jak należy. Wyświetlają się dokładnie takie liczby jakie wysłałem. Nie ma efekt "migania" wyświetlaczy. Problem pojawia się kiedy chcę wykonać taki oto kod:
MASTER:
$regfile = "m8def.DAT"
$crystal = 1000000
'$sim 'szybsza symulacja - wyłącz przy programowaniu!
Config Portd.7 = Output
Portd.7 = 1
Config Spi = Hard , Master = Yes , Noss = 0 , Interrupt = On , Data Order = Msb , Polarity = Low , Clockrate = 4
Config Portb = Output
Spiinit
Dim Minus As Byte
Dim D As Byte
Dim J As Byte
Dim P As Byte
Do
For D = 0 To 9
For J = 0 To 9
For P = 0 To 9
Portd.7 = 0
Spiout D , 1
Spiout J , 1
Spiout P , 1
Portd.7 = 1
Waitms 200
Next P
Next J
Next D
Loop
SLAVE:
$regfile = "m8def.DAT"
$crystal = 1000000
'$sim 'szybsza symulacja - wyłącz przy programowaniu!
Config Portc = Output 'port c jako wyjścia
Config Portd = Output 'port d jako wyjścia
Config Portb = Output
'Konfiguracja SPI
Config Spi = Hard , Master = No , Noss = 0 , Interrupt = On , Data Order = Msb , Polarity = Low , Clockrate = 4
Spiinit
Dim Minus As Byte
Dim Dziesiatki As Integer
Dim Jednosci As Integer 'ta liczba zawsze z kropką! Ta atmega tego nie będzie przetwarzać
Dim Dziesietne As Integer
Minus = 1
Do
'On Spi Odczytaj_nowe
Portd = &B00000000 ' ustawian stany
Portc = &B11111111 ' "nieświecenia" wyswietlaczy
'========== Wczytywanie do zmiennych kolejnych bajtów przesłanych przes ATMEGA MASTER ==================
'Spiin Minus , 1
Spiin Dziesiatki , 1
Spiin Jednosci , 1
Spiin Dziesietne , 1
'========================================== Koniec pobierania danych ===================================
'============= wyswietlacz znaku ==========================
If Minus = 1 Then
Portc.3 = 0 'aktywuje wyswietlacz odpowiedzialny za minus/plus
Portd.6 = 1 ' wyswietla znak "-"
End If
Waitms 2
Portc.3 = 1 'wygaszanie wyswietlacza odpowiedzialnego za minus/plus
'============= wyswietlacz dziesiatek======================
Portc.2 = 0 'aktywuje wyswietlacz odpowiedzialny za dziesiatki
Select Case Dziesiatki
Case 0 : Portd = &B00111111
Case 1 : Portd = &B00000110
Case 2 : Portd = &B01011011
Case 3 : Portd = &B01001111
Case 4 : Portd = &B01100110
Case 5 : Portd = &B01101101
Case 6 : Portd = &B01111101
Case 7 : Portd = &B00000111
Case 8 : Portd = &B01111111
Case 9 : Portd = &B01101111
End Select
Waitms 2
Portc.2 = 1
'wygaszenie wyswietlacza odpowiedzialnego za dziesiatki
'============= wyswietlacz jednosci=========================
Portc.1 = 0 'aktywuje wyswietlacz odpowiedzialny za jednosci
Select Case Jednosci
Case 0 : Portd = &B10111111
Case 1 : Portd = &B10000110
Case 2 : Portd = &B11011011
Case 3 : Portd = &B11001111
Case 4 : Portd = &B11100110
Case 5 : Portd = &B11101101
Case 6 : Portd = &B11111101
Case 7 : Portd = &B10000111
Case 8 : Portd = &B11111111
Case 9 : Portd = &B11101111
End Select
Waitms 2
Portc.1 = 1
'wygaszenie wyswietlacza odpowiedzialnego za jednosci
'=========== wyswietlacz cyfry dziesiętnej ==================
Portc.0 = 0 'aktywuje wyswietlacz odpowiedzialny za cyfry po przecinu
Select Case Dziesietne
Case 0 : Portd = &B00111111
Case 1 : Portd = &B00000110
Case 2 : Portd = &B01011011
Case 3 : Portd = &B01001111
Case 4 : Portd = &B01100110
Case 5 : Portd = &B01101101
Case 6 : Portd = &B01111101
Case 7 : Portd = &B00000111
Case 8 : Portd = &B01111111
Case 9 : Portd = &B01101111
End Select
Waitms 2
Portc.0 = 1
'wygaszenie wyswietlacza odpowiedzialnego za cyfry po przecinu
Loop
Wyświetlacz przez ułamek sekundy wyświetla jakieś liczby (wygenerowane przez pętle for jak się domyślam) i na ok 200ms przygasa. Jeżeli w masterze usunę linię Waitms 200 to wyświetlacz wyświetla liczby tak szybko, że nie jestem w stanie ich odczytać (co jest poprawne wg mnie). Nie rozumiem jednak dlaczego w pierwszym przypadku wyświetlacze są wygaszane na 200 ms i na ułamek sekundy pojawiają się cyfry. Wydaje mi się, że ten kod powinien wyświetlić na wyświetlaczach liczbę 00.0, po 200ms 00.1 itd. Przekopałem już setki stron. Kilkakrotnie czytałem helpa bascoma jak i samą notę Atmela o SPI. Nic nie przychodzi mi do głowy. Próbowałem już wielu konfiguracji SPI - bez zmian. Aha - jeśli chodzi o samą obsługę wyświetlaczy to jestem pewien, że jest ok (lcd'ki są podłączone przez inwerter, stąd takie a nie inne ustawianie stanów na portach). Proszę nie pytać dlaczego akurat tak a nie poprzez zadeklarowane tablice obsługuje lcd - musi zostać tak jak jest. Dla testów podłączam tylko jednego slave'a na razie pod PD7. Za pomoc oczywiście będą punkty.
