D/A转换问题分析
没有电路图,没有程序,这个问题不好分析
一部分电路
#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也有不少寄存器,也要看对这些寄存器的操作是否正确等等