Cum să citiți date folosind Arduino SPI

în foaia de date, se spune că ar trebui să aplic 32 de ceasuri seriale pentru a obține cei 32 de biți de date. Programez acesta este Arduino?

Comentarii

  • Vă sugerez să deschideți exemplele bibliotecii SPI și să le verificați. Oricum, codul ar trebui să fie byte result[4]; for (i = 0; i < 4; i++) result[i] = SPI.transfer(0x00); și veți găsi în result cei 32 de biți de care aveți nevoie
  • Am făcut deja asta. dar cipul de energie Utilizez este STPM10 și sugerează că ar trebui să folosesc SPI sincron simplex acolo unde MOSI nu este conectat. Există doar o diagramă de sincronizare pentru a trece de la octeți de citire și octeți de scriere. Când am folosit SPI.transfer (), datele nu sunt stabil și cred că nu este de încredere
  • Cum spuneți că nu este de încredere? Perifericul este full duplex și, în funcție de modul în care funcționează, singura modalitate de a primi date este prin trimiterea de date fictive. Dacă MOSI este nu este conectat, ei bine, nu contează ‘ ; rețineți totuși că nu puteți ‘ t utiliza pinul MOSI pentru alte sarcini. Apropo, ți-ai amintit să setezi corect pinul de selectare a sclavului celuilalt periferic? Ați folosit pinul SS pe placa arduino sau pe altul?

Răspuns

Sună SPI.transfer() de patru ori, salvând de fiecare dată valoarea returnată la o variabilă după schimbarea corectă de biți.

uint32_t val; val = SPI.transfer(0xff); //0xff is a dummy val |= (uint32_t)SPI.transfer(0xff) << 8; val |= (uint32_t)SPI.transfer(0xff) << 16; val |= (uint32_t)SPI.transfer(0xff) << 24; 

Presupun că este cel mai puțin semnificativ octetul este primit mai întâi. Asigurați-vă că modul SPI este cel potrivit, așa cum este indicat în foaia dvs. de date.

Dacă sclavul nu poate fi deasertat între octeți (ceea ce este SPI.transfer() va face la sfârșitul tranzacției), apoi puteți încerca abordarea SPI hardware a lui st2000 sau puteți utiliza SPI bitbanged cu shiftIn().

Comentarii

  • Nu sunt sigur că acest lucru va funcționa. Trebuie să știm cum funcționează sclavul SPI înainte de a putea presupune cum va reacționa. De asemenea, dacă linia Chip Select este afirmată și dezactivată cu fiecare tranzacție SPI pe 8 biți, cât de bine este proiectat sclavul SPI? Adică, un astfel de sclav SPI ar putea ieși ușor din sincronizare cu masterul SPI. Mai exact, cum vă asigurați ce octet de 8 biți citiți de fapt?
  • @ st2000 OP a văzut potrivit pentru a nu da suficiente detalii; nu se pot face altceva decât presupuneri până când acest lucru nu se modifică.
  • Toate exemplele pe care le-am văzut folosesc SPI, transfer (0) pentru a citi date, mai degrabă decât SPI.transfer (0xff). De asemenea, utilizează SPI.transfer pentru scrierea datelor, de asemenea. ‘ încă nu mi-am dat seama ce face SPI cu 0 sau 0xff atunci când citiți de fapt datele. Este trimis acest lucru sclavului?
  • @ S.Imp Ei ‘ re octeți fictivi. Puteți trimite orice doriți să trimiteți, dispozitivul de la celălalt capăt le va arunca în continuare, chiar dacă plătește datele cu orice minte. SPI.transfer() este întotdeauna utilizat parțial din cauza naturii intrinseci full-duplex a SPI și (ca urmare a primului factor) apoi parțial din cauza modului în care majoritatea MCU-urilor își implementează perifericele SPI. Odată ce ceasul începe să ruleze, există întotdeauna ” date ” pe liniile MOSI și MISO, acesta ‘ depinde de fiecare participant de pe autobuz să-l citească sau nu, decidând în funcție de protocolul de strat superior predefinit dacă ” date ” este semnificativ sau nu.
  • Nu ar fi ‘ nu ar fi total incorect să spui că poți ‘ nu citiți cu adevărat fără să scrieți pe un autobuz SPI și invers. Deci, are sens să proiectăm pur și simplu un periferic care ia un octet într-un registru și, 8 cicluri mai târziu, returnează un octet într-un alt registru (sau chiar același), doar pentru a generaliza casele de utilizare. Apoi, ‘ depinde de cererea utilizatorului ‘ pentru a decide dacă ‘ re interesat doar de octetul care a fost scris în primul rând (TX) sau cel care a fost citit înapoi (RX) sau ambele (TX și RX). De asemenea, de aici și numele ambiguu transfer(), deoarece servește atât rolurilor de citire, cât și de scriere.

