Go Down

Topic: SPI read write for 32bits data (Read 7 times) previous topic - next topic

retrolefty


Hi Gray,

         Attached is the datasheet. Thanks a lot


Well I think you might be confused. From your datasheet:

Quote

7.4 Command Interface
Commands and data are transferred most-significant bit
(MSB) first. Figure 1 on page 12, defines the serial port
timing. Commands are clocked in on SDI using SCLK.
They are a single byte (8 bits) long and fall into one of
four basic types:
1. Register Read
2. Register Write
3. Synchronizing
4. Instructions


There are 32 different byte size registers to work with on the chip, but it's designed for simple SPI byte size read and write operations.

Lefty

Paradigm

Hi Lefty,

            It says when reading data from SDO, example my instantaneous voltage (which is 32bits), I need to send the SYNC0 and SYNC1 to the SDI pins if not other command is needed. Thats why I need to send (0x04FFFEFF). Or did I misinterpret the datasheet. With CS pin, I dont need to send the SYNC0. Anyhow, my data is also 32bits. How can i read the 32bits data with SPI.transfer? Or write a sub-routine of 

unsigned long SPI_read(byte Address)

7.6.2 Synchronization (SYNC0 and SYNC1)
The serial interface is bidirectional. While reading data on the SDO output, the SDI input must be receiving
commands. If no command is needed during a read, SYNC0 or SYNC1 commands can be sent while read
data is received on SDO.
The serial port is normally initialized by de-asserting CS. An alternative method of initialization is to send 3 or
more SYNC1 commands followed by a SYNC0. This is useful in systems where CS is not used and tied low.

Pls help. Thanks a lot

SurferTim

#12
Nov 20, 2012, 01:33 pm Last Edit: Nov 20, 2012, 02:16 pm by SurferTim Reason: 1
Quote
0x04FFFEFF

If this is what you want to send, and SS is the slave select pin number, then this should do it.
Code: [Select]
digitalWrite(SS,LOW);
var0 = SPI.transfer(0x04);
var1 = SPI.transfer(0xFF);
var2 = SPI.transfer(0xFE);
var3 = SPI.transfer(0xFF);
digitalWrite(SS,HIGH);

edit: Some devices need a small pause between enabling the SPI interface and starting the transfer. I usually put a "delayMicroseconds(1);" after "digitalWrite(SS,LOW);".

Tom Carpenter

#13
Nov 20, 2012, 10:27 pm Last Edit: Nov 22, 2012, 11:02 am by Tom Carpenter Reason: 1
Modified my example from before based on the datasheet:
Code: [Select]
#include <SPI.h>

union FourByte{
   struct {
     unsigned long value:24; //24bit register values go in here
     byte command:8; //8bit command goes in here.
   };
   byte bit8[4]; //this is just used for efficient conversion of the above into 4 bytes.
};

void setup(){
 SPI.begin();
 SPI.setBitOrder(MSBFIRST);
 SPI.setDataMode(SPI_MODE3); //I believe it to be Mode3
  SPI.setClockDivider(SPI_CLOCK_DIV16);
 pinMode(SS, OUTPUT); //not really necessary as it is done by the SPI library.
 digitalWrite(SS, HIGH);
 //Page
 //example of reading data
 unsigned long voltage = SPI_read(4);//Instantaneous Voltage Channel 1
 
 //example of writing data
 union FourByte data;
 data.command = 0b01000000; //Write to config register
 data.value = 1; //This is the default value from datasheet, just using it as an example.
 SPI_write(data);
}

void loop(){
 
}

void SPI_write(union FourByte data) {
 digitalWrite(SS,LOW); //Using CS pin, so sync1/sync0 bytes not needed
 for(char i = 3; i >= 0; i--){
   SPI.transfer(data.bit8[i]); //transfer all 4 bytes of data - command first, then Big Endian transfer of the 24bit value.
 }
 digitalWrite(SS,HIGH);
}

unsigned long SPI_read(byte command){
 digitalWrite(SS,LOW); //SS goes low to mark start of transmission
 union FourByte data = {0xFEFEFE,command}; //generate the data to be sent, i.e. your command plus the Sync bytes.
 for(char i = 3; i >= 0; i--){
   data.bit8[i] = SPI.transfer(data.bit8[i]); //send the data whilst reading in the result
 }
 digitalWrite(SS,HIGH); //SS goes high to mark end of transmission
 return data.value; //return the 24bit value recieved.
}
~Tom~

Jaay

#14
Nov 22, 2012, 03:05 am Last Edit: Nov 22, 2012, 05:05 am by Nick Gammon Reason: 1
I changed to this...but still not working...

Code: [Select]
#include <SPI.h>

int CS = 10;


union FourByte{
   struct {
     unsigned long value:24; //24bit register values go in here
     byte command:8; //8bit command goes in here.
   };
   byte bit8[4]; //this is just used for efficient conversion of the above into 4 bytes.
};

void setup(){
 SPI.begin();
 SPI.setBitOrder(MSBFIRST);
 SPI.setDataMode(SPI_MODE0);
 
 Serial.begin(9600);
 pinMode(CS, OUTPUT);
 digitalWrite(CS, HIGH);
 //Page
 //example of reading data
// unsigned long voltage = SPI_read(0x04);//Instantaneous Voltage Channel 1
 
 //example of writing data
 union FourByte INI;
 INI.command = 0b11111111; //Write to config register
 INI.value = 0xFFFFFE; //This is the default value from datasheet, just using it as an example.
 SPI_write(INI);
 
 
 union FourByte data;
 data.command = 0b11101000; //Write to config register
 data.value = 0xFFFFFE; //This is the default value from datasheet, just using it as an example.
 SPI_write(data);
}

void loop(){
 unsigned long voltage = SPI_read(0x04);
 Serial.print("Voltage=");
 Serial.println(voltage);
 delay(1000);
}

void SPI_write(union FourByte data) {
 digitalWrite(CS,LOW); //Using CS pin, so sync1/sync0 bytes not needed
 for(char i = 3; i >= 0; i--){
   SPI.transfer(data.bit8[i]); //transfer all 4 bytes of data - command first, then Big Endian transfer of the 24bit value.
 }
 digitalWrite(CS,HIGH);
}

unsigned long SPI_read(byte command){
 digitalWrite(CS,LOW); //SS goes low to mark start of transmission
 union FourByte data = {0xFEFEFE,command}; //generate the data to be sent, i.e. your command plus the Sync bytes.
 for(char i = 3; i >= 0; i--){
   data.bit8[i] = SPI.transfer(data.bit8[i]); //send the data whilst reading in the result
 }
 digitalWrite(CS,HIGH); //SS goes high to mark end of transmission
 return data.value; //return the 24bit value recieved.
}



Go Up