i databladet, det står att jag ska använda 32 seriella klockor för att få 32 bitar av data. Jag programmerar att detta är Arduino?
Kommentarer
Svar
Du ringer till SPI.transfer()
fyra gånger, varje gång sparar det returnerade värdet till en variabel efter korrekt bitförskjutning.
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;
Jag antar att det är minst betydelsefullt byte tas emot först. Se till att SPI-läget är rätt, som anges i databladet.
Om slaven inte kan hantera omfördelning mellan byte (vilket är SPI.transfer()
kommer att göra i slutet av transaktionen), då kan du antingen prova st2000 ”s SPI-metod för hårdvara eller använda bitbanged SPI med shiftIn()
.
Kommentarer
- Inte säker på att det här fungerar. Vi måste verkligen veta hur SPI-slaven fungerar innan vi kan anta hur den kommer att reagera. Dessutom, om Chip Select-raden hävdas och avvisas vid varje 8-bitars SPI-transaktion, hur väl är SPI-slaven utformad? Det vill säga att en sådan SPI-slav lätt kan komma ur synkronisering med SPI-mästaren. Specifikt, hur är du säker på vilken 8-bitars byte du faktiskt läser?
- @ st2000 OP-sågen passar för att inte ge tillräckligt med detaljer; ingenting annat än antaganden kan göras förrän det ändras.
- Alla exempel jag ’ har sett använder SPI, överför (0) för att läsa data snarare än SPI.transfer (0xff). De använder också SPI.transfer för att skriva data. Jag har fortfarande inte ’ tänkt på vad SPI gör med 0 eller 0xff när du faktiskt läser data. Skickas detta till slaven?
- @ S.Imp De ’ är dummybyte. Du kan skicka vad du vill skicka, enheten i andra änden kommer fortfarande att kasta dem, om det till och med betalar data åt något.
SPI.transfer()
används alltid delvis på grund av SPI: s inneboende full-duplex natur (och som ett resultat av den första faktorn), delvis på grund av hur de flesta MCU: er implementerar sina SPI-kringutrustning. När klockan börjar gå finns det alltid ” data ” på MOSI- och MISO-raderna, det ’ är bara upp till varje deltagare på bussen för att läsa det eller inte, besluta baserat på vad som helst fördefinierat protokoll med högre lager om ” data ” är meningsfullt eller inte. - Det skulle ’ inte vara helt felaktigt att säga att du kan ’ t läser verkligen utan att skriva på en SPI-buss och vice versa också. Så det är vettigt att helt enkelt utforma en kringutrustning som tar en byte i ett register och, åtta cykler senare, returnerar en byte i ett annat (eller till och med samma) register, bara för att generalisera usecases. Sedan ’ är det upp till användaren ’ s applikation att avgöra om de ’ bara intresserad av den byte som först skrevs ut (TX) eller den som lästes upp (RX) eller båda (TX och RX). Därifrån det tvetydiga namnet
transfer()
eftersom det tjänar både läs- och skrivroller.
Svar
Sparkfun har en bra förklaring av vad SPI är:
https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi
Arduino IDE har ett SPI-bibliotek som följer med IDE.
http://www.arduino.cc/en/Reference/SPI
Biblioteket har två exempel:
Använda SPI för att läsa en barometrisk trycksensor
Styrning av en digital potentiometer med SPI
Svar
Målet är att läsa 32 bitar med den (okända) enhetens SPI-port.
Om enheten tolererar SPI Chip Select-linjeaktivitet (går från inaktiv till aktiv till inaktiv för varje 8 bit byte läst) bör du kunna få de önskade 32 bitarna av data genom att utföra 4 på varandra följande 8 bit SPI läser.
Men om enheten inte tolererar ovanstående SPI Chip Select-linjeaktivitet (det vill säga om enheten kräver att SPI Chip Select är aktiv för hela 32-bitars SPI-transaktionen), Du kan inte separera 32-bitars transaktionen i 4 individuella 8-bitars SPI-transaktioner utan att styra SPI Chip Select-raden. Följande kodexempel illustrerar hur detta görs:
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); }
Exemplet ovan kommer från Arduino SPI-bibliotek webbsida och är en 16-bitars (inte 32-bitars) överföring. För att koda upp en 32-bitars överföring, fortsätt att ringa SPI.transfer-metoden med parametern SPI_CONTINUE.
läggs till senare …
Det verkar som att människor avskräcker användningen av DueExtendedSPI-metoderna . Och SPISettings och SPI.beginTransaction () ska användas? Om så är fallet denna sida visar exempelkod där koden uttryckligen kontrollerar SPI Chip Select-raden (leta efter slaveAPin & slaveBPin). Notera hur koden läser 24 bitar från slav A och skriver 8 bitar till slav B. För att läsa 32 istället för 24 bitar måste vi ändra ett segment av koden (tillsammans med några andra stödjande ändringar) på detta sätt:
... 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(); ...
Kommentarer
- Vi behöver verkligen se specifikationerna för slave SPI-enheten för att komponera en mer specifikt svar.
- Jag använder STPM10 utvärderingskort. Anslutningen är en synkron synkron SPI, och Arduinos MOSI är inte ansluten till någonting. Det finns ett tidsdiagram för att växla från skrivskyddad och skrivskyddad. Mina problem är hur man läser data från chipets register. Jag använde SPI.transfer men jag tycker inte ’ att uppgifterna är tillförlitliga.
- STPM10-tidsdiagrammet som finns på sidan 11 i det ’ s specifikation ser inte ut som en vanlig SPI-transaktion. Jag är benägen att säga att du inte kan använda Arduino SPI-biblioteket. Istället kan du behöva bit-bang detta helt i programvara. Jag tror till exempel inte att det finns en ” SYN ” -rad i SPI-standardbussen. Och jag tror inte ’ att Chip Select-raden ska gå högt innan SPI-transaktionen är slut.
byte result[4]; for (i = 0; i < 4; i++) result[i] = SPI.transfer(0x00);
och du hittar iresult
de 32 bitarna du behöver