Loading...
Pages: [1]   Go Down
Author Topic: Driving 16 bit DAC  (Read 488 times)
0 Members and 1 Guest are viewing this topic.
Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm experimenting with the DAC TDA1543 that uses I2S communication (the name looks like I2C, but it's not the same).
The datasheet is here: http://www.datasheetcatalog.org/datasheet/philips/TDA1543.pdf

Since the communication protocol looked for me quite similar to the shiftout function, I've modified the following code to drive it:


Code:
void mishiftOut(word val, boolean wsSel)
// if wsSel is HIGH, RIGHT channel is selected.

{
uint8_t i;
        digitalWrite(WSPIN, wsSel);
for (i = 0; i < 16; i++)  {
digitalWrite(CLOCKPIN, HIGH);
                digitalWrite(DATAPIN, !!(val & (1 << (15 - i)))); //MSB FIRST
digitalWrite(CLOCKPIN, LOW);
}
        digitalWrite(WSPIN, !wsSel);
}


The wiring is prettey simple, 3 pins of the arduino are used to connect with the ICs data, clock and WS pins.
I've tested it, trying to get different DC voltages in the Analog Outputs (measuring with a multimeter), so far without success. Voltage does not change.
As far as I understand from the datasheet, once the signal is sent, the output should be latched. I'm not using a high frecuency, just sending a stream every 2 seconds.
As far as I understand from the datasheet, I should get an output between 1.8 and 3.8V (5V - 1.2V)
Does anyone have experience with this IC? Is the code I've written right?
Regards
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 269
Posts: 17032
Available for Design & Build services
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The code is probably fine. I would have suggested two SPI transfers per channel, or two shiftouts per channel, which you've basically duplicated.
How is your output wired up? Try adding a 10K pullup resistor, the output is a current sink, so you should see that wiggle some.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 282
Posts: 15443
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looking at fig 5, page 8 of the datasheet I think you need to add one more clock pulse after the WS change at the end of your function. So I think you have to shift out 15 bits, toggle WS and then send the LSB. At least give it a try. Even then I'm not sure all is setup correctly for the next call to the function? This seems to really want both channels to be clocked out as a set, as best I can tell.


Code:

void mishiftOut(word val, boolean wsSel)
// if wsSel is HIGH, RIGHT channel is selected.

{
uint8_t i;
        digitalWrite(WSPIN, wsSel);
for (i = 0; i < 15; i++)  {
digitalWrite(CLOCKPIN, HIGH);
                digitalWrite(DATAPIN, !!(val & (1 << (14 - i)))); //MSB FIRST, do 15 bits only
digitalWrite(CLOCKPIN, LOW);
}
        digitalWrite(WSPIN, !wsSel);
        digitalWrite(DATAPIN, bitRead(val, 0)  // get LSB of val
        digitalWrite(CLOCKPIN, HIGH);
        digitalWrite(CLOCKPIN, LOW);

}


Lefty
« Last Edit: August 17, 2011, 12:19:32 pm by retrolefty » Logged

Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tried both approches with no result. Maybe I wasn't meassuring the right way.
Wired the output to an LM358 OpAmp, the way it´s shown in the TDA datasheet, and this way I can get a range between 2,2 and 3,4V, inputing values from 58000 to 32000. So that´s a nice start. At leas I believe that the code works.
Now, is there a way to wire the OpAmp to get a range from 0 to 5V? I'm just starting to learn something about OpAmps, and I hae to confess that is not an easy road...
Should i start supplying the LM358 with 12V instead of the actual 5V?
Logged

Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Still didn't have the guts to test the Opamp with 12V.
But at least tweaking the feedback resistor I was able to get a consistent value between 1V and almost 0V, but only with 15-bits.
Something is wrong with the last bit. I'll have to try retroleftys idea again.
Logged

Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Got it finally!

Code:
void mishiftOut(int val, boolean wsSel)
// Si wsSel es HIGH va a ir al canal RIGHT

{
uint8_t i;
        digitalWrite(WSPIN, wsSel);
for (i = 0; i < 16; i++)  {
digitalWrite(CLOCKPIN, HIGH);
                digitalWrite(DATAPIN, !!(val & (1 << (15 - i)))); //MSB FIRST
                //delay(ESPERA);
               
digitalWrite(CLOCKPIN, LOW);
}
        digitalWrite(WSPIN, !wsSel);
}

I learned about negative binary handling and that was it.
Logged

0
Offline Offline
Tesla Member
***
Karma: 76
Posts: 6849
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In general I2S devices require a stable continuous multiple synchronous clocks (sometimes 3 clocks!) and can't be given individual samples like this - typical devices use the clock to drive internal decimation filters and suchlike - although the datasheet is a bit sparse it looks like this one is a pretty-much standard D/A interfaced as "pseudo I2S".  So don't immediately expect it to be as easy/possible on other I2S chips.
Logged

Pages: [1]   Go Up
Print
 
Jump to: