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.

[参考译文] DAC161S997:SPI 通信问题,器件无反馈

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/895389/dac161s997-spi-communication-issue-device-no-feedback

器件型号:DAC161S997
主题中讨论的其他器件:LM2841

尊敬的先生:

      我计划使用 DAC161S997将 SPI 数据传输到4-20mA 输出,我几乎使用典型的应用圈。 只需更改 LDO 即可切换 LM2841的电源。 现在我可以使用 UART 与 MCU 进行通信,但当我向 DAC 发送命令时,无法从 DAC 获得正确的答案。 我使用模拟 SPI 功能。 下面的代码,请。   请帮我回顾一下,如果您能给我一些建议,我将不胜感激。

      当我运行测试()时,只能从 DAC 获得“FF”、“FF”、“FF”。  

/*从 SPI 读取1位。 返回数据*/
U8 SpiReadByte (空)

U8 I、rByte=0;
SCLK=0;
for (i=0;i<8;i++)

SCLK=1;
rByte<<=1;
rByte|=MISO;
SCLK=0;



返回 rByte;

/*SPI 发送1位*/
void SpiSendByte (u8 dt)


U8 I;
for (i=0;i<8;i++)

SCLK=0;
if (dt <<i)&0x80)
MOSI=1;
其他

MOSI=0;

SCLK=1;

SCLK=0;

空测试()

U8 outData[3]、I;
CS_DAC = 0;
outData[0]= 0x04;
outData[1]=数据>> 8;
outData[2]=数据& 0xff;

对于(i=0;i<3;i++)

SpiSendByte (outData[i]);
delay_ms (20);

