微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > D/A转换问题分析

D/A转换问题分析

时间:10-02 整理:3721RD 点击:
AT89S52单片机处理数字信号,输入到AD5722中,但AD5722并没有输出,其中可能的原因有哪些,有大神愿意分析一下?

没有电路图,没有程序,这个问题不好分析

一部分电路


#include <AT89x51.h>
#define uchar unsigned char
#define uint unsigned int
#define ENABLE_INT EA = 1
#define DISABLE_INT EA = 0
//AD5722
sbit DA_SYNCN = P2^6;
sbit DA_SCLK = P2^5;
sbit DA_SDIN = P2^4;
sbit DA_LDACN = P2^3;
sbit DA_CLRN = P2^2;
sbit DA_SDO = P2^7;
//AD7712
sbit AD_SCLK = P0^7;
sbit AD_A0 = P0^6;
sbit AD_SDATA = P0^5;
sbit AD_DRDY = P0^4;
sbit AD_RFS = P0^3;
sbit AD_TFS = P0^2;
//ADG1611
void delay_nus(unsigned int n)
{
    unsigned int i;
        for(i = n; i > 0; i--)
        {
            ;
        }
}

void DA_write_data(uchar addr,uint dat)
{
    int i;
        uint temp;
       
        DA_SYNCN = 1;
        DA_LDACN = 1;
        DA_SCLK  = 1;   
        DA_SYNCN = 0;
        //delay_nus(1);
        for(i = 7;i >= 0;i--)
        {   
            temp = ((addr >> i) & 0x01);
        DA_SDIN = temp;
                //delay_nus(1);
                DA_SCLK = 0;
                //delay_nus(1);
                DA_SCLK = 1;
                //delay_nus(1);
        }
        for(i = 15;i >= 0;i--)
        {
                temp = ((dat >> i) & 0x01);
        DA_SDIN = temp;
                //delay_nus(1);
                DA_SCLK = 0;
                //delay_nus(1);
                DA_SCLK = 1;
                //delay_nus(1);
        }
        DA_SYNCN = 1;
       
        //delay_nus(1);
        DA_LDACN = 0;
        //delay_nus(1);
        DA_LDACN = 1;
}


void DA_init()
{
   DA_CLRN = 0;
   delay_nus(5);
   DA_CLRN = 1;
   delay_nus(1);
   DA_LDACN = 1;
   DA_SYNCN = 1;
   DA_SCLK = 1;
   //1 output range 2 power 3 control   
   DA_write_data(0x0c,0x0003);// +5V output range
   delay_nus(100);
   //internal ref set 0x10 0x0011 A
   //0x10 0x0014 B
   //0x10 0x0015 A and B
   //DA_write_data(0x10,0x0015);//internal ref
   DA_write_data(0x10,0x0005);
   //control reg
   delay_nus(100);
   DA_write_data(0x19,0x0009);//Control Reg
   delay_nus(100);
}
void Uart_init(void)    //?
{
    SCON = 0x50;    //?1, 8?,?      
    TMOD |= 0x20;    //?TIMER1: timer 1,?2     
    PCON |= 0x00;    //SMOD=1  
    TH1 = 0xfd;    // TH1:  reload value for 38400 baud @ 22.1184MH
    TR1 = 1;    // TIMER1?
    ES = 1;    //?
    PS = 1;    //?
    ENABLE_INT;
}
void com_isr() interrupt 4    //?
{
    //uchar temp;
        //bit bTI_Backup;
    DISABLE_INT;    //?
    if(RI)    //?
    {
        RI = 0;    // RI?
                //bTI_Backup = TI;
                //TI = 0;
                //temp = SBUF;
                //while(!TI);
                //TI = bTI_Backup;
                       
    }
    if(TI)    //?,?TI?
    {  
        TI = 0;    //TI?,?
    }

         ENABLE_INT;    //?  
}
void Uart_send(uchar dat)
{
      DISABLE_INT;
      SBUF = dat;
          while(!TI);
          TI = 0;
      ENABLE_INT;
       //?
}

void ulong_data_send(unsigned long dat)
{
        uchar buf;
            uchar com_d1,com_d2,com_d3,com_d4;
        buf = (dat >> 21) & 0x7f;
            com_d1 = 128 + buf;
            buf = (dat >> 14)&0x7f;
                com_d2 = buf;
               
            buf = (dat >> 7)&0x7f;
                com_d3 = buf;
                              
                com_d4 = dat &0x7f;
               
                Uart_send(com_d1);
                Uart_send(com_d2);
                Uart_send(com_d3);
                Uart_send(com_d4);
}



void AD7712_init()
{
        AD_TFS = 1;
        AD_SCLK = 0;
        AD_RFS = 1;
}

unsigned long AD7712_read_dat2()
{
      char index = 0;
          unsigned long res = 0;
          uchar bit_dat = 0;
         
          DISABLE_INT;
          AD_RFS = 1;
      AD_SDATA = 1;
          AD_A0 = 0;
          AD_SCLK = 0;
          AD_DRDY = 1;
         
          while(AD_DRDY);
          
          AD_A0 = 1;
      AD_RFS = 0;
          while(AD_DRDY == 0)
          {
            
            index++;
               
                delay_nus(4);
            AD_SCLK = 1;
                delay_nus(4);
                bit_dat = AD_SDATA;
            AD_SCLK = 0;
            
        AD_SDATA = 1;
       
                res <<=1;
                res +=bit_dat;       
                
               
                AD_DRDY = 1;
          }
          AD_RFS = 1;
          AD_A0 = 0;
          ENABLE_INT;
          return res;
}


unsigned long AD7712_read_dat(uchar total_bits)
{     
          unsigned long res = 0;
          char index = 0;
          uchar bit_dat = 0;
          
          DISABLE_INT;
         
          AD_RFS = 1;
      AD_SDATA = 1;
          AD_A0 = 0;
          AD_SCLK = 0;
          AD_DRDY = 1;
         
          while(AD_DRDY);          
          AD_A0 = 1;
      AD_RFS = 0;
          for(index = 0;index < total_bits; index++)
          {
            delay_nus(10);
            AD_SCLK = 1;
                delay_nus(10);
                bit_dat = AD_SDATA;
            AD_SCLK = 0;            
        AD_SDATA = 1;       
                res <<= 1;
                res +=bit_dat;               
          }
          AD_RFS = 1;
          AD_A0 = 0;
          ENABLE_INT;
          return res;
          
}
void AD7712_wr_ctr_reg(uchar mode,uchar gain,uchar CH,uchar PD,uchar WL,uchar BO,uchar BU,uint fs)
{
        int i = 0;
        uchar control_reg0,control_reg1,control_reg2;
    DISABLE_INT;

        control_reg0 = (mode << 5) + (gain <<2) + (CH <<1) + PD;
       
        control_reg1 = (WL << 7) + (BO << 5) + (BU << 4) + ((fs >> 8)&0x0f);
        control_reg2 = fs &0x00ff;
     AD_RFS = 1;
         AD_TFS = 1;
     AD_SDATA = 0;
         AD_A0 = 1;
         AD_SCLK = 0;
       
     AD_DRDY = 1;
         while(AD_DRDY);
    AD_A0 = 0;
        AD_TFS = 0;
    for(i = 23;i>=0; i--)
        {
               
                if(i >= 16)
                {
                        AD_SDATA = (control_reg0 >>(i-16))&0x01;
                }
                else
                {
                        if(i >= 8)
                        {
                                AD_SDATA = (control_reg1 >>(i-8))&0x01;
                        }
                        else
                        {
                                AD_SDATA = (control_reg2 >> i) & 0x01;
                        }
                }
                delay_nus(5);
                AD_SCLK = 1;
                delay_nus(5);
                AD_SCLK = 0;
                delay_nus(5);
        }
        delay_nus(5);
        AD_TFS = 1;
        AD_A0 = 1;
        AD_DRDY = 1;
        while(AD_DRDY);
        ENABLE_INT;
}
/*
44    5769446
45    5839606
46    5908313
47    5975563
48    6041351
49    6105678
50    6168547
51    6229936
52    6289862
53    6348336
54    6405370
55    6460979
*/

void main()
{
        int idx = 0;

    long TEMP_ERR_VAULE = 34000;
    unsigned long adc_dat = 0;
        unsigned long uart_adc_dat = 0;
        unsigned long dac_dat;
        double e,e1,e2,e_sum;
        double su,delta_u,tmp_u;
        double k1,k2,k3;
        double kp,ki,kd;

    delay_nus(10000);
       
       
    DISABLE_INT;
        Uart_init();
        DA_init();
    AD7712_init();
       
        ENABLE_INT;
       
    DA_write_data(0x02,0x00);


        //AD7712_wr_ctr_reg(uchar mode,uchar gain,uchar ch,uchar PD,uchar WL,uchar BO,uchar BU,uint fs)
    AD7712_wr_ctr_reg(       0x01,      0x00,    0x00,   0x00,   1,        0x00,    0x00,    380);
       
        //AD7712_wr_ctr_reg(        0x05,      0x00,    0x00,   0x00,   0x00,    0x00,   0x00,    0x17c);
    //P1 = 0xfd; //100
        //P1 = 0xFB; //500


        //kp = 1.5;ki = 0.0045;
        //kp = 1.5;ki = 0.009;
    //kp = 0.5;ki =0.006;
        //kp = 0.5;ki = 0.003;
    //kp = 0.1;
        //ki = 0.00001;
    kp = 1.0;
        ki = 0.0002;
    kd = 0.0;
    k1 = kp + ki + kd;
    k2 = -kp - 2*kd;
    k3 = kd;
    e = 0.0;
    e_sum = 0.0;
        e1= 0.0;
        e2= 0.0;
       
        su = 0.0;
        delta_u = 0.0;
        tmp_u = 0.0;

        while(1)
        {
          
          adc_dat =AD7712_read_dat2();
          adc_dat =8388608 - adc_dat;
          adc_dat = adc_dat>>7;
      uart_adc_dat = adc_dat;
          //adc_dat >>=8;
         
      e2 = e1;
          e1 = e;
      e =    TEMP_ERR_VAULE-1.0*adc_dat ;       
      delta_u = k1*e + k2 * e1 + k3 * e2;
       
          su = su + delta_u;
      if(su > 500.0) su = 500.0;
      if(su < -500.0) su = -500.0;
                 
          //if(u < 5.0) u =5.0;       
          tmp_u = (su+2048.0)*16;
          dac_dat = (unsigned long)tmp_u;
          //dac_dat = 0;
          
          DA_write_data(0x02,dac_dat);
          
          if(idx == 10)
          {
             idx = 0;
                 //uint_data_send(res);
                 //uart_adc_dat = dac_dat;
                          
                 ulong_data_send(uart_adc_dat);
           }
          idx++;
        }
}

没用过AD5722,大致看了一下资料,除去硬件等原因,时序也很重要,想办法检测一下时序是否正确,另外AD5722也有不少寄存器,也要看对这些寄存器的操作是否正确等等

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top