cheney03 发表于 2021-4-20 11:28

AD9106 相关问题

本帖最后由 cheney03 于 2021-4-20 11:34 编辑

<p>项目要用到AD9106这款芯片,现在遇到了点问题.</p>

<p>&nbsp;首先我把我的需求说一下。我需要至少生成两路正弦波,并且能够同步输出,幅度/相位/频率(频率固定60/120/240/480/960KHz) 均可改变。</p>

<p>因为我的输出频率在1MHz以下,所以时钟我采用的是单端输入,参考的是数据手册page 24of48&nbsp;图39设计,如图 此设计是否可行?</p>

<div style="text-align:start; text-indent:0px; -webkit-text-stroke-width:0px">
<p>&nbsp;</p>

<p><span style="font-size:14px"><span style="color:#000000"><span style="font-family:&quot;lucida Grande&quot;, Verdana, &quot;Microsoft YaHei&quot;"><span style="font-style:normal"><span style="font-variant-ligatures:normal"><span style="font-variant-caps:normal"><span style="font-weight:400"><span style="letter-spacing:normal"><span style="orphans:2"><span style="text-transform:none"><span style="white-space:normal"><span style="widows:2"><span style="word-spacing:0px"><span style="background-color:#ffffff"><span style="text-decoration-style:initial"><span style="text-decoration-color:initial"><span style="line-height:23.8px">我采用的是单片机IO口模拟SPI写AD9106,目前棘手的问题是数据无法写入芯片,SPI写数据正确,已经用逻辑分析仪验证</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</div>

<div style="text-align:start; text-indent:0px; -webkit-text-stroke-width:0px">
<p><span style="font-size:14px"><span style="color:#000000"><span style="font-family:&quot;lucida Grande&quot;, Verdana, &quot;Microsoft YaHei&quot;"><span style="font-style:normal"><span style="font-variant-ligatures:normal"><span style="font-variant-caps:normal"><span style="font-weight:400"><span style="letter-spacing:normal"><span style="orphans:2"><span style="text-transform:none"><span style="white-space:normal"><span style="widows:2"><span style="word-spacing:0px"><span style="background-color:#ffffff"><span style="text-decoration-style:initial"><span style="text-decoration-color:initial"><span style="line-height:23.8px">&nbsp;因为配置BGDR(写地址0x03),改变数据,通过万用表测量到REFIO引脚的无电平变化,正常改变code值,VREFIO的值也会改变。</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</div>

<div style="text-align:start; text-indent:0px; -webkit-text-stroke-width:0px">
<p>&nbsp;</p>
</div>

<p>&nbsp;</p>

cheney03 发表于 2021-4-20 11:39

<p>原理图是参考虾哥的帖子https://bbs.eeworld.com.cn/thread-511550-1-1.html,还有官方设计的</p>

cheney03 发表于 2021-4-20 11:43

<pre>
<code>
#include &lt;reg52.h&gt;
#include &lt;intrins.h&gt;
sbit TRIGGER =P2^0;
sbit SCLK    =P2^1;
sbit SDIO    =P2^2;
sbit CS      =P2^3;
sbit RESET   =P2^4;




void SET_CS()
{
        CS=1;              //P2.3-&gt;/CS, /CS=1
}

void CLR_CS()
{
        CS=0;                 // /CS=0
}

void SET_SCLK()
{
        SCLK=1;         //P2.3-&gt;SCLK, SCLK=1
}

void CLR_SCLK()
{
        SCLK=0;                                        // SCLK=0
}

void SET_SDIO(void)
{
SDIO=1;          //P2.2-&gt;SDIO, SDIO=1
}

void CLR_SDIO(void)
{
SDIO=0;                                       //SDIO=0
}

void SET_Trigger(void)
{
TRIGGER=1;             //P2.3-&gt;Trigger, Trigger=1
}

void CLR_Trigger(void)
{
TRIGGER=0;                  //Trigger=0
}

void SET_Reset(void)
{
RESET=1;             //P2.3-&gt;Trigger, Trigger=1
}

void CLR_Reset(void)
{
TRIGGER=0;                  //Trigger=0
}

void delay (int length)
{
        while (length&gt;=0)
        length--;
}


void spi_write_byte(unsigned char temp)
{
   unsigned char i;
   for(i=0;i&lt;8;i++)//32
{
       if(temp&amp;0x80)
       {
               SET_SDIO();                                          //Send 1 to SDIO pin
       }
       else
        {
                CLR_SDIO();                                                                   //Send 0 to SDIO pin
        }

                delay(1);                     
                SET_SCLK();                                                                                           //SCLK Rising
                delay(2);
                CLR_SCLK();                                                                                           //SCLK falling
                delay(1);
                temp&lt;&lt;= 1;                                    //Rotate data
       }
}

void WriteToAD9106(unsigned int Address, unsigned int Data)
{

       
        CLR_CS();
        CLR_SCLK();

delay(1);
        spi_write_byte(Address &gt;&gt; 8);
spi_write_byte(Address);

spi_write_byte(Data &gt;&gt; 8);
spi_write_byte(Data);        
SET_CS();
}

//void WriteToAD9106(unsigned int InstruAndData,unsigned int InstruAndData2)
//{
//unsignedint SendValue =0;
//unsignedint        SendValue2 =0;
//unsignedint i = 0;

//SendValue = InstruAndData;
//SendValue2 = InstruAndData2;        
//delay(1);
//                                            //bring CS low
//CLR_SCLK();
//CLR_CS();
//delay(1);
//for(i=0;i&lt;16;i++)//32
//{
//        if(SendValue&amp;0x8000)
//        {
//                SET_SDIO();                                          //Send 1 to SDIO pin
//        }
//        else
//        {
//                CLR_SDIO();                                                                   //Send 0 to SDIO pin
//        }

//                delay(1);                     
//                SET_SCLK();                                                                                           //SCLK Rising
//                delay(2);
//                CLR_SCLK();                                                                                           //SCLK falling
//                delay(1);
//                SendValue &lt;&lt;= 1;                              //Rotate data
//        }
//for(i=0;i&lt;16;i++)//32
//{

//        if(SendValue2&amp;0x8000)
//        {
//                SET_SDIO();                                          //Send 1 to SDIO pin
//        }
//        else
//        {
//                CLR_SDIO();                                                                   //Send 0 to SDIO pin
//        }
//                delay(1);                     
//                SET_SCLK();                                                                                           //SCLK Rising
//                delay(2);
//                CLR_SCLK();                                                                                           //SCLK falling
//                delay(1);
//                SendValue &lt;&lt;= 1;                              //Rotate data
//        }

//                SET_CS();                                             //bring CS high again
//}

void AD9106_Init()
{
SET_CS();       
SET_Trigger();
CLR_Reset();       
delay(14);
SET_Reset();       

WriteToAD9106(0x001f,0x0000);//模式连续运行。
WriteToAD9106(0x000c,0x9f1f);
WriteToAD9106(0x0027,0x3131);//DDS输出,预存波形
WriteToAD9106(0x0037,0x00fc);//上斜坡锯齿波

WriteToAD9106(0x0035,0x4000);//Data=0x4000Very important,the maximum value is 0x4000
WriteToAD9106(0x003e,0x006c);//Register 0x3E, Data=0x0E38
WriteToAD9106(0x003f,0xe600);//Register 0x3F, Data=0xE600           5MHz output,50MHz fsys
WriteToAD9106(0x001d,0x0001);//用新配置更新所有SPI设置(自清零)

WriteToAD9106(0x001e,0x0001);//PAT_STATUS 0x1E, run bit=1           Very important
WriteToAD9106(0x001d,0x0001);
delay(14);
CLR_Trigger();
WriteToAD9106(0x001d,0x0001);
}       


void main()
{
//unsignedint InstruAndData_PatternType=0x001F0000;                 //Register 0x1F,Data=0x0000(Continuous)       
//unsignedint InstruAndData_Wave4=0x00263131;                       //Register 0x26,Data=0x3131(wavefrom typ)          DAC4 and DAC3 select the DDS prestore wave form.
//unsignedint InstruAndData_DGAIN4=0x00324000;                           //DAC4_DGAIN 0x32, Data=0x4000Very important,the maximum value is 0x4000
//unsignedint InstruAndData_DGAIN3=0x00334000;                                 //DAC3_DGAIN 0x33,
//unsignedint InstruAndData_DDSMSB=0x003E1999;//0x003E0E38;       //Register 0x3E, Data=0x0E38
//unsignedint InstruAndData_DDSLSB=0x003F9A00;//0x003FE600;       //Register 0x3F, Data=0xE600           10MHz output,180MHz fsys 10M=(FTW/2^24)*180M FTW=0XE38E6(932067.5555555556)
//unsignedint InstruAndData_DDS4_PW=0x00401300;                           //Register 0x40, DDS4degree           adjust the DDS4 and DDS3 to have the same phase
//unsignedint InstruAndData_Run=0x001E0001;                  //PAT_STATUS 0x1E, run bit=1           Very important
//unsignedint InstruAndData_update=0x001D3D70;//0x001D0001;       //Register 0x1D, Data=0xE600

// AD9106_Init();       

        while(1)
{
      
//          AD9106_Init();
      WriteToAD9106(0x0003,0x003F);
               
////WriteToAD9106(0x3203,0x982F);
////WriteToAD9106(InstruAndData_PatternType);
//    WriteToAD9106(0x001F,0x0000);               
////WriteToAD9106(InstruAndData_Wave4);
//          WriteToAD9106(0x0026,0x3131);
////WriteToAD9106(InstruAndData_DGAIN4);
//          WriteToAD9106(0x0032,0x4000);
////WriteToAD9106(InstruAndData_DGAIN3);
//    WriteToAD9106(0x0033,0x4000);               
////WriteToAD9106(InstruAndData_DDSMSB);
//    WriteToAD9106(0x003E,0x1999);                
////WriteToAD9106(InstruAndData_DDSLSB);
//          WriteToAD9106(0x003F,0x9A00);
////WriteToAD9106(InstruAndData_DDS4_PW);
//    WriteToAD9106(0x0040,0x1300);

////WriteToAD9106(InstruAndData_update);
//    WriteToAD9106(0x001D,0x3D70);
////WriteToAD9106(InstruAndData_Run);
//    WriteToAD9106(0x001E,0x0001);
////WriteToAD9106(InstruAndData_update);
//    WriteToAD9106(0x001D,0x3D70);
//    delay(10);
//   CLR_Trigger();
////WriteToAD9106(InstruAndData_update);
//    WriteToAD9106(0x001D,0x3D70);
////while(1);
//          
}       
}

</code></pre>

<p>&nbsp;</p>

littleshrimp 发表于 2021-4-20 11:48

<p>用示波器测量一下时钟&ldquo;CLKP&rdquo;是否正常,用万用表测试一下AVDD,DVDD电压是否正常,除硬件问题。</p>

<p>芯片复位后,使用SPI读取全部非零的寄存器,对比数据手册看数值是否一致。</p>

<p>用官方提供的ADuC7026例程做移植,或者参照https://wiki.analog.com/resources/eval/dpg/eval-ad9106这里的例程测试能否正常通信。</p>

<p>&nbsp;</p>

cheney03 发表于 2021-4-20 11:50

cheney03 发表于 2021-4-20 11:43
#include &lt;reg52.h&gt;
#include &lt;intrins.h&gt;
sbit TRIGGER =P2^0;
sbit SCLK    =P2^1;
sbit ...

<p>程序也是参考官方的,发现用官方的SPI写例程连续写地址+数据共32位数据不对,后面我分开写地址和数据,用逻辑分析仪I抓取SPI写数据正确,但是数据无法写入芯片,WriteToAD9106(0x0003,0x003F);写地址0x0003,改变数据字,通过万用表测量到REFIO引脚的无电平变化,说明数据没有写入</p>

littleshrimp 发表于 2021-4-20 12:49

cheney03 发表于 2021-4-20 11:50
程序也是参考官方的,发现用官方的SPI写例程连续写地址+数据共32位数据不对,后面我分开写地址和数据,用 ...

<p>可以试着排除硬件或通信问题,比如复位后读全部非零寄存器,或者写入后再读出对比看是否一致。</p>

<p>或者测量硬件看是否正常。</p>

cheney03 发表于 2021-4-20 15:00

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-20 12:49
可以试着排除硬件或通信问题,比如复位后读全部非零寄存器,或者写入后再读出对比看是否一致。

或者测 ...

<p>还有一个疑问,我主机MCU供电电压是5V的,AD9106的供电电压3.3V,SPI通讯是否要求主从机电压一致?若像我这样SPI通讯,电压过高是否会损坏或者击穿芯片?</p>
</div><script>showreplylogin();</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

cheney03 发表于 2021-4-20 15:34

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-20 11:48
用示波器测量一下时钟&ldquo;CLKP&rdquo;是否正常,用万用表测试一下AVDD,DVDD电压是否正常,除硬件问题。 ...

<p>示波器测输入时钟晶振输入正常,AVDD,DVDD均为3.3V,接REFIO电容两端参考电压为0.999V,DLDO1/DLDO2/CLKLDO 电容两端电压均为1.8V</p>
</div><script>showreplylogin();</script>

littleshrimp 发表于 2021-4-20 16:29

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-20 15:00
还有一个疑问,我主机MCU供电电压是5V的,AD9106的供电电压3.3V,SPI通讯是否要求主从机电压一致?若像我 ...

<p>不能使用5V驱动,应该会损坏,但不一定肯定会损坏。</p>

<p></p>
</div><script>showreplylogin();</script>

littleshrimp 发表于 2021-4-20 16:29

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-20 15:34
示波器测输入时钟晶振输入正常,AVDD,DVDD均为3.3V,接REFIO电容两端参考电压为0.999V,DLDO1/DLDO2/CLKL ...

<p>那还是重点检查通信吧,应该是通信方面的问题。</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-20 16:37

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-20 16:29
那还是重点检查通信吧,应该是通信方面的问题。

<p>我也觉得通信方面问题比较大,写数据我用逻辑分析仪抓取数据是对的,读要怎么读寄存器呢,小白不怎么会写程序</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-20 16:40

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-20 16:37
我也觉得通信方面问题比较大,写数据我用逻辑分析仪抓取数据是对的,读要怎么读寄存器呢,小白不怎么会写 ...

<pre>
<code>从AD9106写一字节,模拟SPI总线方式
void spi_write_byte(unsigned char temp)
{
   unsigned char i;
   for(i=0;i&lt;8;i++)//32
{
       if(temp&amp;0x80)
       {
               SET_SDIO();                                          //Send 1 to SDIO pin
       }
       else
        {
                CLR_SDIO();                                                                   //Send 0 to SDIO pin
        }

                delay(1);                     
                SET_SCLK();                                                                                           //SCLK Rising
                delay(2);
                CLR_SCLK();                                                                                           //SCLK falling
                delay(1);
                temp&lt;&lt;= 1;                                    //Rotate data
       }
}


//从AD9106读一字节,模拟SPI总线方式
unsigned char spi_read_byte()
{
    unsigned char tdata,i;
    for(i=8;i;i--)
    {   delay(1);       
      CLR_SCLK();
      delay(2);
          SET_SCLK();
      tdata&lt;&lt;=1;
      if(SDIO)
                tdata|=1;
   
    }
    return tdata;
}





unsigned int Read_AD9106(unsigned int Address)
{

        unsigned int data1,data2;
        unsigned int tdata;
       
        CLR_CS();
        CLR_SCLK();

    delay(1);
    spi_write_byte(Address &gt;&gt; 8);//
    spi_write_byte(Address);    //发送命令字和地址

    data1=spi_read_byte();   //读取数据
    data2=spi_read_byte();
       
    SET_CS();
    tdata=(data1&lt;&lt;8)|data2;
    return tdata;
}
</code></pre>

<p>&nbsp;</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-20 16:45

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-20 16:29
那还是重点检查通信吧,应该是通信方面的问题。

<p>先发送命令字+地址&nbsp;&nbsp;接着读两字节(数据为16位),然后两字节数据再做处理,这样时序方面有没错呢?</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-21 11:40

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-20 16:29
那还是重点检查通信吧,应该是通信方面的问题。

<p>有个很奇怪的现象,按图中接法,逻辑分析仪单独接单片机,抓取的数据正确,但是中间连接了我的AD9106实验板,无法抓取数据,感觉是芯片的SLCK/SDIO/CS这几引脚有阻碍作用。AD9106的输入时钟(CLKP/CLKN)对SPI通讯没影响吧,是不是只要上电,硬件SLCK/SDIO/CS连接正确就能写数据到芯片?</p>
</div><script>showreplylogin();</script>

littleshrimp 发表于 2021-4-21 12:01

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-21 11:40
有个很奇怪的现象,按图中接法,逻辑分析仪单独接单片机,抓取的数据正确,但是中间连接了我的AD9106实验 ...

<p>现在两端的电平都是3.3V吗?</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-21 13:31

<div class='shownolgin' data-isdigest='no'>littleshrimp 发表于 2021-4-21 12:01
现在两端的电平都是3.3V吗?

<p>是的,电平一样。<strong>问题终于解决了,是我SPI通讯线过长,之前的线长40cm,换了20cm的,成功写入</strong>。再次感谢你的解答,后面可能还会遇到问题,到时再向你请教。</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-21 15:40

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-21 11:40
有个很奇怪的现象,按图中接法,逻辑分析仪单独接单片机,抓取的数据正确,但是中间连接了我的AD9106实验 ...

<p>现在SPI写数据可以写入芯片,改变BGDR值,<span style="font-size:9.5pt"><span style="font-family:MinionPro-Regular"><span style="color:#070001">V</span></span></span><span style="font-size:5.5385pt"><span style="font-family:MinionPro-Regular"><span style="color:#070001">REFIO</span></span></span><span style="font-size:9.5pt"><span style="font-family:IYGYJS+HYa3gj"><span style="color:#070001">电平有改变.。但是我的数据跟数据手册中的不一样。当</span></span></span>BGDR=0x00时,电压应该是1.04V,我的测出来是0.98V。当BGDR=0x20(32)时,电压应该是0.84V,我的测出来是0.78V。</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-25 11:03

<div class='shownolgin' data-isdigest='no'><p>波形已经调出来了,但是波形不稳会上下抖动,而且一段时间后会失真</p>
</div><script>showreplylogin();</script>

cheney03 发表于 2021-4-25 11:06

<div class='shownolgin' data-isdigest='no'> 本帖最后由 cheney03 于 2021-4-25 11:07 编辑

<pre>
<code>void AD9106_Init()
{
   SET_CS();       
   SET_Trigger();
   CLR_Reset();       
   delay(14);
   SET_Reset();       

   WriteToAD9106(0x001f,0x0000);      //模式连续运行。
// WriteToAD9106(0x0009,0x9F1F);      // DAC4 RSET(0x000c,0x9f1f);DAC1 RSET
   WriteToAD9106(0x0026,0x3131);      //(0x0027,0x3131); //DDS输出,预存波形
   WriteToAD9106(0x0032,0x4000);      // DAC4_DGAIN
   WriteToAD9106(0x0033,0x4000);      // DAC3_DGAIN

//WriteToAD9106(0x0036,0x00fc);      //DAC3/4 //(0x0037,0x00fc); DAC1/2锯齿配置寄存器 上斜坡锯齿波

//WriteToAD9106(0x0035,0x4000);      //Data=0x4000Very important,the maximum value is 0x4000
WriteToAD9106(0x003e,0x0A3D); //       //Register 0x3E, Data=0x009D
WriteToAD9106(0x003f,0x7100); //      //Register 0x3F, Data=0x4900           1MHz output,25MHz fsys
WriteToAD9106(0x001d,0x0001);       //用新配置更新所有SPI设置(自清零)

WriteToAD9106(0x001e,0x0001);      //PAT_STATUS 0x1E, run bit=1           Very important
WriteToAD9106(0x001d,0x0001);      //用新配置更新所有SPI设置(自清零)
delay(14);
CLR_Trigger();
WriteToAD9106(0x001d,0x0001);      //用新配置更新所有SPI设置(自清零)
}</code></pre>

<p>初始化函数是按这个配置的</p>
</div><script>showreplylogin();</script>

littleshrimp 发表于 2021-4-25 11:25

<div class='shownolgin' data-isdigest='no'>cheney03 发表于 2021-4-25 11:06
void AD9106_Init()
{
   SET_CS();       
   SET_Trigger();
   CLR_Reset();       
   delay(14);
   SET_R ...

<p>你的电流输出没有加缓冲放大器是吗?</p>
</div><script>showreplylogin();</script>
页: [1] 2 3
查看完整版本: AD9106 相关问题