[原创]ADI AD8555可编程放大器的体验
0赞
发表于 8/18/2012 11:32:34 AM
阅读(3751)
最近公司引入了一款新的压力传感器,在调理信号的时候使用的很多AD转换器都不合适,老是出现各种漂移,几位老大都很苦恼,昨晚上我们加班,在公司查阅了很多案例,看到了ADI 的 AD8555数字可编程放大器,这款芯片一款增益及输出失调,可数字编程的零漂移桥式传感放大器,特别适合于多点或多参量测量系统的前向通道,可对各种传感器信号进行调理,所以我决定试一试,大家也比较认可。
这款芯片工作电压为2.7 V~5.5 V,工作温度范围为-40℃~125℃;其数字可编程增益控制范围为70~l 280;DC和ACCMRR高达96 dB;输入失调电压低(最大为10μV),输入失调电压漂移50 nV/℃;通过外接电容器,可以方便地实现低通滤波功能;输入和输出范围很宽,能驱动低电压ADC。另外,AD8555还具有开路和短路故障保护以及输出摆幅限制功能。这个特性为我们整个项目的成败起到了决定性作用。
晚上找硬件部的制版后,参照图纸,一直在写程序,加了一晚上班,我觉得很有成就感,迫不及待的拿出来给大家欣赏:这款芯片的控制芯片是ADUC841,
#include<ADuc841.h>
#include<stdio.h>
#define Function 2
// 0:改变感应电流。当AD8555通电后,向高附加值的意义当前默认值。
// 1:模拟模式
// 2: 程序模式
// 3:读模式
#define Second_stage_gain 0 //(<<AD8555 Data Sheet>> Table 7)
//Code--获取
// 0----17.5
// 1----25
// 2----35
// 3----50
// 4----70
// 5----100
// 6----140
// 7----200
#define First_stage_gain 0 //(<<AD8555 Data Sheet>> Table 6 )
//参照AD8555数据表定义
#define Output_offset 128
#define tw1 64
#define tw0 0
#define tws 8
void send_bit(unsigned int);
void delay(int);
void simulate();
void program();
void read();
void current();
void field();
void fieldII(unsigned int);
void fieldIII();
void fieldIV(int);
void fieldIV_program(int);
void fieldV();
sbit digin=P2^1; //设置另外一个输出 ADuC841
int main(void)
{
if(Function==0)current(); //0的时候
else if (Function==1)simulate();//1的情况,下同
else if (Function==2)program();
else read();
while(1){digin=0;}
}
//模拟模式
void simulate()
{
unsigned int temp;
digin=0;
for(temp=1;temp<=3;temp++)
{
field();
send_bit(0);
send_bit(1);
fieldII(temp);
fieldIII();
if(temp==1)
fieldIV(Second_stage_gain);
else if(temp==2)
fieldIV(First_stage_gain);
else
fieldIV(Output_offset);
fieldV();
}
return;
}
//关键的程序模式,设计的难点
int j,flag,count,parity;
void program()
{
int i;
unsigned int temp;
digin=0;
parity=0;
for(temp=1;temp<=5;temp++)
{
j=129;
count=0;
flag=1;
while((j&0x00ff)>128)
{
field(); //发送0位数据包,下面分别是1,2,3,4
send_bit(1);
send_bit(0);
fieldII(temp);
fieldIII();
if(temp==1)
fieldIV_program(Second_stage_gain);
else if(temp==2)
fieldIV_program(First_stage_gain);
else if(temp==3)
fieldIV_program(Output_offset);
else if(temp==4) //blow the master fuse
{ for(i=0;i<7;i++)send_bit(0);
send_bit(1);
j=0;
}
else
{
if(parity%2==1)
{for(i=0;i<5;i++)send_bit(0);
send_bit(1);
send_bit(0);
send_bit(0);
}
else {for(i=0;i<8;i++)send_bit(0);}
j=0;
}
fieldV();
delay(1280);
}
}
return;
}
//读模式
void read()
{
int i,temp;
for(temp=1;temp<=3;temp++)
{
field();
send_bit(1);
send_bit(1);
fieldII(temp);
fieldIII();
fieldIV(0);
fieldV();
for(i=0;i<8;i++)send_bit(0);
}
return;
}
//感应电流
void current()
{
field();
send_bit(0);
send_bit(0);
fieldII(1);
fieldIII();
fieldIV(1);
fieldV();
return;
}
void send_bit(unsigned int log)
{
if(log==0)
{digin=0;
delay(tws);
digin=1;
delay(tw0);
digin=0;
delay(tws);
}
if(log==1)
{digin=0;
delay(tws);
digin=1;
delay(tw1);
digin=0;
delay(tws);
}
return;
}
void delay(int num)
{while(num>0)
num--;
}
void field()
{ int i;
send_bit(1);
for(i=0;i<10;i++)send_bit(0);
send_bit(1);
return;
}
void fieldII(unsigned int stage)
{
if(stage==1)
{
send_bit(0);
send_bit(0);
}
else if(stage==2)
{
send_bit(0);
send_bit(1);
}
else if(stage==3)
{
send_bit(1);
send_bit(0);
else
{
send_bit(1); // The code is 11.
send_bit(1);
}
return;
}
void fieldIII()
{
send_bit(1);
send_bit(0); //The code is 10.
return;
}
void fieldIV(int value)
{
int i;
for(i=0;i<8;i++)
{if((value<<i&128)==0)send_bit(0);
else send_bit(1);
}
return;
}
void fieldIV_program(int value)
{
int i;
for(i=0;i<8;i++)
{j=value<<i;
if((value&128>>i)==0)send_bit(0);
else {
if(count<i)flag=1;
if(flag==1)
{send_bit(1);
parity+=1;
count=i;
for(i;i<7;i++)send_bit(0);s.
flag=0;
}
else send_bit(0);
}
}
return;
}
void fieldV()
{ int i;
send_bit(0);
for(i=0;i<10;i++)send_bit(1);
send_bit(0);
return;
}
程序的整体结构我已经标出来了,也给出了注释,比较简单,当然设计中参考了ADI的大佬,非常感谢他们,把程序调通交给测试组的小弟们,我就头昏眼花了,回家睡觉了,下午去看效果。