logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

SPI i Bascom: Gubienie bajtów przy transmisji między AtTiny2313 przez SPI

puciaken 02 Maj 2007 10:47 1289 0
  • #1 3840799
    puciaken
    Poziom 11  
    Posty: 69
    Ocena: 1
    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

    $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
    End


    MASTER

    $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
    Loop


    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


    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
    End


    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

    $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
    Return


    Mam nadzieję, że rozwiązanie tego problemu to nie wielki kłopot. Liczę na pomoc.

    Pozdrawiam
REKLAMA