in the datasheet, it's stated that I should apply 32 serial clocks to get the 32 bits of data. How can I program this is Arduino?
asked Apr 27, 2016 at 12:14 Lorenz Ardiente Lorenz Ardiente 31 1 1 gold badge 1 1 silver badge 4 4 bronze badgesI suggest you to open the examples of the SPI library and check them. Anyway, the code should be byte result[4]; for (i = 0; i < 4; i++) result[i] = SPI.transfer(0x00); and you will find in result the 32 bits you need
Commented Apr 27, 2016 at 12:45I already did that. but the energy chip I am using is STPM10 and it suggests that I should use simplex synchronous SPI where the MOSI is not connected. there is just a timing diagram to switch from reading bytes and writing bytes. When I used SPI.transfer(), The data is not stable and I think not reliable
Commented Apr 29, 2016 at 6:10How do you say it is not reliable? The peripheral is full duplex, and according to the way it works the only way to receive data is by sending dummy data. If MOSI is not connected, well, it doesn't matter; note however that you can't use the MOSI pin for other tasks. By the way, did you remember to correctly set the slave select pin of the other peripheral? Did you use the SS pin on the arduino board or another one?
Commented Apr 29, 2016 at 9:55You call SPI.transfer() four times, each time saving the returned value to a variable after proper bit shifting.
uint32_t val; val = SPI.transfer(0xff); //0xff is a dummy val |= (uint32_t)SPI.transfer(0xff)
I assume the least significant byte is received first. Make sure the SPI mode is the right one, as indicated in your datasheet.
If the slave can't handle being deasserted between bytes (which is what SPI.transfer() will do at the end of the transaction), then you can either try st2000's hardware SPI approach or use bitbanged SPI with shiftIn() .
answered Apr 27, 2016 at 13:07 SoreDakeNoKoto SoreDakeNoKoto 2,422 2 2 gold badges 13 13 silver badges 23 23 bronze badgesNot sure this will work. We really need to know how the SPI slave works before we can assume how it will react. Also, if the Chip Select line is asserted and de-asserted with each 8 bit SPI transaction, how well is the SPI slave designed? That is, such a SPI slave could easily get out of sync with the SPI master. Specifically, how are you assured which 8 bit byte you are actually reading?
Commented Apr 27, 2016 at 14:13@st2000 The OP saw fit to not give enough details; nothing but assumptions can be made till that changes.
Commented Apr 27, 2016 at 14:59All the examples I've seen use SPI,transfer(0) to read data rather than SPI.transfer(0xff). They also use SPI.transfer for writing data, too. I still haven't figured out what SPI does with the 0 or 0xff when you are actually reading data. Is this sent to the slave?
Commented Jun 20, 2020 at 20:30@S.Imp They're dummy bytes. You can send whatever you want to send, the device at the other end will still discard them, if it even pays the data any mind. SPI.transfer() is always used partly because of the intrinsic full-duplex nature of SPI and (as a result of the first factor) then partly because of the way most MCUs implement their SPI peripherals. Once the clock starts running, there is always "data" on the MOSI and MISO lines, it's just up to each participant on the bus to read it or not, deciding based on whatever predefined higher-layer protocol if the "data" is meaningful or not.
Commented Jun 23, 2020 at 22:22It wouldn't be totally incorrect to say you can't truly read without writing on an SPI bus and vice versa as well. So it makes sense to simply design a peripheral that takes a byte in one register and, 8 cycles later, returns a byte in another (or even the same) register, just to generalize usecases. Then it's up to the user's application to decide if they're only interested in the byte that was written out in the first place (TX) or the one that was read back (RX) or both (TX and RX). Also, hence the ambiguous name transfer() since it serves both reading and writing roles.
Commented Jun 23, 2020 at 22:31The Arduino IDE has a SPI library that comes with the IDE.
http://www.arduino.cc/en/Reference/SPI
Objective is to read 32 bits using the (unknown) device's SPI port.
If the device will tolerate the SPI Chip Select line activity (going from inactive to active to inactive for each 8 bit byte read) you should be able to get the desired 32 bits of data by performing 4 consecutive 8 bit SPI reads.
However, if the device will not tolerate the above SPI Chip Select line activity (that is, if the device requires the SPI Chip Select to be active for the entire 32 bit SPI transaction), you can not separate the 32 bit transaction into 4 individual 8 bit SPI transactions with out controlling the SPI Chip Select line. The following code example illustrates how this is done:
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); >
The above example comes from the Arduino SPI library web page and is a 16 bit (not 32 bit) transfer. To code up a 32 bit transfer, continue to call the SPI.transfer method using the SPI_CONTINUE parameter.
It appears people are discouraging use of the DueExtendedSPI methods. And SPISettings and SPI.beginTransaction() are to be used? If so this page show example code where the code is explicitly controlling the SPI Chip Select line (look for slaveAPin & slaveBPin). Note how the code is reading 24 bits from slave A and writing 8 bits to slave B. To read 32 instead of 24 bits, we need to alter a segment of the code (along with a few other supporting changes) in this fashion:
. 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(); .