Miałem niedawno problem jak rozwiązać problem wielu hardware'owych uartów. Przychyliłem się do rozwiązania, w którym połączę parę układów AtTiny2313 przez SPI. Próbowałem nawiązać transmisję. Wszystko byłoby ok, gdyby nie to, że gdzieś gubią się bajty...
Kod wygląda tak:
SLAVE
MASTER
To co wysyła Slave to 4 bajty: 3 (cosik, w przyszłości informacja ile bajtów ma odebrać master) + 3 komunikaty midi, np. (144 36 0). To, że nie wyświetli zera w terminalu zrozumiem, bo warunkiem jest Cosik<>0, ale gdy włączę If Cosik=3 Then Print Cosik, to tak średnio co czwarte wciśnięcie klawisza na keyboardzie (bo układ jest połączony z keyboardem przez MIDI i odbiera komunikaty, zwykle 3 bajtowe) nie wyświetli trójki w terminalu, bo po prostu jej nie odebrał, a ponoć została wysłana przez Slave'a. Do instrukcji Spiout Cosik, 1 doszło na pewno, bo zakończenie wysyłania sygnalizuje zmiana stanu diody LED.
Jak dałem w Masterze opóźnienie Wait 1 (czyli sekundę) między odbiorem kolejnych bajtów z SPI to po wciśnięciu klawisza odbierał wszystkie bajty (oczywiście z wyjątkiem tych co się tak czy tak gubią jak widać), czyli nie ma tutaj mowy o tym, że po prostu procek nie nadąża z odbiorem, bo gdzieś te dane albo są buforowane, albo po prostu slave czeka z ich wysłaniem, aż Master będzie gotów do odbioru.
Mogę wysłać jak wygląda to co otrzymuję w terminalu, ale chyba nie jest to konieczne. Po prostu gdzieś się gubią bajty. Pierwsze dwa komunikaty zwykle są bezbłędne, ale potem już zaczynają się gubić bajty. Pewnie to żadna reguła.
Zasugerowałem się radą kolegi z forum i spróbowałem to zrobić zgodnie z helpem Bascoma i napisałem coś takiego:
SLAVE
Teraz błąd chyba tkwi tutaj. Nie wiem dlaczego Spiout teraz zawiesza program... Dioda się raz zaświeca i na tym się kończy.
MASTER
Mam nadzieję, że rozwiązanie tego problemu to nie wielki kłopot. Liczę na pomoc.
Pozdrawiam
Kod wygląda tak:
SLAVE
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 31250
Dim Cosik As Byte , Midibuf(3) As Byte
Config Portd = Output
Config Serialin = Buffered , Size = 200
Config Spi = Hard , Master = No
...
Spiinit
Cls
Do
Inputbin Midibuf(1)
Cosik = 3
Spiout Cosik , 1
Spiout Midibuf(1) , 1
Spiout Midibuf(2) , 1
Spiout Midibuf(3) , 1
Toggle Portd.7
Loop
EndMASTER
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
Dim Cosik As Byte , Midibuf(3) As Byte
Config Portd = Output
Config Spi = Hard , Master = Yes
...
Spiinit
Cls
Do
Cosik = 0
Spiin Cosik , 1
If Cosik <> 0 And Cosik <> 255 And Cosik <> 254 Then
'If Cosik = 3 Then
Print Cosik 'czyli po prostu dostaję prawie wszystkie komunikaty jakie wysyła slave
End If
LoopTo co wysyła Slave to 4 bajty: 3 (cosik, w przyszłości informacja ile bajtów ma odebrać master) + 3 komunikaty midi, np. (144 36 0). To, że nie wyświetli zera w terminalu zrozumiem, bo warunkiem jest Cosik<>0, ale gdy włączę If Cosik=3 Then Print Cosik, to tak średnio co czwarte wciśnięcie klawisza na keyboardzie (bo układ jest połączony z keyboardem przez MIDI i odbiera komunikaty, zwykle 3 bajtowe) nie wyświetli trójki w terminalu, bo po prostu jej nie odebrał, a ponoć została wysłana przez Slave'a. Do instrukcji Spiout Cosik, 1 doszło na pewno, bo zakończenie wysyłania sygnalizuje zmiana stanu diody LED.
Jak dałem w Masterze opóźnienie Wait 1 (czyli sekundę) między odbiorem kolejnych bajtów z SPI to po wciśnięciu klawisza odbierał wszystkie bajty (oczywiście z wyjątkiem tych co się tak czy tak gubią jak widać), czyli nie ma tutaj mowy o tym, że po prostu procek nie nadąża z odbiorem, bo gdzieś te dane albo są buforowane, albo po prostu slave czeka z ich wysłaniem, aż Master będzie gotów do odbioru.
Mogę wysłać jak wygląda to co otrzymuję w terminalu, ale chyba nie jest to konieczne. Po prostu gdzieś się gubią bajty. Pierwsze dwa komunikaty zwykle są bezbłędne, ale potem już zaczynają się gubić bajty. Pewnie to żadna reguła.
Zasugerowałem się radą kolegi z forum i spróbowałem to zrobić zgodnie z helpem Bascoma i napisałem coś takiego:
SLAVE
Dim Cosik As Byte , Midibuf(3) As Byte
Config Portd = Output
Config Serialin = Buffered , Size = 200
Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = No , Polarity = Low , Phase = 0 , Clockrate = 128
...
Config Pinb.6 = Output
Enable Interrupts
Spiinit
Spdr = 0
Cls
Do
Waitms 100
Toggle Portd.6
Cosik = 3
'Inputbin Midibuf(1)
Spiout Cosik , 1
Spiout Midibuf(1) , 1
Spiout Midibuf(2) , 1
Spiout Midibuf(3) , 1
Loop
EndTeraz błąd chyba tkwi tutaj. Nie wiem dlaczego Spiout teraz zawiesza program... Dioda się raz zaświeca i na tym się kończy.
MASTER
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
Dim Cosik As Byte , Midibuf(3) As Byte , I As Byte, Rbit As Bit , Bsend As Byte , B As Byte
Config Portd = Output
Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128
...
Config Pinb.6 = Output
Enable Interrupts
Enable Spi
Spiinit
On Spi Spi_isr Nosave
Print "start"
Spdr = 0
Cls
Do
If Rbit = 1 and B<>255 Then
Print "received : " ; B
Reset Rbit
Bsend = Bsend + 1
Spdr = Bsend
End If
Loop
End
Spi_isr:
push r24
in r24,sreg
push r24
B = Spdr
Set Rbit
pop r24
!out sreg,r24
pop r24
ReturnMam nadzieję, że rozwiązanie tego problemu to nie wielki kłopot. Liczę na pomoc.
Pozdrawiam