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.

[参考译文] DAC80504:无法在 DAC 上获取输出

Guru**** 2362820 points
Other Parts Discussed in Thread: DAC80504
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1520792/dac80504-unable-to-get-output-on-dac

器件型号:DAC80504

工具/软件:

您好:

我将 DAC80504RTET 与 TMS320F28035MPNTEP 微控制器配合使用。 尝试读取器件 ID 时、我收到了0x00、但 MISO 线路上可以看到活动。 我还尝试写入 DAC 寄存器0x08、但在模拟输出中未观察到输出。 我在这里附上了我的程序。

函数调用 Uint16 DevID = SPI_readFromDAC (0x01);

读取器件 ID 的 SPI 信号捕获。

ch0:CS

Ch1:CLK

CH2:MISO (SDO)

CH3:MOSI (SDI)

写入操作:SPI_writeToDAC (0x08、0x5555)

void spi_configureSPIAModule(void)
{
    EALLOW;

    // GPIO configuration
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // SPISIMOA (MOSI)
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // SPISOMIA (MISO)
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // SPICLKA (CLK)
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // SPISTEA (CS)

    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;

    // SPI config
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;       // Hold in reset
    SpiaRegs.SPICCR.bit.SPICHAR = 7;          // 8-bit char
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;      // CPOL = 1 (clock idle high)

    SpiaRegs.SPICTL.all = 0;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0; //CPHA=0
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    SpiaRegs.SPICTL.bit.TALK = 1;

    SpiaRegs.SPIBRR = 0x007F;                 // ~468.75kHz
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;       // Release SPI
    SpiaRegs.SPIPRI.bit.FREE = 1;             // Run in emulation suspend

    // Enable FIFO
    SpiaRegs.SPIFFTX.bit.SPIRST = 1;          // FIFO reset
    SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;        // Enable FIFO enhancements
    SpiaRegs.SPIFFTX.bit.TXFFIL = 0;          // Interrupt level (unused)
    SpiaRegs.SPIFFTX.bit.TXFFIENA = 0;        // Disable TX FIFO interrupt
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;      // Clear interrupt flag
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;          // FIFO reset again

    SpiaRegs.SPIFFRX.bit.RXFFIL = 0;
    SpiaRegs.SPIFFRX.bit.RXFFIENA = 0;

    SpiaRegs.SPIFFCT.all = 0x00;              // FIFO delay

    EDIS;
}

void spi_writeToDAC(Uint8 regAddr, Uint16 value)
{
    Uint8 cmd = regAddr & 0x0F;
    Uint8 data_msb = (value >> 8) & 0xFF;
    Uint8 data_lsb = value & 0xFF;

    // Send 3 bytes via FIFO (no gap)
    SpiaRegs.SPITXBUF = ((Uint16)cmd) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_msb) << 8;
    SpiaRegs.SPITXBUF = ((Uint16)data_lsb) << 8;

    // Wait until transmit complete
    while (SpiaRegs.SPIFFTX.bit.TXFFST != 0);  // Wait until FIFO is empty
}

Uint16 spi_readFromDAC(Uint8 regAddr)
{
    Uint16 readMSB, readLSB;
    Uint16 dummy;
    Uint8 cmdByte = 0x80 | (regAddr & 0x0F);  // Bit 7 = 1 for read

    // Clear RX FIFO
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;

    SpiaRegs.SPITXBUF = ((Uint16)cmdByte) << 8; // Byte 1
    SpiaRegs.SPITXBUF = 0x0000;                 // Byte 2
    SpiaRegs.SPITXBUF = 0x0000;                 // Byte 3

    // Wait for all 3 bytes to arrive
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    dummy    = SpiaRegs.SPIRXBUF;
    readMSB  = SpiaRegs.SPIRXBUF >> 8;
    readLSB  = SpiaRegs.SPIRXBUF >> 8;


    return (readMSB << 8) | readLSB;
}

