PIC32 SPI to MCP4922 Dual 12 bit Digital to Analog Converter

Reposted from Vernon’s Excellent Blog (original date 12/16/2011).

I recently completed an exercise in bringing up a MCP4922 DAC on the PIC32 SPI. I didn’t find any examples specifically using the PIC32 with MCP4922 or even any examples of the MCP4922 used in a 3.3v circuit. Therefore I thought a post might help the next fool that comes along and tries it…

1. The PIC32 Peripheral Library Help file is not much for detail, I found a need to dig into the SPIxCON register table in the PIC32 datasheet just to get definitions for the Input Parameter Mnemonics.

2. The CLK and SDO lines both need to be pulled up with at least 10K (I ended up using 4.7K). Further design refinements included pull ups on CS and LDAC with 10K to ensure sufficient loading on the PIC32 outputs, .01uf bypass caps on the outputs to filter the switching noise out and closer coupling of the MCP4922 P/S bypass caps to 4mm or less from the Vdd pin as recommended in the datasheet.

3. When halting just after a TX everything worked OK but it got unstable when I let it run free at an update rate of 10HZ or even slower. After much troubleshooting (including assuming that I had damaged the DAC chip) scope trace snapshots revealed the instability was due to a data/clock sync error. Specifically the clock burst was terminating early on random data write events. I found that it requires the CKE transition to be inverted (CKE = 1, [SPI_OPEN_CKE_REV]) to shift data out before the clock to run stable. Indeed, now it runs smooth and clean at a 1MHz SPI clock rate. YAY!

Here’s the SetDAC Function (Written in C32 v2.01)


And now it works!

Clock and Data Waveforms @ 1MHz

Clock and Data Waveforms @ 1MHz

Happy Coding…