Răspuns

Răspuns

Obiectivul este de a citi 32 de biți folosind portul SPI al dispozitivului (necunoscut).

Dacă dispozitivul va tolera activitatea liniei SPI Chip Select (trecând de la inactiv la activ la inactiv pentru fiecare citit de 8 biți de octet) ar trebui să puteți obține cei 32 de biți de date dorite efectuând 4 8 consecutiv bit SPI citește.

Cu toate acestea, dacă dispozitivul nu va tolera activitatea de linie SPI Chip Select de mai sus (adică, dacă dispozitivul necesită ca SPI Chip Select să fie activ pentru întreaga tranzacție SPI pe 32 biți), nu puteți separa tranzacția de 32 biți în 4 tranzacții SPI individuale de 8 biți fără a controla linia SPI Chip Select. Următorul exemplu de cod ilustrează modul în care se face acest lucru:

void loop(){ //transfer 0x0F to the device on pin 10, keep the chip selected SPI.transfer(10, 0xF0, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, keep the chip selected SPI.transfer(10, 0×00, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, store byte received in response1, keep the chip selected byte response1 = SPI.transfer(10, 0×00, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, store byte received in response2, deselect the chip byte response2 = SPI.transfer(10, 0×00); } 

Exemplul de mai sus provine din Arduino SPI library pagină web și este un transfer pe 16 biți (nu pe 32 de biți). Pentru a codifica un transfer pe 32 de biți, continuați să apelați metoda SPI.transfer folosind parametrul SPI_CONTINUE.

adăugat mai târziu …

Se pare că oamenii descurajează utilizarea metodelor DueExtendedSPI . Și SPISettings și SPI.beginTransaction () urmează să fie utilizate? Dacă da, această pagină arată un exemplu de cod în care codul controlează în mod explicit linia SPI Chip Select (căutați slaveAPin & slaveBPin). Rețineți cum codul citește 24 de biți de la sclavul A și scrie 8 biți la sclavul B. Pentru a citi 32 în loc de 24 de biți, trebuie să modificăm un segment al codului (împreună cu alte câteva modificări de susținere) în acest mod:

... SPI.beginTransaction(settingsA); digitalWrite (slaveAPin, LOW); // reading only, so data sent does not matter val0 = SPI.transfer(0); val1 = SPI.transfer(0); val2 = SPI.transfer(0); val3 = SPI.transfer(0); digitalWrite (slaveAPin, HIGH); SPI.endTransaction(); ... 

Comentarii

  • Trebuie să vedem specificațiile dispozitivului SPI slave pentru a compune un răspuns specific.
  • Folosesc tabloul de evaluare STPM10. Conexiunea este un SPI sincron simplex, iar MOSI-ul Arduino nu este conectat la nimic. Există o diagramă de sincronizare pentru a comuta de la numai citire și numai la scriere. Problemele mele sunt cum să citesc datele din registrele cipului. Am folosit SPI.transfer, dar nu ‘ nu cred că datele sunt fiabile.
  • Diagrama de sincronizare STPM10 găsită la pagina 11 a acestuia nu arată ca o tranzacție standard SPI. Sunt înclinat să spun că nu puteți utiliza biblioteca Arduino SPI. În schimb, este posibil să trebuiască să eliminați totul în software. De exemplu, nu cred că există o linie ” SYN ” în magistrala SPI standard. Și nu ‘ nu cred că linia Chip Select ar trebui să meargă înainte de sfârșitul tranzacției SPI.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *