This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem with output IOUTA and IOUTB of DAC8812

Other Parts Discussed in Thread: DAC8812, OPA2277, DAC8811

Número de pieza: DAC8812

Herramienta/software:

Hello,

I have a problem with the DAC output: it always stays at 0 volts. To provide some context, I designed and prototyped two bipolar voltage sources using the DAC8812 and two OPA2277 (based on the bipolar output circuit of the DAC8811).

LDAC#: GPIO04
CS#: GPIO05
RS#: GPIO16
CLK: GPIO18
SDI: GPIO23
MSB: connect to ground
VDD: 3,3 V of ESP32
VREFX: 2,5 V of power supply
+VS: 10 V of power supply
-VS: -10 V of power supply

Estas son las señales que veo en el osciloscopio:

First signals:
Yellow signal: CS#
Blue signal: CLK



Second signals:
Yellow signal: LDAC# (Has a duration greater than 20 ns)
Blue signal: CS#


Third signal:
Yellow signal: CLK
Blue signal: SDI (sending 0b111111111111111111)

The SPI communication initially seems good, but I can't understand why the output is different from 0 V.



/*Demo codes for testing DAC8812*/

#include <Arduino.h>
#include <SPI.h> 


//Full functionality demo code

// DAC8812 Pin Definitions
#define CS_PIN 5      // Chip Select (CS) pin
#define LDAC_PIN 4    // Load DAC (LDAC) pin
#define RS_PIN 16     // Reset (RS) pin

// SPI settings
SPISettings DAC8812_settings(1000000, MSBFIRST, SPI_MODE0);

void setup() {
  // Initialize Serial Monitor for debugging
  Serial.begin(115200);

  // Configure SPI
  SPI.begin();  // Initializes the SPI bus

  // Configure control pins
  pinMode(CS_PIN, OUTPUT);
  pinMode(LDAC_PIN, OUTPUT);
  pinMode(RS_PIN, OUTPUT);
  
  // Set control pins to default states
  digitalWrite(CS_PIN, HIGH);  // CS should be high when not communicating
  digitalWrite(LDAC_PIN, HIGH);  // LDAC high to not update outputs
  digitalWrite(RS_PIN, HIGH);  // RS high to avoid reset


  Serial.println("DAC channels updated!");
}

void loop() {
  // Your main loop code can go here
  //digitalWrite(RS_PIN, HIGH);  // RS high to avoid reset
  programDAC8812(1, 0xFFFF);  // Set channel A to midscale (32768, mid value of 2^16)
 // programDAC8812(2, 0x4000);
  
}

void programDAC8812(byte channel, uint16_t value) {
  uint32_t command = 0x00000;  // Nota: el tamaño debe ser al menos 18 bits, por eso se usa un uint32_t

  // Configure the command based on the selected channel
  if (channel == 1) {
    command = 0b11 << 16;  // Set DAC A (A1:A0 = 01)
  } else if (channel == 2) {
    command = 0b10 << 16;  // Set DAC B (A1:A0 = 10)
  }
  
  // Combine the channel bits with the value
  command |= (value & 0xFFFF);  // Set the 16-bit value

  // Print the full 18-bit command in binary
  Serial.print("Channel: ");
  Serial.print(channel);
  Serial.print(", Value: 0x");
  Serial.print(value, HEX);
  Serial.print(" -> Command: 0b");
  for (int i = 17; i >= 0; i--) {
    Serial.print((command >> i) & 1);
  }
  Serial.println();

  // Begin SPI communication
  SPI.beginTransaction(DAC8812_settings);
  digitalWrite(CS_PIN, HIGH);
  digitalWrite(CS_PIN, LOW);
  // Split the 18-bit command into SPI transfers
  uint16_t firstPart = (command >> 2) & 0xFFFF;  // Extract the upper 16 bits
  uint8_t secondPart = (command & 0x3) << 6;     // Extract the lower 2 bits and shift them

  // Print the parts being transferred
  Serial.print("SPI.transfer16: 0x");
  Serial.println(firstPart, HEX);
  Serial.print("SPI.transfer: 0x");
  Serial.println(secondPart, HEX);

  // Send the data via SPI
  //SPI.transfer16(firstPart);
  uint8_t byte1 = (command >> 10) & 0xFF; // Primeros 8 bits (de B17 a B10)
  uint8_t byte2 = (command >> 2) & 0xFF;  // Siguientes 8 bits (de B9 a B2)
  uint8_t byte3 = (command & 0x3) << 6;   // Últimos 2 bits (de B1 a B0) desplazados a la izquierda

  // Enviar cada parte
  SPI.transfer(byte1);
  SPI.transfer(byte2);
  SPI.transfer(byte3);
  

  digitalWrite(CS_PIN, HIGH);  // End SPI communication
  digitalWrite(LDAC_PIN, LOW);
   // Short delay for LDAC pulse
  digitalWrite(LDAC_PIN, HIGH);
  //digitalWrite(CS_PIN, LOW);
  SPI.endTransaction();
 
}


I hope you can help me.

Regards, Omar