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