您能指导我如何操作吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:  

    DAC 输出。 如果计划使用内部基准、则应使用3.3V VDD 将 REF-DIV 设置为 VIO。 最大基准(包括内部基准)为 VDD /2。 您还可以将 Gain 设置为 VIO 以重新获得输出。 如果违反基准条件、内部基准缓冲器将关闭、这可能是您在写入命令正确时也看到输出没有变化的原因。  

    关于 SDO、SPI 读取需要两个访问周期。 您分享的屏幕截图似乎是第一个访问周期、在这个周期中、您将读取命令发送到寄存器1 (DevID)。 如果发送另一条命令(任何命令、可以是写入另一个寄存器、另一次读取或写入 NOP 寄存器)、SDO 上是否会返回任何数据。  

    此致、

    凯蒂恩·琼斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    为了读取器件 ID、我更新了函数 SPI_readFromDAC 以发送另一条命令。 您可以在下面的屏幕截图中看到第二个命令返回了一些数据。  我仍然得到 DevID 为零。 猜我在提取 SDO 时出错。 您能在下面查看我的代码吗

    ch0:CS

    Ch1:CLK

    CH2:MISO (SDO)

    CH3:MOSI (SDI)

    UINT16 SPI_readFromDAC (UINT8 regAddr)

    uint16 readMSB、readLSB;
    uint16 dummy;
    UINT8 cmdByte = 0x80 |(regAddr 和0x0F);//位7 = 1 (用于读取)

    //清除 RX FIFO
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;

    //发送读取命令(24位)
    SpiaRegs.SPITXBUF =((UINT16) cmdByte)<< 8;//字节1
    SpiaRegs.SPITXBUF = 0x0000;//字节2
    SpiaRegs.SPITXBUF = 0x0000;//字节3

    //等待所有3个字节到达
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    dummy = SpiaRegs.SPIRXBUF;//丢弃接收的字节

    //发送虚拟写入(24位)以接收数据
    SpiaRegs.SPITXBUF = 0x0000;//字节1
    SpiaRegs.SPITXBUF = 0x0000;//字节2
    SpiaRegs.SPITXBUF = 0x0000;//字节3

    //等待所有3个字节到达
    while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);

    //读取接收到的数据
    readMSB = SpiaRegs.SPIRXBUF;
    readLSB = SpiaRegs.SPIRXBUF;

    //组合 MSB 和 LSB
    return (readMSB << 8)| readLSB;
    }

    对于 DAC 输出问题、写入 GAIN 寄存器会解决我的问题吗? 我的 REF_DIV 和 GAIN 连接到 GND。 我将使用内部基准并更新增益寄存器来获得0至5V 的输出电压(2.5*2)。

    我尝试配置 GAIN 寄存器、但 DAC 输出仍为零伏

    SPI_writeToDAC (0x04、0x1);//设置增益=2
    SPI_writeToDAC (0x08、0xFFFF);

    void SPI_writeToDAC (Uint8 regAddr、Uint16值)

    Uint8 cmd = regAddr 和0x0F;
    UINT8 DATA_MSB =(值>> 8)& 0xFF;
    Uint8 data_lsb =值和0xFF;

    //通过 FIFO 发送3个字节(无间隙)
    SpiaRegs.SPITXBUF =((UINT16) cmd)<< 8;
    SpiaRegs.SPITXBUF =((UINT16) DATA_MSB)<< 8;
    SpiaRegs.SPITXBUF =((UINT16) DATA_lsb)<< 8;

    //等待传输完成
    while (SpiaRegs.SPIFFTX.bit.TXFFST!= 0);//等待 FIFO 为空
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:  

    您是否更改了代码? 最初、您的 SPI 写入是正确的、数据在 SCLK 的上升沿移出并在下降沿捕获。 您在下降沿移动数据似乎并非如此。 这可能是您编码无法识别 SDO 上时钟输出的数据的原因。 您可以更改状态寄存器中的 FSDO 位、以更改 DAC 将数据移出的边缘。 但您的控制器应该会在上升沿将数据在 SDI 上移出。  

    SDO 上的数据看起来是正确的器件 ID。  

    是的、您可以更新 GAIN 寄存器中的 REF-DIV 和 BUF-GAIN。 HW 引脚的状态只会选择默认状态。 即使您的数据似乎发生在错误的边沿上、读取命令似乎也能正常工作、但很奇怪、它会再次尝试更改边沿并更新增益寄存器和输出寄存器。  

    此致、

    凯蒂恩·琼斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Katlynne、

    现在我将 CLKPOLARITY= 0、CLK_PHASE = 0更改为"在 SPICLK 信号的上升沿输出数据。 输入数据在 SPICLK 信号的下降沿上锁存"。 下面是为器件 ID 读取捕获的信号。 现在、我的函数将返回器件 ID 1、这显然是错误的。

    写入 GAIN 寄存器(SPI_writeToDAC (0x04、0x1);)、但 DAC 上没有输出

    我在这里附上了我的代码。 是否可以直接连接以快速解决此问题?

    spi_configureSPIAModule();
    regValue = spi_readFromDAC(0x01);
    spi_writeToDAC(0x08, 0xFFFF);
    
    void spi_configureSPIAModule(void)
    {
        EALLOW;
    
        // GPIO configuration
        GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // SPISIMOA (MOSI)
        GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // SPISOMIA (MISO)
        GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // SPICLKA (CLK)
        GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // SPISTEA (CS)
    
        GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;
        GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;
    
        // SPI config
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;       // Hold in reset
        SpiaRegs.SPICCR.bit.SPICHAR = 7;          // 8-bit char
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;      // Data is output on rising edge and input on falling edge
    
        SpiaRegs.SPICTL.all = 0;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0; // Data is output on the rising edge of the SPICLK signal. Input data is latched on the falling edge of the SPICLK signal
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
        SpiaRegs.SPICTL.bit.TALK = 1;
    
        SpiaRegs.SPIBRR = 0x007F;                 // ~468.75kHz
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;       // Release SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;             // Run in emulation suspend
    
        // Enable FIFO
        SpiaRegs.SPIFFTX.bit.SPIRST = 1;          // FIFO reset
        SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;        // Enable FIFO enhancements
        SpiaRegs.SPIFFTX.bit.TXFFIL = 0;          // Interrupt level (unused)
        SpiaRegs.SPIFFTX.bit.TXFFIENA = 0;        // Disable TX FIFO interrupt
        SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;      // Clear interrupt flag
        SpiaRegs.SPIFFTX.bit.TXFIFO = 1;          // FIFO reset again
    
        SpiaRegs.SPIFFRX.bit.RXFFIL = 0;
        SpiaRegs.SPIFFRX.bit.RXFFIENA = 0;
    
        SpiaRegs.SPIFFCT.all = 0x00;              // FIFO delay
    
        EDIS;
    
        spi_writeToDAC(0x04, 0x1);//GAIN =2;
    }
    
    void spi_writeToDAC(Uint8 regAddr, Uint16 value)
    {
        Uint8 cmd = regAddr & 0x0F;
        Uint8 data_msb = (value >> 8) & 0xFF;
        Uint8 data_lsb = value & 0xFF;
    
        // Send 3 bytes via FIFO (no gap)
        SpiaRegs.SPITXBUF = ((Uint16)cmd) << 8;
        SpiaRegs.SPITXBUF = ((Uint16)data_msb) << 8;
        SpiaRegs.SPITXBUF = ((Uint16)data_lsb) << 8;
    
        // Wait until transmit complete
        while (SpiaRegs.SPIFFTX.bit.TXFFST != 0);  // Wait until FIFO is empty
    }
    
    Uint16 spi_readFromDAC(Uint8 regAddr)
    {
        Uint16 readMSB, readLSB;
        Uint16 dummy;
        Uint8 cmdByte = 0x80 | (regAddr & 0x0F);  // Bit 7 = 1 for read
    
        // Clear RX FIFO
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
    
        // Send read command (24 bits)
        SpiaRegs.SPITXBUF = ((Uint16)cmdByte) << 8; // Byte 1
        SpiaRegs.SPITXBUF = 0x0000;                 // Byte 2
        SpiaRegs.SPITXBUF = 0x0000;                 // Byte 3
    
        // Wait for all 3 bytes to arrive
        while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);
    
        dummy = SpiaRegs.SPIRXBUF; // Discard received byte
    
        // Send dummy write (24 bits) to receive data
        SpiaRegs.SPITXBUF = 0x0000; // Byte 1
        SpiaRegs.SPITXBUF = 0x0000; // Byte 2
        SpiaRegs.SPITXBUF = 0x0000; // Byte 3
    
        // Wait for all 3 bytes to arrive
        while (SpiaRegs.SPIFFRX.bit.RXFFST < 3);
    
        // Read the received data
        readMSB = SpiaRegs.SPIRXBUF;
        readLSB = SpiaRegs.SPIRXBUF;
    
        // Combine MSB and LSB
        return (readMSB << 8) | readLSB;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我 略微调整了 SPI_readFromDAC()函数、并开始获取与我在 SDO 线路上看到的类似的数据。  

    当我读取 Rx 缓冲器时、收到了0x81 0x04 0x17。  因此、器件 ID = 0x0417。

    下面是将0xFFFF 写入 DAC 寄存器0x08 (SPI_writeToDAC (0x08、0xFFFF);)的屏幕截图

    我更改了增益寄存器1中的 REF_DIV 位、并开始获取输出上的电压。 电压范围为0V 至2.5V。

    当 REF_DIV 位为0时、为什么没有获得输出?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:

    0x0417是 DAC80504的正确器件 ID。

    我在该链的前面部分谈到了 REF-DIV 设置。 REF-DIV 引脚接地、默认为1分频。 这对您的 VDD 电源和内部基准不起作用。 需要将基准除以2、然后将增益设置为2以获得满量程0-2.5V 输出。  

    如果您计划使用内部基准、应该使用3.3V VDD 将 REF-DIV 设置为 VIO。 最大基准(包括内部基准)为 VDD /2。 您还可以将 Gain 设置为 VIO 以重新获得输出。 如果违反基准条件、内部基准缓冲器将关闭、这可能是您在写入命令正确时也看到输出没有变化的原因。  [/报价]

    此致、

    凯蒂恩·琼斯