用ADS1232做六位半万用表的输入ADC可好?
一直很喜欢安捷伦的六位半万用表,寻思着要自己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就行了,还要精心地设计好其他电路。包括电源、高压输入等。
给个赞,以资鼓励DIY精神。
谢谢O(∩_∩)O
赞一个,楼主,恒流源方案能否分享一下,邮箱是vitasnokia@126.com