This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

【原创】用ADS1232做六位半万用表的输入ADC可好?

Other Parts Discussed in Thread: ADS1232, REF5040

一直很喜欢安捷伦的六位半万用表,寻思着要自己DIY一个六位半的表,如何捕获噪声中的输入信号,并进行精确测量是这个DIY的重要问题。在考虑完模拟输入的过压保护和恒流源电路设计后,就要考虑怎么做一个强大的AD输入电路了。虽然一开始打算做的是四位半万用表,但是,我们的终极目标是用高档表—— 六位半,向经典表王——安捷伦34401A学习。所以,我思前想后,LT2440无疑是最好的选择,因为其是积分型ADC,温漂够小,但是其价格昂贵,所以放弃。改而使用TI的ADS1232,同是24位ADC,但ADS1232的淘宝价格是12元,与LT2440的几十个大洋想比,还是很便宜的。并且仔细对比了两者的区别,其实相差也就是一点点指标而已。ADS1232在其DataSheet中就建议使用在称重测量等精确测量产品中,所以用来做表应该也是可以吧,哈哈。 大爱TI的高性价比器件。这样亲民的价格才能获得更多用户嘛。

ADS1232有两路输入,一路用作测量电压了, 一路测量电阻。基准源用的也是TI的,并联基准,REF5040。一直挺喜欢的一款并联基准源,温度漂移仅仅是比LM399低一点点哦。而价格却比399低多了,其综合性价比高。降低我的成本了。

好,下面就是我的设计电路——

下面是ADS1232的驱动程序,在STM32上的,因为MCU用STM32比较好些,之前考虑过MSP430,但是其主频低于STM32,因此采用STM32了,而同系列的TI的MCU是LM3S,一直没有板子,呜呜。ADS1232经过测试,可以用。Good.

#include"stm32f10x.h"

 #include"delay.h"

 #include"ads1232.h"

 

 extern unsigned char flag;

 

 

#define DOUT GPIO_Pin_0

#define SCLK GPIO_Pin_1

#define PDWN GPIO_Pin_2

#define SPEED  GPIO_Pin_3

#define GAIN0 GPIO_Pin_4

#define GAIN1 GPIO_Pin_5

#define A0    GPIO_Pin_6

#define ADPORT GPIOB

 

 

#define DOUT_H GPIO_SetBits(ADPORT,DOUT)

#define DOUT_L GPIO_ResetBits(ADPORT,DOUT)

#define SCLK_H GPIO_SetBits(ADPORT,SCLK)

#define SCLK_L GPIO_ResetBits(ADPORT,SCLK)

#define SPEED_H GPIO_SetBits(ADPORT,SPEED)

#define SPEED_L GPIO_ResetBits(ADPORT,SPEED)

#define PDWN_H GPIO_SetBits(ADPORT,PDWN)

#define PDWN_L GPIO_ResetBits(ADPORT,PDWN)

#define A0_H   GPIO_SetBits(ADPORT,A0)    //AIN 2

#define A0_L   GPIO_ResetBits(ADPORT,A0)  //AIN 1

#define GAIN_1 GPIO_ResetBits(ADPORT,GAIN0|GAIN1);

 

 

 /****************************************************

 *function name: void AD_InitIO(void)

 *description  : AD GPIO Initialization,PB0-DOUT,PB1-SCLK

 *input        : null

 *output       : null

 *return       £ºnull

 ******************************************************/

 void AD_InitIO(void)

{

   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

 

   GPIO_InitStructure.GPIO_Pin=SCLK;

   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;

   GPIO_Init(ADPORT,&GPIO_InitStructure);

}

 

 

 /****************************************************

 *function name: void DOUT_IN(void)

 *description  : ADS1232's DOUT PB0 config input

 *input        : null

 *output       : null

 *return       £ºnull

 ******************************************************/

 void DOUT_IN(void)

 {

   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

   GPIO_InitStructure.GPIO_Pin=DOUT;

   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //ÉÏÀ­ÊäÈë

   GPIO_Init(ADPORT,&GPIO_InitStructure);

 }

 

  /****************************************************

 *function name: void DOUT_OUT(void)

 *description  : ADS1232's DOUT PB0 config input

 *input        : null

 *output       : null

 *return       £ºnull

 ******************************************************/

 void DOUT_OUT(void)

 {

   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

   GPIO_InitStructure.GPIO_Pin=DOUT;

   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;

   GPIO_Init(ADPORT,&GPIO_InitStructure);

 }

 

 /****************************************************

 *function name: unsigned long AD_read(void)

 *description  : read AD data

 *input        : null

 *output       : null

 *return       £ºnull

 ******************************************************/

unsigned long AD_read(unsigned char channel)

 {

    int i=0;

 unsigned long ad_value=0;

 AD_InitIO();

 

 

 

SCLK_L;

 PDWN_L;

delay_us(20);

 if(channel == 1)

{

A0_L; //AIN1

}

else 

{

A0_H;  //AIN2

}

GAIN_1;

 SPEED_H;     //80SPS 

 PDWN_H;  

 delay_us(20);

 

//    DOUT_OUT();

//    DOUT_H; 

//    delay_us(1);

 DOUT_IN();

 while(GPIO_ReadInputDataBit(ADPORT,DOUT)==1);

//delay_ms(200);

 flag=1;

 for(i=0;i<24;i++)

 {

    ad_value=ad_value<<1;

  SCLK_H;

  delay_us(2);

  if(GPIO_ReadInputDataBit(ADPORT,DOUT)==1)

   {

   ad_value|=0x00000001;  //or  ad_value+=1;     

}

else 

 SCLK_L;

 delay_us(2);

 }

 SCLK_H;

 delay_us(2);

 SCLK_L;

 delay_ms(1);

 return ad_value;

 }


做一个万用表当然不是纯粹地选好ADC就行了,还要精心地设计好其他电路。包括电源、高压输入等。