Code For MCP4821/MCP4822

Microchip‘s MCP4821/MCP4822 is a low budget 12-bit digital-to-analog converter. MCP4821 is the single channel version whereas MCP4822 has two channels that can be latched simultaneously. Both chips have internal band gap references and can be controlled via SPI.

Since MCP4821/MCP4822 has only a single write command register, it is extremely easy to use with MCUs that support SPI communications. The following code shows how to use this chip in Arduino:

#include <SPI.h>

const int PIN_CS = 10;
const int GAIN_1 = 0x1;
const int GAIN_2 = 0x0;

void setup()
{
  pinMode(PIN_CS, OUTPUT);
  SPI.begin();  
  SPI.setClockDivider(SPI_CLOCK_DIV2);
}

//assuming single channel, gain=2
void setOutput(unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | 0x10;
  
  PORTB &= 0xfb;
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  PORTB |= 0x4;
}

void setOutput(byte channel, byte gain, byte shutdown, unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | channel << 7 | gain << 5 | shutdown << 4;
  
  PORTB &= 0xfb;
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  PORTB |= 0x4;
}

void loop()
{
 //high-res triangular wave
 for (int i=0; i < 4096; i+=32)   
 {
  //setOutput(0, GAIN_2, 1, i);
  setOutput(i);
 }
}

There are two overloaded setOutput methods. Both methods can be used with either MCP4821 or MCP4822. The first method assumes the use of a single channel and a gain a 2. And the second method gives you more flexibility.

Note that the chip select pin (pin 10) is toggled using PORTB directly, this is to avoid the excessive overhead associated with the digitalWrite command, especially for high speed operations (e.g. 100kHz and above).

Be Sociable, Share!

6 Comments

  1. Diegopaez says:

    Thanks for the code i was totally lost before find your page. Thanks.

  2. […] wired it as described here, and it worked perfectly.  With this, I hooked up the X and Y lines to the two outputs of the DAC, […]

  3. Jonathan says:

    Hi there,

    I’m having trouble getting this to work. I have everything set up exactly as you do, and copy/pasted the code and the upload worked fine but I’m getting nothing out of the DAC. If you have any tips, I would much appreciate it. I could also send you pictures of my setup if you’d like.

    Thanks,
    Jonathan

Leave a Reply to Erste Schritte und Zielstellung | arduinomidimusic