矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 24507|回复: 123

Voltgen自校准电压源ADC芯片升级

[复制链接]
     
发表于 2024-1-1 12:42:13 | 显示全部楼层 |阅读模式
本帖最后由 zhengrob 于 2024-1-1 12:44 编辑

Voltgen的作者资深坛友washu在他的帖子中提到过,十几年前构思这个方案的时候,器件选型颇费周折,DAC芯片试了N个型号,MAX541/AD5541/DAC8830, 最后综合多个原因选定了AD569。而对ADC芯片,好像从一开始就只能是LTC2400而无其他选项。LTC2440性能更好但只支持差分输入,不适合;ADS1232书面指标很不错,但实际跑起来大失所望,只能降低规格使用。还有其他一众大厂的产品,要么单独测试感觉言过其实(ADS1256),要么就是不支持单周期建立等而作罢,总而言之,对这个应用而言,LTC2400不是最好的器件,但它是最适合的器件!

时至今日,我们再来审视一下,哪颗芯片更适合voltgen这个应用来替代二十多年前面世的LTC2400呢?应该是有一些的。今天要试的主角就是它,AD7175-2. 不像LTC2400和LTC2440, 在网上可以搜到多个做六位半表头的测试内容,AD7175没有的。隔壁论坛有坛友尝试去做测试,但并没有得到正向的结果。所以不亲手试一下AD7175无论如何是不知道它到底什么成色的。

如何测试?当然就在voltgen上测试。感谢PCB作者TR,在板子上预留了扩展针槽,就以这些针槽之间的尺寸为标准,画一块扩展板。硬件解决了,程序上稍微麻烦一些,因为实在不想在Atmega32上开发AD7175的测试代码了,从主板上拆掉M32,装上AD7175小板,小板与stm32F103小板直接相连,显示屏也换成了COG12864。最后这个板子的硬件连接就是这样的:



虽说现在AD7175与LTC2400都是ADI出品的,可根子上完全是2家的产品,AD7175的驱动写起来要麻烦很多。基本配置是这样的:单端输入,外接基准,外部晶体振荡器,20sps采样速度,单周期建立。AD调通了后,再把voltgen的其他代码移植过来,然后才能在这块板上真正跑起来,运行起来的情况就是这样的:

https://www.bilibili.com/video/B ... 9139ba3044c193ad67f
https://www.bilibili.com/video/B ... 9139ba3044c193ad67f

初步结论:AD7175-2比LTC2400采样要稳定太多了,在进入locked状态后,AD7175只有几个uV的跳动,大多是情况是3个uV以内,而LTC2400则经常有十几uV甚至二十几uV的跳动。它们根本就不是一个时代的产品,有这样的差异也是正常的!


评分

5

查看全部评分

     
发表于 2024-1-29 10:07:22 | 显示全部楼层
zhengrob 发表于 2024-1-29 09:53
这个稍微清楚一些,大字的是经过8个数字的窗口滤波,小字的是没加滤波的采样数字,20sps,效果还可以的: ...

20Sa/s 这效果真好

Vin 是作为电流源/微欧表返回的 DUT 上电压(以及电阻源/pA表的电流)设计的,所以你如果有兴趣可以把这些都做上,这些都未发行,但设计已公开。
屏幕截图 2024-01-29 100200.png



已有裙友画好测试 PCB,我有多的你如果不想自己画可匀你一张 或者自己画更完善也可以
未标题-3.jpg



原设计是 1mA~1A,现已测试 10A 也是没问题的:
微信图片_20240127183715.jpg


不过 10A 需要增加一个功放你看你有没有兴趣
微信图片_20240116000740.jpg
回复 支持 1 反对 0

使用道具 举报

     
 楼主| 发表于 2024-1-1 18:09:15 | 显示全部楼层
zhengrob 发表于 2024-1-1 16:33
目前只是在AD7175正常运行的情况下,把原voltgen的主要程序功能移植到了STM32,能跑起来能看一下性能表现 ...

本次测试使用的AD7175代码,@STM32F103CB:

#define ADC_CLK_0     GPIO_ResetBits(GPIOB, GPIO_Pin_9)   //PB9
#define ADC_CLK_1     GPIO_SetBits(GPIOB, GPIO_Pin_9)  

#define IO_ADC_DAT       GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) //PB6

#define ADC_SDI_1      GPIO_SetBits(GPIOB, GPIO_Pin_8)
#define ADC_SDI_0      GPIO_ResetBits(GPIOB, GPIO_Pin_8)

#define ADC_CS_1       GPIO_SetBits(GPIOB, GPIO_Pin_7)
#define ADC_CS_0       GPIO_ResetBits(GPIOB, GPIO_Pin_7)

void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  
    //对应的SCK、MOSI为AF引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
        //液晶初始化I/O口  rs/rst
        //PB10 CS
        //PB11 RES
        //PB12 RS A0
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_14|GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7|GPIO_Pin_8 | GPIO_Pin_9;       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
               
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 ;       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint32_t AD7175_RDATA(void)//
{
  uint32_t Rdata=0;
//  while(IO_ADC_DAT);
  for(uint8_t s=0;s<24;s++)
  {
   ADC_CLK_0 ;
    delay(1);
    Rdata<<=1;
    if(IO_ADC_DAT) Rdata++;
    ADC_CLK_1;
    delay(1);
  }
  return Rdata;
}

void AD7175_SPI_WB(uint8_t com)
{
  uint8_t com_temp=com;
  for(uint8_t s=0;s<8;s++)
  {
    if(com_temp&0x80)
    {
      ADC_SDI_1;
      delay(10);
    }
    else
    {
      ADC_SDI_0;
      delay(10);
    }
    ADC_CLK_0 ;
    delay(10);
    com_temp<<=1;
    ADC_CLK_1 ;
    delay(10);
  }
}


uint8_t AD7175_SPI_RB(void)
{
  uint8_t Rdata=0;
  for(uint8_t s=0;s<8;s++)
  {
   ADC_CLK_0 ;
    delay(10);
    Rdata<<=1;
    if(IO_ADC_DAT) Rdata++;
   ADC_CLK_1 ;
    delay(10);
  }
  return Rdata;
}

void AD7175_RESET(void)
{
  ADC_CLK_1 ;
  delay(0xff);
  ADC_CS_0;
  delay(10);
  for(uint8_t a=0;a<15;a++)
  {
    AD7175_SPI_WB(0xff);
  }
  ADC_CS_1;
  delay(0xff);//等待复位完成
  ADC_CS_0;
}

uint16_t AD7175_Read_Reg(uint8_t addr)
{
  uint16_t reg;
  ADC_CS_0;
  delay(10);
  AD7175_SPI_WB(addr);
  reg=AD7175_SPI_RB();
  reg<<=8;
  reg|=AD7175_SPI_RB();
  ADC_CS_1;
  delay(10);
  return reg;
}

uint16_t Get_AD7175_ID(void)
{
  uint16_t ID;
  ID=0;
  ADC_CS_0;
  delay(10);
  AD7175_SPI_WB(0x47);
  ID=AD7175_SPI_RB();
  ID<<=8;
  ID|=AD7175_SPI_RB();
  ADC_CS_1;
  delay(10);
  return ID;
}

void AD7175_INIT(void)//初始化函数
{
   ADC_CS_0;
   delay(10);

  AD7175_SPI_WB(0x06);//GPIO 配置寄存器
  AD7175_SPI_WB(0x00);//
  AD7175_SPI_WB(0x0d);//写入0x0c时,D3、D5灭
  
  AD7175_SPI_WB(0x01);//写ADC模式寄存器
  AD7175_SPI_WB(0x20);// chang to external vref, single cycle
  AD7175_SPI_WB(0x0c);//连续转换模式、外部晶振//   external crystal: 11 00
  
  AD7175_SPI_WB(0x10);//写通道映射寄存器0
  AD7175_SPI_WB(0x00);//使能通道0,禁止多通道
  AD7175_SPI_WB(0x44);//ADC+ -> AIN2;ADC- ->AIN4(AVSS)
  
  AD7175_SPI_WB(0x20);//写配置寄存器
  AD7175_SPI_WB(0x00);//// all ZERO ,all buffer closed. single-end, no buffer, ext ref
  AD7175_SPI_WB(0x00);//
  
  AD7175_SPI_WB(0x28);//写滤波器配置寄存器0
  AD7175_SPI_WB(0x05);//
  AD7175_SPI_WB(0x13);//0x07:10k   0x0A:1k  0x0f:59.95sps   0x14:5sps   0x05: 25ksps  0x13:10sps 0x12: 16.6sps
  
  AD7175_SPI_WB(0x02);//写接口模式寄存器
  AD7175_SPI_WB(0x01);//  DOUT_RESET bit is used
  AD7175_SPI_WB(0x80);//
}

uint32_t Get_Vol(void)
{
   uint32_t v=0;
  while(IO_ADC_DAT);
  v = AD7175_RDATA();
return  v;
}

void delay_us(uint32_t time)
{     
   while (time--);
}
       
/*            毫秒级延时函数        */
void delay(uint32_t time)               
{
while(time--) delay_us(10);
}

float Vtest;
uint32_t AdcValue;

int main(void)
{
    SystemInit();
    RCC_Configuration();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    GPIO_Config();

  AD7175_RESET();//复位AD7175-2                                                                                                        
  AD7175_ID=Get_AD7175_ID();//读取AD7175 ID 0X0CDX;
  AD7175_INIT();

while(1)
{
   AdcValue = Get_Vol();
   Vtest = AdcValue *5.06*2.5/16777216; // 5.06 is ADC_Ref; 2.5 is reversed-scale of scale of 3:2.
   delay(45000);
}


       






回复 支持 1 反对 0

使用道具 举报

     
 楼主| 发表于 2024-1-1 12:46:42 | 显示全部楼层
图片传不上去啊。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 13:10:16 | 显示全部楼层
zhengrob 发表于 2024-1-1 12:46
图片传不上去啊。

图片传不上,上视频吧,板子是这样连接的:

https://www.bilibili.com/video/B ... 9139ba3044c193ad67f
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 13:10:53 | 显示全部楼层
楼主给力。
虽然对此产品有些兴趣,
但并不想在AVR上复刻,
听到楼主替换了ADC,
尤其是跑在了STM32上,
实在必须点一个大大的赞。
希望楼主能够分享。
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 13:51:31 | 显示全部楼层
AD7175 肯定是好东西,俺手里还剩几片一直都没舍得用呢。如果想要更好的性能,还可以考虑直接升级成 AD7177。
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 14:45:09 来自手机 | 显示全部楼层
AD 7175比LTC2400便宜很多。望能分享。
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 15:23:19 | 显示全部楼层
xu 发表于 2024-1-1 14:45
AD 7175比LTC2400便宜很多。望能分享。

时过境迁,现在是 7175 比 2400 便宜了
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 15:27:30 | 显示全部楼层
AD7175-2比LTC2400采样要稳定太多了,在进入locked状态后,AD7175只有几个uV的跳动,大多是情况是3个uV以内,而LTC2400则经常有十几uV甚至二十几uV的跳动。它们根本就不是一个时代的产品,有这样的差异也是正常的!

+++++++++++++++++++++++++

我记得 15 年发行套件的时候已经有 7175 了,但当时比较贵且难以买到(不像现在立创也就几十块钱),而且也没法申请到样片:这个之前也提到过,我选型的基础是能申请到样片

从楼主的测试看来,更换 ADC 为 7175 势在必行,更小的跳动意味着可不用原来设计的滤波长度,从而更快调整(到预期值)。此外,Voltgen 还有其它进一步的设计,比如电流源/微欧表、电阻源等,更快的 ADC 可加快这些跟进设计的表头反应速度,提高可用性。




回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 16:33:54 | 显示全部楼层
abbey_tom 发表于 2024-1-1 13:10
楼主给力。
虽然对此产品有些兴趣,
但并不想在AVR上复刻,

目前只是在AD7175正常运行的情况下,把原voltgen的主要程序功能移植到了STM32,能跑起来能看一下性能表现。但是通讯和校准等接口部分程序还没移植过来,需要些时间。这些程序是必要的,因为移植过来后原来washu的那几个上位机仍然可以用。到时候会分享给坛友的。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 16:44:15 | 显示全部楼层
本帖最后由 zhengrob 于 2024-1-1 16:45 编辑
washu 发表于 2024-1-1 15:27
AD7175-2比LTC2400采样要稳定太多了,在进入locked状态后,AD7175只有几个uV的跳动,大多是情况是3个uV以内 ...


是的,我在调试程序时就发现了,改为AD7175后用不着32个数字的平均滤波了,可能8个最多16个就足够了。改变设定后,最多3秒钟实际采样就跟踪到了设定值,差别也就在几个uV以内了。

单端输入并不是AD7175的最佳工作方式,手册中明确指出这样的使用方式比差分式性能要低些。尽管这样仍然能看到对LTC2400的性能碾压,看来是有必要做全面的升级并在此基础之上开发更新的应用了。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 18:30:32 | 显示全部楼层
zhengrob 发表于 2024-1-1 18:09
本次测试使用的AD7175代码,@STM32F103CB:

#define ADC_CLK_0     GPIO_ResetBits(GPIOB, GPIO_Pin_9 ...

终于能上传图片了:

新组合

新组合
小板3D.jpg
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 18:40:11 | 显示全部楼层
scoopydoo 发表于 2024-1-1 13:51
AD7175 肯定是好东西,俺手里还剩几片一直都没舍得用呢。如果想要更好的性能,还可以考虑直接升级成 AD7177 ...

对voltgen,可能AD7175真的就够用了。 AD7177毕竟是有人拿来做8位半的东西 。得空也不妨试一下,我手上有3片。
回复 支持 反对

使用道具 举报

     
发表于 2024-1-1 19:37:05 | 显示全部楼层
本帖最后由 jforu 于 2024-1-1 19:38 编辑

手上有2块2400, 昨天刚画完去加力创,因为手上的元件大多是DIP的,因为原来LT的SOP运放都差于DIP封闭(CS8不如CN8指标好).

因为时间有点紧,上传时没细改.基本按washu的PCB(照片)加washu的电路图. 只修改部分元件(运放,光耦)的封装.

3D_PCB1_2023-12-31.png
3D_PCB1_2023-12-31B.png
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-1-1 20:50:28 | 显示全部楼层
zhengrob 发表于 2024-1-1 16:44
是的,我在调试程序时就发现了,改为AD7175后用不着32个数字的平均滤波了,可能8个最多16个就足够了。 ...

缓冲滤波数组长度由32降为8, 锁定更快了:

https://www.bilibili.com/video/B ... 9139ba3044c193ad67f
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 15:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表