Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega8][bascom] problem z mcp3204 spi

pawwik 03 Jul 2008 21:26 4687 15
  • #1
    pawwik
    Level 11  
    no wiec moj problem jest taki
    mam atmege8 i mcp3204 polaczony przez spi

    na starcie mowie ze sprzętowe SPI za cholerę nie chciało mi dać jakich kolwiek rezultatów wiec przerzuciłem się na softwarowe ale i tak mam problem. Bazując na nocie a dokładnie na:
    [atmega8][bascom] problem z mcp3204 spi
    napisałem taki kawałek kodu:

    Code:
    Do
    
       Portb.2 = 0





       Temp(1) = Spimove(7)
       Temp(2) = Spimove(0)
       Temp(3) = Spimove(0)
        Portb.2 = 1


       Print Bin(temp(1)) ; " " ; Bin(temp(2)) ; " " ; Bin(temp(3)) ; "
           Print Temp(3)



    Wait 1
    Loop


    no ale nie dziala dostaje w odpowiedzi przewaznie same 1

    czy widzial ktos moze dzialajacy kod do tego przetwonika ?
    lub ma jakis pomysl co i jak zmienic zeby zadzialalo ?
    walcze caly dzien i nie mam juz pomyslow.
  • #2
    wojtek2112
    Level 13  
    Witam!
    Miałem niedawno ten przetwornik, użyłem do niego instrukcji shiftout
    (adresowanie np.CH0 &B110000). Następnie zastosowałem instrukcję spiin
    [np.spiin x(1),2 zapisanych w zmiennej typu byte x(2)] .Zostaje tylko
    przetworzyć zmienną x na inną (zsumować 2 bajty) np. do wyświetlenia na lcd. Trzeba równierz dobrze ustawić przed odczytem danych linie sck i cs/shdn tego mcp. Jeżeli chcesz więcej informacji to daj znać.
    Pozdrawiam
  • #3
    pawwik
    Level 11  
    to ze cs musze dac na 0 to wiem ale co mam zzrobic z sck ?
    daje znac chce wiecej informacji :D zaczynam juz watpic z moc bascoma z tym spi i coraz czesciej mysle o C...
  • #4
    wojtek2112
    Level 13  
    Code:
    $regfile = "m88def.dat"
    
    $crystal = 4000000
    $baud = 19200
    $hwstack = 32
    $swstack = 10
    $framesize = 40
     Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.6 , Db6 = Portd.7 , Db7 = Portb.0 , E = Portd.3 , Rs = Portd.2
        Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5
      Dim Adres_mcp As Byte
      Dim Odczyt_mcp(2) As Byte
      Dim A As Word
     Dim String_lcd As String * 8
     Dim Wart_nap As String * 8


    Cs Alias Portb.1
    Clk Alias Portb.5

    Adres_mcp = &B110000
     'to jest adres dla mcp3208 dla channel 0, ale dla mcp3204 powinien być chyba taki sam , najwyżej skasuj ostatnie zero
    Do

     Set Cs
      Reset Cs
       Set Clk
    Reset Clk
     Shiftout Portb.3 , Clk , Adres_mcp , 0
    Spiin Odczyt_mcp(1) , 2
     Set Clk
      Set Cs
     A = Odczyt_mcp(1)
     Shift A , Left , 8
     A = A + Odczyt_mcp(2)
     Shift A , Right , 4
      String_lcd = Str(a)
     Wart_nap = Format(string_lcd , "0.00")
    Locate 1 , 1
    Lcd Wart_nap ; "   "
    Waitms 250

    Loop
    'End
    'Jak będzie dobrze to odpowiedz . Pozdrawiam


    Proszę stosować znaczniki code
    And!
  • #5
    pawwik
    Level 11  
    ciagle same 0 dostaje. Nawet po dodaniu Spiinit.
  • Helpful post
    #6
    wojtek2112
    Level 13  
    Jak masz ustawione spi ,musi być soft. Ustawienie hard nie chciało u mnie
    współpracować z tym mcp.Napięcie referencyjne mcp miałem ustawione na
    4,096 v.Nie wiem jak jest u ciebie.Zresztą poczekaj trochę podłączę ten układ i sprawdzę działanie tego listingu (1 godz).
  • #7
    pawwik
    Level 11  
    Code:
    $regfile = "m8def.DAT"
    
    $crystal = 3686400
    $baud = 2400

    $hwstack = 32
    $swstack = 10
    $framesize = 40




    Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5
    Dim Adres_mcp As Byte
    Dim Odczyt_mcp(2) As Byte
    Dim A As Word
    Dim String_lcd As String * 8
    Dim Wart_nap As String * 8

     Spiinit
    Cs Alias Portb.2
    Clk Alias Portb.5
    Config Portb.2 = Output
    Adres_mcp = &B110000
    'to jest adres dla mcp3208 dla channel 0, ale dla mcp3204 powinien być chyba taki sam , najwyżej skasuj ostatnie zero
    Do

    Set Cs
    Reset Cs
    Set Clk
    Reset Clk
    Shiftout Portb.3 , Clk , Adres_mcp , 0
    Spiin Odczyt_mcp(1) , 2
    Set Clk
    Set Cs
     'Print Odczyt_mcp(1) ; " " ; Odczyt_mcp(2)


    A = Odczyt_mcp(1)
    Shift A , Left , 8
    A = A + Odczyt_mcp(2)
    Shift A , Right , 4
    String_lcd = Str(a)
    Wart_nap = Format(string_lcd , "0.00")
    Print Wart_nap
    Waitms 500

    Loop
    End


    ok juz chodzi. dzieki wielkie:D
    powyzej dzialajacy kod
  • #8
    wojtek2112
    Level 13  
    Wszystko wygląda ok. To znaczy że na zmiennej odczyt_mcp(1) i(2) masz 0.
    Już podłączam tego mcp , sprawdzę u siebie jak to wygląda i zaraz dam znać. Mam nadzieję że damy sobie z tym radę.

    Dodano po 59 [minuty]:

    Sprawdziłem.U mnie wszstko chodzi ok. w moim listingu trzeba tylko dodać config pinb.1=output i set portb.1. Pozdrawiam.
  • #9
    Coppio
    Level 11  
    Witam,
    To niestety ja mam dalej problem z połączeniem A/D, czy możecie doradzić? może 8MHz to za dużo?

    Code:

    $regfile = "m8def.DAT"
    $crystal = 8000000
    '$baud = 2400

    '$hwstack = 32
    '$swstack = 10
    '$framesize = 40



    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2


    'Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5
    Config Spi = Soft , Din = Pinb.5 , Dout = Portb.4 , Ss = None , Clock = Portb.3
    'MCP3204 Din --> MOSI, Dout --> MISO, SCK --> CLK, /CS --> PBO


    Dim Adres_mcp As Byte
    Dim Odczyt_mcp(2) As Byte
    Dim A As Word
    Dim String_lcd As String * 8
    Dim Wart_nap As String * 8

    Spiinit

    'Cs Alias Portb.2
    'Clk Alias Portb.5
    Cs Alias Portb.0
    Clk Alias Portb.3

    Config Portb.2 = Output
    Adres_mcp = &B110000

    Do

    Set Cs
    Reset Cs
    Set Clk
    Reset Clk
    Shiftout Portb.4 , Clk , Adres_mcp , 0
    Spiin Odczyt_mcp(1) , 2
    Set Clk
    Set Cs

    Cls
    Locate 1 , 1
    'Print Odczyt_mcp(1) ; " " ; Odczyt_mcp(2)
    Lcd Odczyt_mcp(1) ; " " ; Odczyt_mcp(2)
    Waitms 500

    A = Odczyt_mcp(1)
    Shift A , Left , 8
    A = A + Odczyt_mcp(2)
    Shift A , Right , 4
    String_lcd = Str(a)
    Wart_nap = Format(string_lcd , "0.00")
    'Print Wart_nap
    Cls
    Locate 1 , 1
    Lcd Wart_nap
    Waitms 500

    Loop
    End
  • #10
    wojtek2112
    Level 13  
    Witam . Czytałem twój listing i zauważyłem jedną rzecz . Jeżeli przypisałeś CS do portb.0 to musisz skonfigurować ten
    port jako wyjściowy czyli config pinb.0=output i set portb.0 .
    A w tej chwili masz ten port w ogóle nie skonfigurowany i
    sygnału zezwalającego CS dla MCP3204 w ogóle nie ma .

    Przepraszam że tak późno odpisuję ale dopiero dzisiaj przeczytałem
    ten post .
  • #11
    Coppio
    Level 11  
    Wielkie dzięki! jak wrce do domu dam znać czy zadziałało. :D
  • #12
    Coppio
    Level 11  
    wojtek2112, wczoraj wstawiłem Twój kod i dalej nic... Ale tak jak mówiłeś zaczołem sprawdzić PCB i mój błąd --> zmienione połączenia interfejs SPI, a teraz poprawiłem i jest OK
    Dzięki za pomoc.
  • #13
    pawelko111
    Level 12  
    Witam serdecznie

    Mam podobny problem z tym przetwornikiem MCP3202, oto kod:

    Code:

    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 9600                                                ' use baud rate
    $hwstack = 48                                               ' default use 32 for the hardware stack
    $swstack = 20                                               ' default use 10 for the SW stack
    $framesize = 80
    Enable Interrupts

    Config Serialout = Buffered , Size = 254

    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.6 , Db6 = Portc.5 , Db7 = Portc.4 , E = Portd.2 , Rs = Portd.3

    Config Spi = Soft , Din = Portb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5

    Dim Adres_mcp As Byte
    Dim Odczyt_mcp(2) As Byte

    Config Portc.4 = Output
    Config Portb.4 = Input
    Config Portb.3 = Output
    Config Portb.5 = Output

    Set Portc.4

    Spiinit

    Cs Alias Portc.4
    Clk Alias Portb.5
    Dout Alias Portb.3

    Din Alias Portb.4
    Adres_mcp = &B11000000

    Dim W As Word
    Dim V As Single
    Dim Licznik As Word
    Dim Z As String * 6

    W = 0
    Licznik = 1
    Cls
    Set Cs

    Do
    Reset Cs
    Set Clk
    Reset Clk
    Waitus 50
    Shiftout Dout , Clk , Adres_mcp , 0 , 4
    Spiin Odczyt_mcp(1) , 2
    Set Clk
    Set Cs

    Cls
    W = Odczyt_mcp(1)
    Shift W , Left , 8
    W = W + Odczyt_mcp(2)
    Shift W , Right , 4
    V = W * 4.9
    V = V / 4096
    Z = Fusing(v , "#.&&&")
    Cls
    Locate 1 , 1
    Lcd Licznik ; " " ; W ; " " ; Odczyt_mcp(1) ; " " ; Odczyt_mcp(2)
    Lowerline
    Lcd "V= " ; Z
    Waitms 500
    Licznik = Licznik + 1
    Loop                                                        'koniec pętli
    End                                                         'koniec programu głównego



    Niby wszystko działa. Podłączyłem do kanału CH0 przetwornika przez dzielnik 1:2 napięcie zasilania (czyli około 2,4V).
    Otrzymuję poprawny wynik, czyli komunikacja "działa".
    Największy problem w tym, ze na 100 pomiarów mam około 40 pomiary poprawne, reszta to 0 lub napięcie maksymalne lub jakieś śmieci.
    Nawet gdybym uśrednił to jaka to będzie średnia, gdy pojawiają się śmieci. Próbkowanie przetwornika co 500ms.
    Tak jakby był jakiś problem z komunikacją w sensie synchronizacji.
    Próbowałem jakieś kombinacje na spi=hard i wstawki asm ale bez skutku ( z innych wątków na forum)

    Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = Low , Interrupt = Off , Phase = 1 , Clockrate = 16 , Noss = 1
    ---
    <ciach>
    Do
    Reset Cs
    Spdr = &B11000000
    Gosub Spi_wait
    Spdr = &H00
    Gosub Spi_wait
    Odczyt_mcp(1) = Spdr
    Spdr = &H00
    Gosub Spi_wait
    Odczyt_mcp(2) = Spdr
    Set Cs
    ---
    <ciach>
    W tym wypadku otrzymuję 2 bajty po 255 :(

    Byłbym bardzo wdzięczny za pomoc.
  • #14
    rpal
    Level 27  
    Kolego jeszcze raz przestudiuj notę katalogową tym bardziej że wykłada sprawę łopatologicznie. Obsługa tego przetwornika jest iście banalna a sprowadza się w C dosłownie dosłownie do kilku linijek kodu. W nocie masz maksymalną częstotliwość taktowania linii SCK która nie ma wiele wspólnego z prędkością taktowania twojego uP. O ile dobrze pamiętam to można do śmiało pogonić 2MHz na spi.
    Wysyłasz komendę, potem jakąkolwiek wartość gdzie okreslone są tylko bity 7,6 i trzecią dowolną wartość. Jednoczesnie odcztytujesz to co nadchodzi z przetwornika. Pierwsza wartość to śmieć, druga to MSB odczytanej wartości z czego wazne są tylko bity 3,2,1,0, trzecia wartość do LSB danej. Łączysz MSB z LSB i otrzymujesz 16bitową liczbę z wartością odczytaną z przetwornika, nawet jeśli jest to przetwornik 12bitowy. O ile mnie oczy nie mylą bo na tym całym basicu nie mam nawet zamiaru się cokolwiek wyznawać to wysyłasz tylko 2 bity zapominając o trzecim. A jesli się mylę w jego składni to tak czy inaczej otrzymujesz 255 ponieważ przetwornik nic nie wysyła na zewnątrz utrzymując swoje wyjście w stanie HIGH albo też masz po prostu zwartą linię MISO to zasilania.
  • #15
    mateuszwid
    Level 10  
    Witam :)
    Jeżeli chodzi o problemy z MCP3204 to chciałbym się podzielić swoim doświadczeniem. Miałem problem z tą kostką, mianowicie: wysyłając dane do przetwornika, odbierałem drugi bajt (z MSB wyniku) EF i ostatni bajt FF. Wydawało by się więc że otrzymuję poprawny wynik dla wartości maks na wejściu napięciowym przetwornika (ładnie było wśród tych jedynek widać bit startu :P). Niestety taki wynik otrzymywałem dla każdego kanału i dla dowolnego napięcia. Schemat połączenia wydawał się ok, komunikacja po SPI z MCP też. Wysyłając głupoty do MCP, to otrzymywałem same jedynki, nie było bitu startu. Taki sam efekt otrzymywałem nie kasując CS . Czyli wydawało się że MCP jest ok. Niestety tak nie było. Po wymianie kostki wszystko z miejsca ruszyło.

    Pozdrawiam
  • #16
    Eltok
    Level 10  
    Witam! Chciałbym dodać coś istotnego do tej dyskusji. Kilka razy podchodziłem do w/w tematu, ale w żaden sposób MCP3204 nie chciał pracować prawidłowo. Niby działał, pokazywał właściwe napięcie, ale tylko w niektórych fragmentach mierzonego napięcia.
    W pewnych miejscach zakresu gubił się, pokazywał dziwne wielkości i co drugi pomiar wyskakiwały same zera. No i wreszcie doszedłem, co było nie tak (w moim przypadku!).
    Listing kol. Pawwika jest prawidłowy, poza jednym szczegółem: Zmienne Odczyt_mcp muszą być zerowane na początku pętli, bo w przeciwnym wypadku pozostałości po poprzednim pomiarze w jakiś dziwny sposób mieszają się z pomiarem aktualnym i wychodzi kaszana. Nigdzie na forach nie spotkałem się z opisem takiego problemu, więc postanowiłem go przedstawić, bo być może był on nie tylko moim problemem.
    Jestem ciekaw, czy ktoś z kolegów potwierdzi ten przypadek.