Fast Function to Write Samples in the MCP4725

Motivation

The Plant

The scheme of connection of the Arduino UNO to the MCP4725 is shown in Fig. 1.

Fig.1 - Arduino UNO and MCP4725 connection scheme

Distinct Library Functions and The Write Access Time

Library or Function

ISR Code Example

(Only the write code snippet in the MCP4725!)

Time Duration Pulse

Adafruit_MCP4725 Library

ISR(TIMER1_OVF_vect)
{
  :
  sei();//enable TWI interrupt recognition inside Timer 1 ISR
  PINB |=0x01; //pulse for time measurement
  dac.setVoltage(sample, false); //send sample
  PINB |=0x01; //toggle PB0
  :
}

Fig. 2. The square pulse generated by the version 1 code during the sample writing into MCP4725
MCP4725 Library

ISR(TIMER1_OVF_vect)
{
  :
  sei();//enable TWI interrupt recognition inside Timer 1 ISR
  PINB |=0x01; //pulse for time measurement
  MCP.setValue(sample); //send sample
  PINB |=0x01; //toggle PB0
  :
}

Fig. 3. The square pulse generated by the version 2 code during the sample writing into MCP4725
Wire Library

ISR(TIMER1_OVF_vect)
{
  :
  sei();//enable TWI interrupt recognition inside Timer 1 ISR
  PINB |=0x01; //pulse for time measurement
  DA_Wire_Write(sample); //send sample
  PINB |=0x01; //toggle PB0
  :
}
void DA_Wire_Write(int sample)
{
  Wire.beginTransmission(MCP4725_address);
  Wire.write((sample & 0x0FFF) >> 8); //send MSB:command+upper nibble
  Wire.write(sample); //send LSB
  Wire.endTransmission();
}

Fig. 4. The square pulse generated by the version 3 code during the sample writing into MCP4725
Direct Register Access Model

ISR(TIMER1_OVF_vect)
{
  :
  PINB |=0x01; //pulse for time measurement
  error = DA_Fast_Write(sample); //send sample
  PINB |=0x01; //toggle PB0
  :
}
int DA_Fast_Write(int sample) //direct register Access
{
  sample &= 0x0FFF; //saturation in case the argument > 4095
  uint8_t LSB = (uint8_t)sample; //get LSB of data
  uint8_t MSB = (uint8_t)(sample>>8); //get MSB of data
  //D7-D4=0000 => Power Down Normal Mode and Fast Mode command

  TWCR |= 0xA0 ; //set TWI START Condition Bit
  while (!(TWCR & 0x80)); // wait until the start condition has been sent
  if ((TWSR & 0xF8) != 0x08) return 1; //mask the prescaler bits => status
  TWCR &= 0x5F ; //clear TWSTA

  TWDR = MCP4725_Address<<1 //SLA+W = Slave address+write bit command (0)
  TWCR |= 0x80; // start transmission of address
  while (!(TWCR & 0x80)); // wait until SLA+W has been transmitted
  if ((TWSR & 0xF8) != 0x18) return 2; //mask the prescaler bits => status

  TWDR = MSB; //load MSB data do TWDR
  TWCR |=0x80; // start transmission of MSB data
  while (!(TWCR & 0x80)); // wait until MSB has been transmitted
  if ((TWSR & 0xF8) != 0x28) return 3; //mask the prescaler bits => status

  TWDR = LSB; //load LSB data do TWDR
  TWCR |= 0x80; //start transmission of LSB data
  while (!(TWCR & 0x80)); // wait until LSB has been transmitted
  if ((TWSR & 0xF8) != 0x28) return 4; //mask the prescaler bits => status
  TWCR |=0x90; // set TWI STOP Condition Bit
  return 0; // return zero if writing process was succeeded
}

Fig. 5. The square pulse generated by the version 4 code during the sample writing into MCP4725

Notes

Waveform Generation - Sampling Rate of 2kHz

Fig.6. Sine waveform generated by the code in the MCP4725 output

Result using the Adrafruit_MCP4725 Library

Fig.7. Square pulse used to measure the time duration of the ISR - Version 1 Code

Result using the MCP4725 Library

Fig.8. Square pulse used to measure the time duration of the ISR - Version 2 Code

Result using the Wire Library

Fig.9. Square pulse used to measure the time duration of the ISR - Version 3 Code

Result using TWI Direct Register Access

Fig.10. Square pulse used to measure the time duration of the ISR - Version 4 Code

Waveform Generation - Sampling Rate of 4kHz

Sine Waveform of 50Hz

Fig.11. Sine waveform generated by the code in the MCP4725 output

Result using TWI Direct Register Access

Fig.12. Square pulse used to measure the time duration of the ISR - Version 4 Code

Complete Code Links

Conclusion