I'm trying to use a specific audio amplifier, TPA3111D1, to power a 10 watt speaker from a microcontroller. I would like to generate sound from a microcontroller that doesn't have a built in DAC, so I am looking for a good DAC that would work with this amplifier. The amplifier allows both differential or single audio source inputs and I'd like the DAC to work with 0 to 5V TTL inputs from 16 pins of the microcontroller.

I think 16 bit should be the appropriate size of the DAC but there are so many to choose from. If anyone has a good tutorial on using a DAC for audio generation from a microcontroller I'd love to see it. Can anyone suggest a DAC or at least narrow my search down a little bit? Thanks!

  • \$\begingroup\$ It's an ATmega2560 so I was thinking of just doing parallel, but I'm open to other ideas since I haven't written the code yet. Would another output format be better? \$\endgroup\$ – wcmartin Jul 18 '11 at 7:04
  • \$\begingroup\$ Wow, thanks for the great responses. They were all very useful. \$\endgroup\$ – wcmartin Jul 22 '11 at 15:13

DACs have different requirements depending on the application. You'll find high precision solutions using expensive components to get good absolute precision, but in audio you don't need that. Linearity is the most important parameter.

Since you'll be using an ATmega2560 which comes in a 100-pin package you can probably spare 16 I/Os, and then I would choose for parallel I/O. You'll have less timing problems than when working with serial I/O like I2S.

Will seems to favor I2S and he has a point on condition that you want to connect to other, (semi-)professional audio equipment. As I understand it your digital audio path is very local, restricted to the connection between your AVR and the DAC. And then I would stick with the parallel. For 44.1kHz sample rate choose a crystal that allows you to get an interrupt every 22.676\$\mu\$s. Use the interrupt to automatically latch the last sample into the DAC, and then you have lots of time to prepare your next sample. That's the only timing you're dependent on. With I2S on the other hand you'll have more things to do. You may use SPI to shift the data out, but in the middle of a word you'll have to toggle the word clock. Things you don't have to worry about with parallel I/O.

The simplest ADC is an R-2R resistor ladder. The linearity depends on the resistors' matching, and there lies the problem for a discrete solution. You would need rather expensive precision resistors. The integrated approach is much better. The AD5547 also uses an R-2R ladder network (see fig. 17 on page 12), so why is this better than discretes? Integrated resistors (and capacitors) may have some tolerance on their nominal value, but their mutual match is the best you can get. So the 80k\$\Omega\$ resistors may be 80.5k\$\Omega\$, but you're sure they're all that value, and that's more important than the actual value itself.
The AD5547 accepts a 5V power supply and is 16-bit parallel in.

enter image description here

The application schematic is from the datasheet, so look there if this isn't very readable.

The DAC is registered, which means you can use the latch to update several DACs simultaneously, but you can make it asynchronous and transparent too by making/WR low and LDAC high (see page 13). Then the output will be continuously updated. But this is only possible if all inputs are updated simultaneously! With an 8-bit microcontroller you will probably write to 2 I/O ports, and then you'll need the latch!
Like most DACs it's current output, so you need to convert it to voltage. In this application with the AD8628 they use a RRIO (Rail-to-Rail I/O) opamp whose specs match the required resolution, but you can use another opamp if you like.
The ADR03 is a precision voltage reference, low drift and such, which for an audio application is overkill. Just make sure that your voltage reference is ripple and noise free!

