Pages: [1]   Go Down
Author Topic: Hardware SPI: how to shift out less than 1 byte?  (Read 730 times)
0 Members and 1 Guest are viewing this topic.
Russia
Offline Offline
Newbie
*
Karma: 1
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone.
I'm interfacing 12-bit Serial DAC (DAC8512), and it seems from datasheet that it expects exactly 12 bits of data clocked in by SPI bus.

Clocking out 12 significant bits and then 4 zeroes (8+8 bits) results in weird waveform on my scope.

So I'm just curious: is it possible to clock out exactly 12 bits?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 597
Posts: 33304
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
is it possible to clock out exactly 12 bits?
Not with the hardware SPI.
You will have to bit bang the signals to get your 12 bits.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8667
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you try putting the 4 zeroes BEFORE your data?  SPI devices often take the last N bits.

An alternative is to use software SPI but that will be relatively slow.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Anaheim CA.
Offline Offline
Faraday Member
**
Karma: 46
Posts: 2864
...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

John is right much easier to send it as an int and mask off the unwanted bits.

Doc
Logged

--> WA7EMS <--
“The solution of every problem is another problem.” -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Judging by the datasheet you can send 12 bits followed by a few "don't care":

Quote
The 74HC161 counter in incremented on every rising edge of the clock. Additionally, the data is loaded into the DAC8512 on the falling edge of the clock by inverting the serial clock using gate “Y.” The timing diagram shows that after the twelfth bit has been clocked the output of the counter is binary 1011. On the very next rising clock edge, the output of the counter changes to binary 1100 upon which the output of gate “X” goes LOW to generate the LD pulse. The LD signal is connected to both the DAC’s LD and the counter’s LOAD pins to prevent the thirteenth rising clock edge from advancing the DAC’s internal shift register. This prevents false loading of data into the DAC8512.

I would be very surprised if modern designers expected exactly 12 bits. More like 16 bits with a provision to ignore some of them, as the above seems to state.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If I'm wrong (and I've been wrong before smiley-wink  ) here is some code for bit-banged SPI:

http://www.gammon.com.au/forum/?id=10892&reply=6#reply6

You would need to adapt it a bit to do 12 bits.
Logged

Russia
Offline Offline
Newbie
*
Karma: 1
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

johnwasser, thanks, that resolved some issue, but now other problem occurs.

Here is my code:
Code:
//Init SPI
pinMode (SPI_DAC_CS_PIN, OUTPUT);
pinMode (DAC_LD_PIN,OUTPUT);

SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);

while(1){
for (int b=0;b<4095;b++)
{
//Prepare to output 2 bytes: SPI CS assert LOW, DAC latch set high.

digitalWrite(DAC_LD_PIN,HIGH);
digitalWrite(SPI_DAC_CS_PIN,LOW);

//  send in the value via SPI:
SPI.transfer((b>>8));  // High byte
SPI.transfer((b&0xFF)); //Low byte

//Assert CS low
digitalWrite(SPI_DAC_CS_PIN,HIGH);
delayMicroseconds(1);

//Now set the DAC to load register to output (LD Low->High).
digitalWrite(DAC_LD_PIN,LOW);
delayMicroseconds(1);
digitalWrite(DAC_LD_PIN,HIGH);

delayMicroseconds(10);//Set a delay to simplify scope analysis
}
delay(200); //200ms delay between cycles
}

The DAC is 12-bit, so, by datasheet, should get values between 0 and 4095. When we send some zeroes before valuable data, the DAC input shift register just shifts that zeroes to the left out of register, so only 12 bits remain.

That code is supposed to go from 0 to 4095, resulting in 0-to-4.095V "saw" with delay between each cycle.

The problem is that DAC seems to read only 11 bit, so I get not single "saw", but a double "saw". Attached is info from my scope:

So I'm curious: Does the SPI send something other than my 2 bytes to line? Maybe some control bits between each of my byte?


* NewFile0.gif (4.82 KB, 320x234 - viewed 17 times.)
Logged

Russia
Offline Offline
Newbie
*
Karma: 1
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solved. Changing SPI to MODE3 instead of MODE0 helped.
However, it seems to me that MODE0 is the right mode, according to datasheet.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Page 4 of the datasheet shows the clock normally high, so modes 2 or 3 would be appropriate.

Then the first diagram on that page shows the sampling of D11 on the leading edge, so it seems to me that mode 2 is possibly more correct.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5846
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solved. Changing SPI to MODE3 instead of MODE0 helped.
However, it seems to me that MODE0 is the right mode, according to datasheet.
Not the way I see it. Page 4 of the datasheet says clock is HIGH with LOW pulses (CPOL=1) and captures on the rising edge and propagates on the falling edge (CPHA=1).
That is mode 3.
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

edit: Here is how to compute mode. The phase (CPHA) isn't based on rising or falling edge as I might have implied above, but first or second edge after the slave select is activated (LOW).

If clock is LOW with HIGH pulses, then CPOL = 0.
If clock is HIGH with LOW pulses, then CPOL = 1.

If it captures on the first edge (rising or falling) after SS goes LOW, then CPHA=0
If it captures on the second edge (rising or falling) after SS goes LOW, then CPHA=1

MODE = 2CPOL + CPHA
« Last Edit: June 17, 2013, 03:52:01 am by SurferTim » Logged

Russia
Offline Offline
Newbie
*
Karma: 1
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for making it clear smiley
Logged

Pages: [1]   Go Up
Jump to: