• 專注電子技術學習與研究
    當前位置:單片機教程網 >> 常用芯片 >> 瀏覽文章

    AD5439調試程序及pdf中文資料

    作者:huqin   來源:不詳   點擊數:  更新時間:2014年08月15日   【字體:

        AD5429/AD5439/AD5449分別是CMOS、8/10/12位、雙通道、電流輸出的數模轉換器(DAC)。這些芯片均采用2.5 V至5.5 V電源供電,因此適合電池等低功耗的場合.芯片采用CMOS亞微米工藝制造,能夠提供出色的四象限乘法特性,大信號乘法帶寬達10 MHz。

         這些DAC采用雙緩沖三線式串行接口,并且與SPI、QSPI™、MICROWIRE™及大多數DSP接口標準兼容。采用多個封裝時,還可以通過串行數據輸出(SDO)引腳,將這些DAC以菊花鏈形式相連。利用數據回讀功能,用戶可以通過SDO引腳讀取DAC寄存器的內容。上電時,內部移位寄存器和鎖存以0填充,DAC輸出處于零電平。

         滿量程輸出電流由所施加的外部基準輸入電壓(VREF)決定。與外部電流至電壓精密放大器配合使用時,集成的反饋電阻(RFB)可提供溫度跟蹤和滿量程電壓輸出。


             AD5449 AD5429 AD5439引腳圖

    芯片的優勢和特點:



    pdf英文資料下載:http://www.thefapper.com/f/AD5429_5439_5449.pdf

    中文資料下載:http://www.thefapper.com/f/AD5439中文資料.docx

    AD5439是雙路 10bit 電流輸出型DAC,由于沒有搞過SPI接口的DAC,所以先在網上下載了一個該DAC的底層函數,程序代碼如下:

    #include "macros.h"
    #include "math.h"
    #include "dac.h"

    // 向AD5439寫命令字以及待轉換的數據
    void WriteAD5439(unsigned int ControlBits,unsigned int data )
    {
       unsigned char i;
      
      data = (data << 2);
      data = (ControlBits | data);
      
      SCLK_SET;
      SYNC_CLR;
      
      for(i=0;i<16;i++)
      {
          SCLK_SET;
        if((data & 0x8000) != 0)
       {
           SDIN_SET;
          }
       else
       {
           SDIN_CLR;
          }
       SCLK_CLR;
       data  = (data << 1);
      }
      SYNC_SET;
      LDAC_CLR;
      SCLK_CLR;
      LDAC_SET;
      delay_ms(1);
      
    }

    // 初始化AD5439,
    void  InitAD5439( void )
    {
        ADCCL_CLR;  // AD5439.CLR = LOW,清零
        delay_ms(5);
        ADCCL_SET;  // AD5439.CLR = High,準備工作
        WriteAD5439_CMD(0x9000);
    }              

    // 讀出SDO的值
    unsigned int readSDO(unsigned int channal)
    {
        unsigned char i = 0;
        unsigned int readData = 0;
     
        // 寫入控制字,選擇讀回的通道
        if(channal == ReadBack_I)
        {
         WriteAD5439_CMD(ReadBack_I);
     }
     if(channal == ReadBack_V)
     {
         WriteAD5439_CMD(ReadBack_V);
     }
     
     // 準備接收數據
     SYNC_CLR;
     SCLK_CLR;  
     
     // 讀數據,并處理
     for(i=0;i<16;i++)
     {
         SCLK_SET; // 上升沿,讀一位
         readData |= (PINB & 0x01) << (15-i);
      SCLK_CLR; // 準備下一回讀出數據
      //delay_ms(1); 
     }
     SYNC_SET;
     
     readData = ((readData >> 2) & 0x3ff);// 根據5439的命令字格式進行調整
     
     // 返回數據
     return readData; 
    }

    // 針對Init5439(),readSDO(),只寫命令字,不寫數據                  
    void WriteAD5439_CMD(unsigned int ControlBits)
    {
         unsigned char i;
      unsigned int data = ControlBits; 
      
      SCLK_SET;
      SYNC_CLR;
      for(i=0;i<16;i++)
      {
          SCLK_SET;
        if((data & 0x8000) != 0)
       {
           SDIN_SET;
          }
       else
       {
           SDIN_CLR;
          }
       SCLK_CLR;
       data  = (data << 1);
      }
      SYNC_SET;
      LDAC_CLR;
      SCLK_CLR;
      LDAC_SET;
      delay_ms(20);
    }


    void WriteVoltage(unsigned int ControlBits,unsigned int data)
    {
      unsigned int  channal,i; // 選擇通道
      unsigned int  dataInUse = data; // 用以重新調用write5439(),防止data受到破壞
      unsigned int  dataReadBack = 0;

     
      
      if(ControlBits == Load_I)
      {
          channal = ReadBack_I;
      }
      if(ControlBits == Load_V)
      {
          channal = ReadBack_V;
      }

      i=0;
      for(;;)
      {
      
         WriteAD5439(ControlBits,dataInUse);
       
          dataReadBack = readSDO(channal);
          if(dataInUse == dataReadBack)
       {
              WriteAD5439(Updata_AB,dataInUse);
        break;
       } 
       else
       {
          i++;
       }
         if(i > 10) // 連續10次寫不正確,則關機退出
       {
           SoftStartOff;     
       }
      }

    }

    void main(void)
    {
        init_MCU(); // 初始化MCU

        WriteVoltage(Load_V,1024);  

        while(1)
        {
             process();  
        }

    }

     

          我首先看的是中文的pdf,我結合著這個程序去看該DAC的讀寫時序圖,沒發現程序有什么問題!那就開工吧,我用的是STC89C52RC作為主控,用io口模擬SPI,沒多久程序一個簡單的測試程序就出來啦,編譯沒錯誤沒警告。下載,調試,示波器上顯示出一個-5v的電壓,哦,忘了說我用的是哪個電路啦,上圖

    我是用的雙極性輸出電路,我采用5v的基準,那么輸出電壓范圍為-5到+5v。

    下面需要解決的問題就是,為何DAC一直輸出-5v

    我所采用解決方法如下:

    第一:采用邏輯分析儀看我程序輸出的時序是否正確,經觀察時序和pdf上的時序一樣。找不到問題,我沒辦法只好硬著頭皮去看英文pdf,勉強可以看懂,看一遍后沒發現問題所在。。。。。。這消耗了兩天多的時間,最后確實沒轍啦,好吧找技術支持,第二天技術支持給我回復啦,他提出了兩個問題(1)SCLK占空比不是50%(2)獨立模式下,數據建立時間是否足夠長



                                                                                                  獨立模式時序圖


                                                                                      時序圖上對應的各個時間

    我解決SCLK占空比不是50%的問題,方法如下

    通過給時鐘加延時來實現占空比為50%,如紅線示

    通過時序圖我們可以知道數據建立時間為t5,5ns,使用52作為主控,數據建立時間肯定大于5ns,程序改好,上電,觀察示波器還是-5v,崩潰。。。。。。再次拿起英文pdf從頭到尾看了一篇,還是沒思路,先放放吧,去焊接個板子去吧,讓大家看看板子的圖,嘻嘻

    同樣的板子焊接了兩塊

           焊接結束我接著調試我的DAC測試板,一樣的沒有進展,一樣的辦法我接著看英文pdf,然后接著迷茫。。。。。。

    最后在一個陽光明媚的下午,突然間我想起啦上次調試AD7799出現的問題就是因為CS的信號有問題,我看了看AD5439的時序圖,發現SYNC貌似和CS有同樣的功能,我直接把SYNC拉低,輸出電壓時0v,貌似不是這里的問題,我又把SYNC接回單片機引腳,這時候竟然奇跡的電壓變化啦,我試了好幾個數據電壓輸出卻是變啦,但是沒試幾次就不管用啦,又回到了-5v。這時候我隱約覺得是不是SYNC的時序真的有問題呢?重看時序,發現問題啦。!

    紅框框里標記的我理解的是16個脈沖結束后,SYNC置高,拉低都可以,我當時按參考程序上來的,直接給SYNC置高!

    void WriteAD5439(uint ContralBits,uint DAdata)
    {
     unsigned char i;
     uint buf;
     uint wave_data;
     buf=DAdata;
     buf = (buf<<2);
     wave_data = (ContralBits | buf);
     SYNC_SET();
     delay(1);
     SCLK_SET();
     SYNC_CLR();
     for(i=0;i<16;i++)
       {
        SCLK_SET();
        if((wave_data & 0x8000) != 0)
       {SDIN_SET();}
     else
       {SDIN_CLR();}
        delay(1);
     SCLK_CLR();
        delay(1);
     wave_data = (wave_data << 1);
        }
     SYNC_SET();
     LDAC_CLR();
     delay(1);
     SCLK_SET();
     LDAC_SET();
     delay(1);
     }

    我就想改下試試吧,然后我就把寫數據的函數改為下面的


    void WriteAD5439(uint ContralBits,uint DAdata)
    {
     unsigned char i;
     uint buf;
     uint wave_data;
     buf=DAdata;
     buf = (buf<<2);
     wave_data = (ContralBits | buf);
     SYNC_SET();
     delay(1);
     SCLK_SET();
     SYNC_CLR();
     for(i=0;i<16;i++)
       {
        SCLK_SET();
        if((wave_data & 0x8000) != 0)
       {SDIN_SET();}
     else
       {SDIN_CLR();}
        delay(1);
     SCLK_CLR();
        delay(1);
     wave_data = (wave_data << 1);
        }
     SYNC_CLR();
     SCLK_SET();
     delay(1);
     }

    重新上電,示波器上的數據終于會變化啦。!搞定!收尾附上我的測試程序,以方便別人學習。!

     

    #include <at89x51.h>

    #define uchar unsigned char
    #define uint  unsigned int

    #define SDIN_SET() P0_0=1;
    #define SDIN_CLR() P0_0=0;

    #define SCLK_SET() P0_1=1;
    #define SCLK_CLR() P0_1=0;

    #define SYNC_SET() P0_2=1;
    #define SYNC_CLR() P0_2=0;

    #define LDAC_SET() P0_3=1;
    #define LDAC_CLR() P0_3=0;

    #define DACLR_SET() P0_4=1;
    #define DACLR_CLR() P0_4=0;

    uint num;

    void delay(uint t)
    {
      uint i;
      while(t--)
      {
       for(i=0;i<125;i++);
       }
     }

    void WriteAD5439_CMD(uint CMDBits)
    {
      unsigned char i;
         unsigned int data1 = CMDBits; 
      SYNC_SET();
      delay(1);
         SCLK_SET();
      SYNC_CLR();
      for(i=0;i<16;i++)
      {
          SCLK_SET();
        if((data1 & 0x8000) != 0)
       {
           SDIN_SET();
          }
       else
       {
           SDIN_CLR();
          }
             delay(1);
       SCLK_CLR();
             delay(1);
       data1  = (data1 << 1);
      }
      SYNC_CLR();
      //LDAC_CLR();
      //delay(1);
      SCLK_SET();
      //LDAC_SET();
      delay(20);
    }

    void WriteAD5439(uint ContralBits,uint DAdata)
    {
     unsigned char i;
     uint buf;
     uint wave_data;
     buf=DAdata;
     buf = (buf<<2);
     wave_data = (ContralBits | buf);
     SYNC_SET();
     delay(1);
     SCLK_SET();
     SYNC_CLR();
     for(i=0;i<16;i++)
       {
        SCLK_SET();
        if((wave_data & 0x8000) != 0)
       {SDIN_SET();}
     else
       {SDIN_CLR();}
        delay(1);
     SCLK_CLR();
        delay(1);
     wave_data = (wave_data << 1);
        }
     SYNC_CLR();
     //LDAC_CLR();
     //delay(1);
     SCLK_SET();
     //LDAC_SET();
     delay(1);
     }

    unsigned int readSDO(void)
    {
        unsigned char i = 0;
        unsigned int readData = 0;
        bit  itemp;
     
     WriteAD5439_CMD(0X2000);
     SYNC_SET();
        delay(1);
     SYNC_CLR();
     
     for(i=0;i<16;i++)
     {
         SCLK_SET();
            readData <<= 1;
            delay(1);
         itemp = P0_5;
      SCLK_CLR(); 
      if(itemp)
              readData |= 1;
      delay(1);
         }
     SYNC_CLR();
     return readData; 
    }

    void  InitAD5439( void )
    {
        DACLR_CLR();  
        delay(5);
        DACLR_SET();  
    }        

    void main (void)
    {
     num=1023;
     //InitAD5439();
     WriteAD5439_CMD(0x9000);
     WriteAD5439(0x1000,num);
     //readSDO();
     while(1)
       {
       num=1023;
       WriteAD5439(0x1000,num);
       delay(10);
       num=0;
       WriteAD5439(0x1000,num);
       delay(10);
       };
    }

    關閉窗口

    相關文章

    亚洲一区二区制服在线|在绩专区欧美自拍日韩|青春娱乐网97超碰人人射|在线观看国产网址你懂的