David rightly comments that this is somewhat older technology, but I thought it is OK since you're using a microcontroller (in lieu of a DSP) and a less-than-perfect class-D amplifier anyway. I picked this for my answer also because it is easy to understand.
David also mentions sigma-delta DACs, which have indeed better performance, but their working principle is a bit more complex, and they're (almost?) without exception serially controlled, for which the AVR doesn't have the hardware.

  • 1
    \$\begingroup\$ Well, if you don't have an I2C interface on the uC then this might be OK if a bit painful. You'd need a DC blocking cap on the output and a resistor to bias the output to 0v. Aside from that, the audio quality will be crappy due to lots of issues (writes to the DAC will have lots of jitter, the DAC won't be very liner, etc.). For uC's without I2C, it would be better to use a small CPLD to give you a I2C interface and then use any one of many I2C audio DAC's. \$\endgroup\$ – user3624 Jul 18 '11 at 14:00
  • \$\begingroup\$ @David - Can you explain the jitter? If you latch the DAC on a timer compare output it will be perfectly in sync, IMO. \$\endgroup\$ – stevenvh Jul 18 '11 at 14:06
  • \$\begingroup\$ @David - also, what do you mean that the DAC will not be linear? \$\endgroup\$ – stevenvh Jul 18 '11 at 14:09
  • 1
    \$\begingroup\$ R-2R based DAC's have linearity issues, which causes distortion of the audio. As you said, this is a resistor matching issue-- but integrated solutions are still problematic. This linearity issue, plus clock jitter, was largely responsible for Digital Audio getting a bad reputation in the early 80's for sounding crappy. Delta-Sigma DAC's improved things greatly because they are inherently linear and have improved jitter "rejection". The solution you propose will sound similar to 80's digital audio-- which may be totally fine! But it is not on par with what the TPA3111 can do. \$\endgroup\$ – user3624 Jul 18 '11 at 14:27
  • 1
    \$\begingroup\$ You'd probably get "12 or 14 bit equivalent performance" from a 16 bit R-2R DAC. A 24-bit delta-sigma DAC would give you 16 to 20 bit performance, stereo, for US$2 + interface logic (if any). I would hope that the DAC you mention would be completely monotonic at least. \$\endgroup\$ – user3624 Jul 18 '11 at 14:52

I'm guessing this is a hobby project, and if so, then the other answer is probably fine. But if this is a real product, you should be looking for a micro with an I2S interface, and then use a proper audio DAC (might be called a 'codec') designed to run with that.

Pretty much all audio D-to-A is done with I2S parts - here's a whole page of them, selected with no particular care or endorsement by me, but it gives you an idea of typical levels of integration.

And here's an app note (from Atmel, coincidentally) about adding I2S peripherals to a non-I2S micro. That someone might thinking it worth that much effort to get to I2S gives you some idea about the significance of the interface in this niche.

I2S is extremely simple - it's not like getting to grips with USB or PCI, but for any realistic performance, you'll want a micro with hardware support built-in.

  • \$\begingroup\$ An Atmel appnote for I2S may look encouraging at first sight, but this is an ARM9 controller, and not an AVR! That's a completely different class, performance-wise. \$\endgroup\$ – stevenvh Jul 18 '11 at 8:19
  • 1
    \$\begingroup\$ @Matt - Isn't AC97 mainly used in PC, and mobile phone and stuff, and I2S more for pure audio equipment? I've never seen AC97 on a stereo set (and even I2S only on high end). \$\endgroup\$ – stevenvh Jul 18 '11 at 9:07
  • 1
    \$\begingroup\$ Sorry, by 'pretty much all', I meant hi-fi / consumer audio, not PCs. I was thinking about the insides of MP3 players, CD players, etc, having assumed that was the type of gadget the OP was making. \$\endgroup\$ – user1844 Jul 18 '11 at 9:25
  • 1
    \$\begingroup\$ Huh? TOSLINK is an optical link between boxes. I2S is (overwhelmingly) a link between chips. (But of course, like I2C, people do sometimes bring it outside, though that's a corner-case) \$\endgroup\$ – user1844 Jul 18 '11 at 11:00
  • 2
    \$\begingroup\$ @Matt AC97 is almost never used outside of the PC world. In 2004, AC97 was replaced by Intel's "HD Audio" interface, which has it's own set of issues. I have yet to see a HDAudio/AC97 codec with decent audio performance-- at best you're talking iPod level performance. There is another important thing to note: I2S-ish type interfaces are MUCH EASIER to interface to than AC97/HD Audio. TOSLINK is essentially S/PDIF over fiber, and is absolutely never used within a box. People don't even use S/PDIF (over copper) for chip to chip interconnects if they don't have to. \$\endgroup\$ – user3624 Jul 18 '11 at 13:42

Ok. At the urging of @stevenvh, here's how I'd do it...

The uC that you chose does not have an I2C-Like interface that would normally connect, more or less, directly up to an audio DAC. The ideal solution would be to choose another uC that does support I2C directly, but of course we don't always have that luxury. We could use some of the I/O ports on the uC, but that would take a lot of pins/signals. One thing that could be used is the SPI Master peripheral. So, here's what I propose.

Use a cheap CPLD to interface the SPI port on the uC to the I2C port on a typical audio converter.

Start with an oscillator of appropriate frequency, maybe 24.576 MHz for a 48KHz sample rate. In the CPLD you have a counter that runs off of this clock. The output of the counter is used to generate all of your audio clocks: MCLK, BITCLK, and LRCLK. It is also used to generate one or two control signals.

Another section of the CPLD is an RX shift register. The RX SR can be 16, 24, or even 64 bits long. It gets it's data from the SPI interface on the uC, and transfers it's data to the TX Shift Register at regular intervals. The TX shift register is the same size as the RX shift register, and clocks it's data out to the DAC at the same rate as BITCLK.

The ideal size of the SR's is really a balancing act. You're balancing the size of the CPLD vs. the software overhead vs. the number of bits in your audio. For the moment, lets assume 1 channel of 16 bit audio.

For this example, the SR's are 16 bits long. At the beginning of the sample, the CPLD generates an IRQ to the CPU. The CPU responds by sending the next 16 bit sample over the SPI interface to the RX SR. At the end of the sample, or beginning of the next, the RX SR data is loaded into the TX SR, where it is shifted out to the DAC. So at any given moment there could be two transfers going on at the same time: SPI to RX SR, and TX SR to DAC.

The TX SR is set up so that as data is shifted out, zeros are shifted in. You actually send 64 bits of data to the DAC, but it's OK if the "unused" bits are all zero.

If you want to send 24 bit audio instead of 16 bits then you just lengthen your shift registers to 24 bits. But if you want to go to stereo audio things get a little trickier. I know the OP only cares about mono audio, but I'll include it here for completeness.

You have a choice: You can leave the SR's at 16 or 24 bits, but run the IRQ's twice as fast (and load the TX SR twice as fast). Or you can lengthen the SR's to almost 64 bits. The first option keeps the CPLD small, but doubles the number of IRQ's it has to perform. The second option is reversed.

For a simple single channel of 16 bit audio, you'll need a CPLD with about 48 Flip-Flops: 9 bit counter, two 16-bit SR's, three output clocks, an IRQ, and a couple of extras. This would fit into a Xilinx Coolrunner-II 64-macrocell part which runs around US$1.50 in medium volumes. Altera has some Max V parts that are more Flip-Flop rich that could be cheaper.

As for a proper DAC, there are dozens to choose from. Cirrus Logic, Texas Instruments (Burr Brown) and AKM are the top three that I'd pick from. All of them have an inexpensive stereo DAC that will work fine. The simpler the better. I like the Cirrus Logic CS4334/35/38/39. Digikey has the part for US$3. But the other guys have very similar parts for a similar cost.

  • \$\begingroup\$ "I2C-Like interface that would normally connect, more or less, directly up to an audio DAC" Do you mean I2S? "Despite the name, it is unrelated to the bidirectional I²C bus." \$\endgroup\$ – endolith Dec 16 '15 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.