delay_ms (2);
SpiSendByte (0x89);
W[0]= SpiReadByte ();
SpiSendByte (0xff);
w[1]=SpiReadByte();
SpiSendByte (0xff);
w[2]=SpiReadByte();
CS_DAC = 1

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

    您好 Jeffrey、

    我首先建议您通过检查电源电压 VD 和 VA、开关 LM2841的输出电压和上电后的初始回路电流来确认回路的正确启动。 如果循环正确启动,则继续测试函数 test()。 我对您的代码有几个意见。

    1、您的代码似乎是为了将数据:0x08FF 写入 addr:0x04 (数据寄存器)、但您从 addr:0x09读回? 是这样吗? addr 0x09的内容取决于芯片的状态、如果有环路和 SPI 错误、输出可能为0xFFFF

    从寄存器读取数据需要两条命令。 第一个命令是启动读取操作、第二个 命令应该是一个 NOOP 命令来时钟输出寄存器的内容。 在 test()方法中似乎缺少 NOOP 命令

    3.您能否将 SPI 信号连接到示波器并分享波形的屏幕截图?

    此致、

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

    尊敬的 Reza :

                非常感谢您这么快地回复我。 仍需要您的专业支持。

               到目前为止,我相信 DAC 已通电,因为我们可以在示波器。上获得 SCLK 信号和 DAC 的 MISO 信号,但 反馈值仍然 不正确。

               我们向 DAC 发送地址+数据,但获得相同的反馈。

               例如 : 发送0x89 0x05 0xff     DAC 反馈:0x89 0x05 0xff     (0x09是 DAC 寄存器状态的地址, 一般情况下,反馈应为0xeX,X 可能 是其他 数字 )

                                       发送0x89 0xff 0xff     DAC 反馈:0x89 0xff 0xff      

                您是否愿意为我提供一些关于如何编辑读()和写()的建议 ?  或  读取 ()和写入()的格式或模板是什么 ?  到目前为止,我使用 GPIO 模拟 SPI。

               BTW,我们发现 ERRB 被拉低,在原理图上,它连接到 VSS。  已将我的原理图附在下面。

     谢谢!       

    1、您的代码似乎是为了将数据写入:0x08FF 到 addr:0x04 (数据寄存器)、但您从 addr:0x89读回? 是这样吗? addr 0x89的内容取决于芯片的状态、如果存在环路和 SPI 错误、输出可能为0xFFFF

    Jeffrey 回答: 因为我们要实现两个步骤: 1 :将日期写入0x04;2:从0x09读取状态日期 。

    从寄存器读取数据需要两条命令。 第一个命令是启动读取操作、第二个 命令应该是一个 NOOP 命令来时钟输出寄存器的内容。 在 test()方法中似乎缺少 NOOP 命令

    Jeffrey 回答:您是否会帮我写 Read()函数,给我们一些清晰的建议? 我们反复尝试,但仍然无法获得正确 的反馈。  

    3.您能否将 SPI 信号连接到示波器并分享波形的屏幕截图?

    Jeffrey 回答:很抱歉,由于某种原因,我们现在无法获得波形屏幕截图。 我们只需用  不同的图片捕获它们。

     

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

    尊敬的 Reza :

                 请 根据 图片检查振荡器的快照,在将命令+数据8900ff (红色框)发送到 DAC 后 ,我们从它获得反馈,但我们发现2组数据(绿色框和红色框),我不知道哪一组数据正确 。  

                如果仔细检查红色框中的波形,它们是相同的,这意味着我们回读我们发送的内容。 只需尝试8900ff,没有具体目标。

               到目前为止,我们仅假定如下所示。(我们使用了 SPI 模型0)

    MCU 向 DAC 发送数据

    2. DAC 响应,但值不正确。

           所以,我的问题是。

            1.从 DAC 发送或读取数据时,应遵循什么格式?

           2.哪些数据显示 DAC 工作正常?

           3.接下来我该怎么办?

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

    您好 Jeffrey、

     SpiReadByte()和  SpiSendByte (dT)函数看起来很好。  默认情况下、SPI 移位寄存器始终在 SDO 线路上输出之前的 SPI 写入帧。 这就是为什么在发送  0x89 0xff 0xff 0xff 时、从 SDO 行回读0x89 0xff 0xff 0xff。  

    要正确回读寄存器、您必须在读取命令之后跟随 NOOP 命令。 下面是一个示例。

    发送0x89 0xFF 0xFF (读取命令地址0x09)

    发送0x00 0x00 0x00 (NOOP 命令)。 在此帧期间读回 SDO 位。  

    我将修改测试代码、如下所示。

    秘书长的报告

    空测试()

    U8 outData[3]、I;
    CS_DAC = 0;
    outData[0]= 0x04;
    outData[1]=数据>> 8;
    outData[2]=数据& 0xff;

    对于(i=0;i<3;i++) //发送0x0408FF  

    SpiSendByte (outData[i]);
    delay_ms (20);

    CS_DAC = 1;

    delay_ms (2);

    //为 addr 0x09发送读取命令

    CS_DAC = 0;
    SpiSendByte (0x89);
    SpiSendByte (0xff);
    SpiSendByte (0xff);
    CS_DAC = 1

    delay_ms (2);

    //发送 NOOP 命令。 在此帧期间读取 SDO

    CS_DAC = 0;

    SpiSendByte (0x02);
    W[0]= SpiReadByte ();
    SpiSendByte (0x00);
    w[1]=SpiReadByte();
    SpiSendByte (0x00);
    w[2]=SpiReadByte();
    CS_DAC = 1

    还有两点需要注意。

    1、SDO 数据在 SCLK 的下降沿随时钟输出。 您可能必须在 read()函数中更改 SCLK 的极性以正确时钟输出数据。 不过、在示波器上观察这种情况会更容易。  

    2.在 CS 的下降沿和上升沿之间、应存在24个 SCLK 的整数倍。 如果有多个非整数 SCLK、则会丢弃 SPI 帧并报告错误。

    此致、

    此致、





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

    尊敬的 Reza:

                 感谢您的信息。

                 我按照您的指示更新我的函数,似乎输出仍然不符合我们原来的期望。 新功能如下所示。

               例如:

                          发送(0x89) ;发送(0xFF)  ;发送(0xFF) ;

                           SEND (0x02);READ (); SEND (0x00);READ (); SEND (0x00); 读();

                          我们得到的结果是:000200

                      如果发送其他号码

                          SEND (0x08);READ (); SEND (0x06);READ (); SEND (0x04); read();// 08,06,04无意义,只需简单的检查结果,但似乎仍然有效,具有值返回。

                          我们得到的结果是000806、似乎我们读取了与我们发送的数据相同的数据、并在高位加00。

               此外,我们将数据发送到 DACCODE 寄存器  ,但循环电流输出值不正确,甚至超过24mA。  因为我无法读取寄存器状态(无法正确返回) ,所以我不知道实际原因。 (为了避免静态功耗的影响,我已经从电路中删除了 DCDC LM2841,直接为 DAC 和 MCU 提供3.3VDC,24VDC 与 Triode as LOW+接触,几乎像4线 回路电流  )

               例如,我们将(2aaa)发送到0x04,理想环路电流应为0mA,但测量电流为5.2mA。 其他测试结果如下所示,我无法找到它们之间的规律性。

    输入值

    理想电流

    环路电流输出

    2AAA (0%)

    10922

    4.

    5.2.

    5554 (25%)

    21844

    8.

    10.27.

    7FFF (50%)

    32767

    12.

    15.37.

    AAAA (75%)

    43690

    16.

    20.48.

    D555 (100%)

    54613

    20.

    25.54.

              

     

     

     

                            

    我的怀疑

            我的 send()和 read()单词格式在 test() 中仍然有一些问题,可能还有其他问题, 因此我无法获得正确的反馈 。  同时 ,我们可以在 振荡器上获得 SCLK、MISO、MOSI 信号,尽管我不知道反馈值是否正确。

    需要支持

    1. 您是否能帮助您检查 test()、什么;s 错误? send()和 read()的正确模板是什么? 我在数据表中找不到这些信息。

    2. 有哪些反馈显示 DAC 运行良好? 与读取(0x89)类似,获取结果:E0或其他方法。

    BTW:为什么发送0x02? 我们可以使用其他号码吗? 例如、00、03、04等

           

    空测试(U16数据)

    U8 outData[3]、I;
    CS_DAC = 0;
    outData[0]= 0x04;
    outData[1]= 0x2a;
    outData[2]= 0xAA;
    对于(i=0;i<3;i++)//发送0x042aaa

    SpiSendByte (outData[i]);
    delay_us (10);

    CS_DAC = 1;
    delay_us (30); //为了显示 振荡器上的所有波形 ,我们更改了延迟时间
    //为 addr 0x09发送读取命令
    CS_DAC = 0;
    SpiSendByte (0x89);
    SpiSendByte (0xff);
    SpiSendByte (0xff);
    CS_DAC = 1;
    delay_us (10); //为了显示 振荡器上的所有波形 ,我们更改了延迟时间  
    //发送 NOOP 命令。 在此帧期间读取 SDO
    CS_DAC = 0;
    SpiSendByte (0x02);
    W[0]= SpiReadByte ();
    SpiSendByte (0x00);
    w[1]=SpiReadByte();
    SpiSendByte (0x00);
    w[2]=SpiReadByte();
    CS_DAC = 1;


    /*从 SPI 读取位,返回数据*/
    U8 SpiReadByte (void){u8 i、rByte=0;SCLK=0;for (i=0;i<8;i++){SCLK=1;delay_us (5);;rByte<=1;rByte|=MISO;SCLK=0;delay_us (5);}return rByte;}
    /*SPI 发送1位*/
    void SpiSendByte (u8 dt){u8 i;for (i=0;i<8;i++){SCLK=0;delay_us (5);if (<i)&0x80)MOSI=1;else{MOSI=0;}SCLK=1;Delay_us(5);}SCLK=0;}

    周末愉快!

    非常感谢!

    最恰当的考虑

    Jeffrey

     //为了显示 振荡器上的所有波形 ,我们更改延迟时间

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

    您好 Jeffrey、

    我很高兴您在这方面取得了一些进展、通过其他信息、我们可以解决这一问题。 我怀疑您遇到的问题是测试功能。 请记住、始终使用24个 SCLK 的整数倍来与 DAC 进行通信至关重要。 如果不这样做、移位寄存器的内容可能会失真。 Read()方法的当前使用方式将导致 SPI 移位寄存器的内容发生移位。 我建议定义新函数、以确保所有 DAC SPI 读取和写入操作只有24个 SCLK。 请参见下面的

    我再看一下 SpiSendByte (dt)和 SpiReadByte ()的函数,我们可以对其进行细微修改以实现 该目的。 首先、我将把这两个函数合并为一个函数。

    ********* 通用 SPI 字节函数、在 SCLK 上升沿写入、在下降沿读取 SDO。*********

    /*通用 WR RD SPI 字节*/
    U8 SpiSendByte (u8 dt)

    {  
    U8 I、rByte=0;
    for (i=0;i<8;i++)

    SCLK=0;
    if (dt <<i)&0x80)
    MOSI=1;
    其他

    MOSI=0;

    SCLK=1;

    SCLK=0;

    rByte<<=1;
    rByte |=MISO;

    返回 rByte;

    (第5颗星 定义24位 WR/RD 功能

    u32 dacWR (u8 addr、u8 hibyte、u8 loByte)

    U8 A、b、c = 0
    u32数据= 0;
    CS_DAC = 0;

    a = SpiSendByte (addr);
    delay_ms (20);

    b = SpiSendByte (hibyte);
    delay_ms (20);

    C = SpiSendByte (loByte);
    delay_ms (20);

    CS_DAC=1
    数据= a<<16 + b<8 + c;
    返回数据;

    (第5颗星 测试功能。  根据需要修改延迟

    空测试()

    U32虚拟、SDO = 0;

    CS_DAC = 0;

    虚拟= dacWR (0x04、0x08、0xFF); //写入数据寄存器(0x0408FF)                                                                                                                 delay_ms (20);
    虚拟= dacWR (0x89、0x00、0x00); //发送地址0x09的 RD 命令                                                                                delay_ms (20);
    SDO = dacWR (0x02、0x00、0x00); //发送 NOOP 命令以时钟输出 SDO 位

    CS_DAC = 1;

    确保 DAC 正常运行的一种好方法是 读回状态寄存器(addr 0x09)。 正如您提到的、回读数据应为 E0。 请注意、您不必连续(默认每100ms 一次)向芯片发送有效 SPI 数据以避免 SPI 超时错误、也不必屏蔽 ERR 配置寄存器(addr 0x05)中的 ERROR 位。

    此外、对于读回数据、您可以使用任何 SPI 地址、但我建议使用 addr 0x02、因为它是 NOOP 命令、不执行任何特定命令。

    您还可以针对每个24位 SPI 写入操作回读 SDO 位。 默认情况下、SDO 位将始终与之前的24位 SPI 帧相同。 您可以使用此选项来验证芯片的 SPI 写入和读取操作是否正确。

    请告诉我这是否能解决问题。 谢谢。

    此致、

     

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

    您好,Reza:

           感谢您的建议,完成后,我将尝试并回复您的结果。   

           我发现了另一个有关 NPN 晶体管的问题、当我在环路+上添加24VDC 时、它的温度非常高。 它会影响 DAC 运行和输出吗? 如何减少由此产生的热量?  

           我在 NPN 晶体管之前的原理图中发现了额外的100 Ω 电阻器和齐纳二极管(在数据表第26页)。 它们的功能是什么? 我可以将它们添加到我的电路中吗?

           祝你度过美好的一天!  

    谢谢

    Jeffrey  

    最恰当的考虑  

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

    您好 Jeffrey、

    齐纳二极管用于确保当回路电源电压较低时、用于 LDO 的输入电压仍足以为提供的示例生成3.3V VCC。 在本示例中、使用了3.9V 齐纳二极管来保证 LDO 在所有环路电源和电流条件下均能正常工作。 也可以添加与齐纳二极管串联的100欧姆电阻器。

    您的示例中 NPN 晶体管正在升温、因为大部分输出功率在 BJT 上耗散(Appox 24V *回路电流)。 使用齐纳二极管和100 Ω 电阻器的串联组合将有助于降低 BJT 上的热耗散。 请确保 BJT 额定值正确、且 β= 40最小值和 Vceo = 40V 最小值。

    此致、

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

    尊敬的 Reza:

           我根据您的建议更新了代码,现在,我们可以与 DAC 进行通信,并从0x09获得反馈“E0”,我相信 DAC 现在可以正常工作。 现在我们面临一个精度问题,当我从串行端口给 DAC D555时 ,它在开始时提供了19.9mA,但它缓慢下降到19.5mA,我怀疑 NPN 热量(当20mA 和24V 使其处于高温时)会产生输出漂移。 因此、我尝试减少 NPN 产生的热量。  

           关于原理图中使用的现有齐纳二极管和电阻器,它们可以降低多少电压? 如何计算压降电压?   我是否可以将100Ω 更改为更多,,如500 Ω 或1K Ω,消耗更多的功率,降低施加在 NPN 上的电压?  我尝试在环路+上增加12V,NPN 的温度对我来说是可以的。  

          在这段特殊时间内保持安全。  

    谢谢!

    Jeffrey  

           

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

    您好 Jeffrey、

    我很高兴 SPI 现在可以正常工作。

    NPN 的发热可能会导致其 β 下降、从而导致环路精度降低。 确认这一点的最佳方法是使用较低的电源电压或通过连接到 LOP+、LOP-端子的一些串联电阻负载来检查电流精度。  

    应用电路中使用的齐纳二极管是一个3.9V 齐纳二极管、将 NPN 上的电压降低约3.9V。 只要仍然满足环路合规电压要求、就可以增大集电极上的100欧姆电阻器(RC)。 增加 RC 也会降低 NPN VCE 电压。 增加 RC

    环路依从电压决定了最小环路电源电压。 使用 KVL、在最大 I_LOOP 条件下、环路组件上所有压降的总和应小于最小环路电源。 第9.2.2.2节对此进行了说明。 规格。 根据该部分下的公式22、当 RC = 100 Ω 且 Rload (max)= 250 Ω 时、最小环路电源确定为9.3V。

    增加 RC 意味着最小回路电源需要增加24mA*Δ RC 或者最大负载减少 ΔRc Ω。

    但愿这有所帮助。

    此致、

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

    尊敬的 Reza:  

          是的、您是对的、如果使用低电压(如12VDC)或小电流(4mA)、温度处于可接受范围内。考虑整个系统的精度、我需要控制所有器件的温度低于35°C   

          如果“应用电路中使用的齐纳二极管是3.9V 齐纳二极管,并将 NPN 两端的电压降低约3.9V”,我是否可以使用一个具有高电压(如6V 或8V)的齐纳二极管?  那么它将消耗更多的功率? 但我不知道如果更改该齐纳二极管电压会对其他人产生什么影响? 毕竟、它是确保 LDO 提供3.3V 电压的原始功能。 (现在,我使用一个 DCDC 而不是 LDO)

         负载电阻应小于250欧姆、环路电压为24VDV、大于9.3V、因此我将尝试首先将 RC 增加到500或1K。 我正在尝试从所有点降低整个系统的热量。 如果您有任何关于减少热量的建议、非常感谢。  

    谢谢  

     Jeffrey  

    最恰当的考虑  

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

    您好 Jeffrey、

    选择了3.9V 齐纳二极管、以确保始终满足 LDO 的最小输入电压。 您也可以使用6V 或8V 齐纳二极管、但应确保该值大于所选直流/直流转换器的最低输入电压。 当 I_Loop max = 24mA 流经齐纳二极管时、齐纳功率也应足够。

    对于24V 的回路电源、您无法将 RC 更改为1kohm、因为这会违反24mA 时的回路合规性。 请遵循下面的指南行

    环路电源> Vzener + I_Loopmax (RC+ Rload_max)+ 4V

     对于24V 电源、8V 齐纳二极管和250ohm 最大负载、这会将 RC_max 限制为250ohm。

    此致、

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

    您好 Jeffrey、

    您对此设计是否有任何更新? 如果不是、如果出现新问题、您能否关闭此主题并重新打开另一个主题? 谢谢!

    此致、

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

    您好,Reza:

              当然,我将首先关闭此主题。 感谢您宝贵的时间和专业的建议。

    谢谢!

    Jeffrey