Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8] [bascom] [Spi slave]

solar1 11 Jun 2008 08:27 3857 5
  • #1
    solar1
    Level 15  
    Witam mam problem - usiluje zrealizowac na atmedze 8 odczyt danych z tablicy po spi do mastera .. tylko nie jestem w stanie odpalic spi na atemedze w trybie slave tj :
    chce aby atmega wysylala ciagle dane mastera < nie uzywam MOSI w masterze > poprostu atmega robi swoje i podczas podania stanu 0 na pinie SS powinem odczytaj sobie bajty... ale tak sie nie dzieje <sprawdzilem to nawet analizatorem stanow logicznych , czy trzeba jednak podac cos na MOSI aby rozpoczac transmisje ? >

    oto program
    Code:

    $crystal = 14745600
    $regfile = "m8def.dat"
    $noramclear

    Dim Databyte As Byte                                        'Data to send

    Config Spi = Hard , Data Order = Msb , Master = No     
    Databyte = &HA2




    Do                                                         
    Restore Dta1
    Read Databyte
    Spiout Databyte , 3

    Loop
    End

    Dta1:
    Data &H23 , &HA1 , &H91 , &H46 , &H0B , &H81



    programjest raczej zwiezly .. a mimo to nie moge uruchomic spi
  • #2
    BoskiDialer
    Level 34  
    Jeśli slave ma tylko wysyłać dane, to wystarczy połączyć pomiędzy procesorami sygnały SCK oraz MISO. SS w tym przypadku jest raczej zbędne - ważne, żeby w masterze ten pin był wyjściem, w slave może być wejściem połączonym z SS mastera, a może nie być wykorzystany w ogóle (lepiej wybierz sposób pierwszy). Zauważ, że wywołanie Spiout nie powoduje wysłania danych - to master generuje sygnał zegarowy, więc żaden bajt nie zostanie przesłany, dopóki master sam nie zażąda odbioru bajtu przez SPI. Jeśli slave ma wymuszać moment transmisji bajtu, to łatwiej będzie zamienić rolę układów, ale jeśli chcesz, to możesz dać dodatkową linię pomiędzy procesorami, która w masterze będzie wywoływać przerwanie, w którym nastąpi odczyt bajtu (bardziej skomplikowane od zamiany ról)
  • #3
    solar1
    Level 15  
    ok powieminaczej
    usiluje wyslac szeregowo paczki danych z procesora z zewnetrznego zrodla zegarowego
    i co nastepuje w bascomie
    : polecenie shiftout - nie ma mozliwosci wysylania danych z zwenetrznego zrodla zegarowego - to pocelecnie samo generoje na pinie clk zegar - wiec to polecenie nic mi nie daje :
    myslalem o spi w trybie slave tak wiec na pin sck podaje zewnetrzne zrodlo zegarowe i ogladam sobie dane na pinie wyjsciowym MISO - i nic nie widze .. doszedlem do tego (dzieki helpowi ze aby procesor byl w trybie slave potrzebne sa wstawki asemblerowe )
    z tym ze dane sa wysylane strasznie wolno ! bajt .... jakies 40 cykli na pinie zegara <dla szyny spi> i potem ponownie bajt ... zalaczam obecnie kod swoj.. czy to moize byc wina "wolnego " odczytywania danych z tablicy ? przez bascoma ?

    Code:

    $crystal = 14745600
    $regfile = "m8def.dat"
    $noramclear


    Dim Databyte As Byte                                        'Data to send
    Dim Licz As Byte
    Config Pinb.4 = Output
    Config Pind.0 = Output

    Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = No , Polarity = Low , Phase = 0 , Clockrate = 4

    Spiinit

    On Spi Spi_isr Nosave

    Enable Interrupts


    'Licz = 0


    Spiinit

    Spdr = 0
    Restore Dta1
    Spdr = Databyte


    Do                                                          'Forever loop
      If Licz = 8 Then
      Disable Interrupts
       Toggle Pind.0
      Licz = 0
      Read Databyte
       Spdr = Databyte
      Enable Interrupts
      end if

    Loop
    End




    Spi_isr:
    'Restore Dta1
    'Read Databyte
    Incr Licz

      push r24    ; save used register
      in r24,sreg ; save sreg
      push r24
      nop
      Databyte = Spdr
     ' Set Rbit                                                  ' we received something
      pop r24
      !out sreg,r24 ; restore sreg
      pop r24        ; and the used register
    Return


    Dta1:
    Data &HA2 , &HA2 , &HA2 , &HA2 , &HA2 , &H81 , &H15 , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF

  • #4
    BoskiDialer
    Level 34  
    Kompletnie nie rozumiem tego programu (języka też). Zrób może najpierw prostą wymianę bajtów, żeby slave caly wysyłał bajt 0xAB. Jeśli nie będzie działać, to zrób to bezpośrednio odwołując się do rejestrów spcr i spdr.
  • #5
    solar1
    Level 15  
    program wysyla zawartosc tablicy dta1: przez spi
    <Spi_isr>
    jest to przyklad wziety z helpa - tak wiec prosciej sie nie da - wyslanie pojedynczego bajtu dziala dobrze - wyslanie paczki np 10 bajtow juz nie -
    na analizatorze stanow logicznych mam "dziury" po miedzy jednym a drugim bajtem wysylanym przez spi mam okolo 40 impulsow zegarowych na spi - nie rozumiem czemu
    czy pobranie kolejnego bajtu z tablicy i zapisanie go w rejestrze SPDR moze zajac az tyle czasu ? <40x50uS ? >
  • #6
    solar1
    Level 15  
    A wiec po paru bojach - udalo sie ..mniejwiecej :
    _ shiftout na piechote z zwenetrznym generatorem zegarowym _
    Code:

    crystal = 16000000
    $regfile = "m8def.dat"
    $noramclear

    Dim Wartosc(10) As Byte         ' ilosc wysylanych bajtow
    Dim Databyte As Byte             ' bajt wysylany
    Dim Dana As Byte                   ' licznik
    Dim Bitpointer As Byte            ' wskaznik aktualnie wysylanego bitu

    Config Pinb.1 = Output                    ' I/O jako wyjscie danych
    Config Pind.2 = Input                  ' pin zewnetrznego zegara

    Iowy Alias Portb.1

    On Int0 Seriout                               'przerwanie
    Config Int0 = Rising                        ' jak je wyzwalamy

    '########## tabela z wysylanymi bajtami ###############
    Wartosc(1) = &B10101010                             
    Wartosc(2) = &B10101010                               
    Wartosc(3) = &B10101010
    Wartosc(4) = &B10001001
    Wartosc(5) = &B01100010
    Wartosc(6) = &B11010000
    Wartosc(7) = &B10000001
    Wartosc(8) = &B10101000
    Wartosc(9) = &HFF
    Wartosc(10) = &HFF
    '#####\ustawiamy wartosci startowe ################
    Dana = 1
    Bitpointer = 0
    Databyte = Wartosc(1)

    nop
    nop
    nop
    nop
    Enable Int0
    Enable Interrupts                         ' uruchamiamy przerwania

    Do                                            Forever loop
    Loop
    End

    Seriout:                                    ' przerwanie
    Disable Interrupts
            Iowy = Databyte.bitpointer            'Send bit out
            Incr Bitpointer
            If Bitpointer = 8 Then         'wyzeruj go i zacznij zliczac od poczatku
              Bitpointer = 0           'Reset po
              Incr Dana             ' przesun sie w bajtach wyjsciowych o 1 w gore
             Databyte = Wartosc(dana)   ' przypisz dane z do bajta wsylanego
        End If
    Enable Interrupts
    Return


    Program dziala dosc dobrze - z tym ze , pomiedzy wykryciem taktu zegara a reakcja uC mam 5,02uS opoznienia..
    czy mozna dopiescic jeszcze ten program ?
    a moze w bascomienie da sie osiagnac lepszych wynikow ?
    ... zegar dla megi jest maksymalny na jaki pozwala nota katalogowa... zastanawiam sie czy wogole mozna podkrecic atmege8 na np 20mhz.. albo czy to cos da ?