External DAC – MCP4706

swTwo days ago, we tested Microchip MCP3021 ADC. Now we are going to test simple and very cheap Microchip DAC MCP4706. It would be useful especially with (DC)TR-52 modules. More inside…

 MCP4706 description (from official website)

The MCP4706/4716/4726 are single channel 8-bit, 10-bit, and 12-bit buffered voltage output Digital-to-Analog Converters (DAC) with nonvolatile memory and an I2C serial interface. This family will also be referred to as MCP47X6.

The VREF pin or the device VDD can be selected as the DAC’s reference voltage. When VDD is selected, VDD is connected internally to the DAC reference circuit. When the VREF pin is used, the user can select the output buffer’s gain to 1 or 2. When the gain is 2, the VREF pin voltage should be limited to a maximum of VDD/2.

The DAC register value and Configuration bits can be programmed to nonvolatile memory (EEPROM). The nonvolatile memory holds the DAC register and Configuration bit values when the device is powered off. A device Reset (such as a Power-on Reset) latches these stored values into the volatile memory. Power-Down modes enable system current reduction when the DAC output voltage is not required. The VOUT pin can be configured to present a low, medium, or high resistance load.

These devices have a two-wire I2C™ compatible serial interface for standard (100 kHz), fast (400 kHz), or High-Speed (3.4 MHz) mode.

These devices are available in small 6-pin SOT-23 and DFN 2×2 mm packages.

MCP4706

MCP4706

DAC usage with DPA

You can use my previous I2C project as a base for new one and change it for new device in this way:

// Handle peripheral command
// PNUM = 3 = DAC MCP4706
if ( _PNUM == PNUM_USER + 3 ) // ?
{
 
    if ( _PCMD == 0 )
    {
        // Check data length
        if ( _DpaDataLength != 1 )
            DpaApiReturnPeripheralError( ERROR_DATA_LEN );
        MCP4706_Write_Volatile_DAC(_DpaMessage.Response.PData[0]);
        goto DpaHandleReturnTRUE;
    } 
 
    if ( _PCMD == 2 )
    {
        // Check data length
        if ( _DpaDataLength != 2 )
            DpaApiReturnPeripheralError( ERROR_DATA_LEN );
        MCP4706_Write_Volatile_Memory(_DpaMessage.Response.PData[0],_DpaMessage.Response.PData[1]);
        goto DpaHandleReturnTRUE;
    }    
 
    if ( _PCMD == 3 )
    {
        // Check data length
        if ( _DpaDataLength != 2 )
            DpaApiReturnPeripheralError( ERROR_DATA_LEN );
        MCP4706_Write_All_Memory(_DpaMessage.Response.PData[0],_DpaMessage.Response.PData[1]);
        goto DpaHandleReturnTRUE;
    }
 
    // unknown command?
    DpaApiReturnPeripheralError( ERROR_PCMD ); 
}

There are also new functions:

void MCP4706_Write_Volatile_DAC(uns8 DACout)
{
    i2c_start();
    i2c_write(MCP4706_ADR_W);               
    i2c_write(0b00000000);                    
    i2c_write(DACout);                           
    i2c_stop();
    waitDelay(1);
}
 
void MCP4706_Write_Volatile_Memory(uns8 DACout, uns8 status)
{
    uns8 control_word = 0b01000000;
 
    // add status bits
    control_word |= status;
 
    i2c_start();
    i2c_write(MCP4706_ADR_W);               
    i2c_write(control_word);                    
    i2c_write(DACout);                           
    i2c_write(DACout); // do not care
    i2c_stop();
    waitDelay(1);    
}
 
void MCP4706_Write_All_Memory(uns8 DACout, uns8 status)
{
    uns8 control_word = 0b01100000;
 
    // add status bits
    control_word |= status;
 
    i2c_start();
    i2c_write(MCP4706_ADR_W);               
    i2c_write(control_word);                    
    i2c_write(DACout);                           
    i2c_write(DACout); // do not care
    i2c_stop();
    waitDelay(1);    
}

And of course new definitions:

#define MCP4706_ADR_W    0b11000000
#define MCP4706_ADC_R    0b11000001
 
#define MCP4706_GAIN_FLAG    0b00000001
#define MCP4706_PD0_FLAG     0b00000010
#define MCP4706_PD1_FLAG     0b00000100
#define MCP4706_VREF0_FLAG   0b00001001
#define MCP4706_VREF1_FLAG   0b00010010

Testing

What you need for testing:

  • some SOT23-6 (or DFN6) to DIP adapter.
  • DK-EVAL-04.
  • some wires.
  • pull-up resistor for SDA and SCL lines

Just connect VDD, VSS, SCL and SDA pins of the DAC to the appropriate pins of DK-EVAL:

  • DAC-VCC and DAC-VREF to the DK-EVAL-04 pin 8
  • DAC-VSS to the DK-EVAL-04 pin 7
  • DAC-SCL to the DK-EVAL-04 pin 3
  • DAC-SDA to the DK-EVAL-04 pin 2

In this case, VCC would be 3V. So VREF would be 3V too.

So if you want to set-up output voltage 1,5V without changing EEPROM set DPA to:

  • NADR: 0x0001 (or any other, if you have
  • PNUM: 0x23
  • PCMD: 0x00 (Write volatile DAC)
  • HWPID: 0x000F or 0xFFFF
  • DATA: 8bit DAC value (0x7F)

or:

  • NADR: 0x0001 (or any other, if you have
  • PNUM: 0x23
  • PCMD: 0x02 (Write volatile memory)
  • HWPID: 0x000F or 0xFFFF
  • DATA: 8bit DAC value (0x7F)
  • DATA: settings (gain, power-down modes, reference): 0

If you want to set-up output voltage 0,75V with preserve value to the EEPROM set DPA to:

  • NADR: 0x0001 (or any other, if you have
  • PNUM: 0x23
  • PCMD: 0x03 (Write all memory)
  • HWPID: 0x000F or 0xFFFF
  • DATA: 8bit DAC value (0x3F)
  • DATA: settings (gain, power-down modes, reference): 0

Enjoy.

Leave a Reply

Your email address will not be published. Required fields are marked *