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.

[参考译文] ADS1220:ADS1220问题:PGA 死机?

Guru**** 2390755 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/800757/ads1220-ads1220-issue-pga-is-dead

器件型号:ADS1220

您好!

请告诉我、问题可能出在哪。
如果激活 PGA、我在获取数据时遇到问题。
默认情况下、我只更改增益。

写入和读取寄存器0-3的值。
我通过分压器将电池电压连接到输入、关于
20.6mV、但仅当 PGA 旁路打开时才会获得该值。
值20.65335、20.65421、20.65333、20.65112等

如果 PGA 旁路关闭并将 PGA 设置为任何增益、我将得到非常小的浮点值(0.00012、0.00015、-0.00010、-0.00013等)
可能我做了一些错误的事情?

在下面、我附上了原理图、逻辑器屏幕截图、Arduino 代码和库
我使用的是什么。

代码

#include "ADS1220.h"
ADS1220 ADC;
#define PGA 1
#define VREF 2.048
#define VFSR Vref/PGA
#define full_scale (((long int) 1<<23)-1


) void setup (){
Serial.begin(9600);
adc.begin(9、8);
adc.setGain(PGA);
adc.setConversionMode(1); //连续模式
adc.setMultiplexer(0X00);
adc.setPGAbypass(true);// PGA 关闭

uint8_t buff = 0;
buff = adc.readRegister (0);
Serial.print ("REG0 =");
Serial.println (buff、bin);
buff = adc.readRegister (1);
Serial.print ("REG1 =");
Serial.println (buff、bin);
buff = adc.readRegister (2);
serial.print ("REG2 =");
serial.println (buff、bin);
buff = adc.readRegister (3);
serial.print ("REG3 =");
serial.println (buff、bin);
}

void loop (){
char outstr[10];

if (adc.isDataReady ()){
long test = adc.readadc ();
float A = convertToMilliV (测试);
dtostrf (a、10、5、outstr);
serial.println (outstr);
}
delay (300);
}

float convertToMilliV (int32_t i32data)
{
return (float)(((i32data * VFSR * 1000)/ full_scale);
}

CPP 文件 

#include "ADS1220.h" #include "Arduino .h" #include "spi.h" ADS1220:::ADS1220 (){ } void ADS1220:::writeRegister (uint8_t address、uint8_t value){ digitalWrite (ADS1220_CS_PIN、low); spi.transfer (CMD_WREG|(address<< 2字节)设置? spi.transfer (value); startSync ();//发送启动/同步以实现连续转换模式 delayMicroseconds (1);//延迟最小 td (SCCS) digitalWrite (ADS1220_CS_PIN、高电平); } uint8_t ADS1220::readRegister (uint8_t address){ digitalWrite (ADS1220_CS_PIN 、高电平);}uint8_transfer (nature_mb)<?/<spi_transfer? uint8_t data = spi.transfer (spi_master_dummy); digitalWrite (ADS1220_CS_PIN、HIGH); return data; } void ADS1220::begin (uint8_t cs_pin、uint8_t drdy){ //设置引脚上 的 ADS1220_CS_PIN = cs_pin; ADS1220 = cs_pin;ADS1220_pin =输出 = SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE1);;dry_spi_output= SPI (dry_spi_port = dry_port)/配置引脚0) //将 DRDY 配置为输入(mfg 希望我们使用中断) pinMode (ADS1220_DRDY_PIN、input); digitalWrite (ADS1220_CS_PIN、low);//将 CS 设置为低 电平 delayMicroseconds (100);//等待至少 td (CSSC) reset ();//发送 RESET 命令 delayMicroseconds (100); //延迟最小值50us + 32 * tclk //完整性检查回读(可选) startSync ();//发送启动/同步以实现连续转换模式 delayMicroseconds (1);//延迟最小值 td (SCCS) digitalWrite (ADS1220_CS_PIN、HIGH);//将 CS 清除为高 电平} bdatole={=digature=dam.(ADS1220_d) 返回 false; } 返回 true; } long ADS1220::readadc(){ digitalWrite (ADS1220_CS_PIN,LOW);//采用 CS low delayMicroseconds (1);// td (CSSC) long adcVal = SPI.transfer (SPI_MASTER_Dummy); adcVal =(adcVal <8)| adcVal < 8);adcVal =(SPI_dum_adcVal (SP_adcVal = adcVal <8);adcVal (spi_adcVal = adcVal <8 );(spi_adcstu.adcVal = adcVal =(adcVal >> 8); delayMicroseconds (1);// TD (CSSC) digitalWrite 的最小值(ADS1220_CS_PIN、高电平); return adcVal; } 字节* ADS1220::::readadc_Array (1){ digitalWrite (ADS1220_CS_PIN、低电 平);//采用低电平(3) ;dCSS+静态数组 (3);//采用低电平(3);t3 (3)(3)(3)(3)(最小值) dataarray[x]= spi.transfer (spi_master_dummy); } delayMicroseconds (1);// TD (CSSC) digitalWrite (ADS1220_CS_PIN、HIGH)的最小值; return dataarray; } //单次转换读取模式 long ADS1220:::readadc_Single (){ digitalWrite (ADS1220_CS_CS_PIN、high);digitaldeltn (ADS1220c (ADS1220_cs (ADS1220_Cs);d_delimumt/(nh)= d/ rand.deltn (low);d/(dsps (dsps)(d_delt_rand/del //等待 DRDY 停止运行 //不是一件好事 //代码可能卡在此处 //以后需要改进 } long adcVal = spi.transfer (spi_master_dummy); adcital=(adcVal << 8)| spi.transfer (spi_master_dummy); adcVal =(adcVal << 8)|(adcVal << 8)| spi.transfer (spi_master_dum_dumb); adcVal =(adcVal <8 );adcVal =(adcVal =(adcDc)(adcDc)(degin)( adcDc)(dc)( degreb) 1)(adcD20b); adc (adcDc (d_degreb)(d_mudeltb)( //将 CS 置于低 电平 delayMicroseconds (1);// TD (CSSC) SPI.transfer ( 0x08)的最小值; while (digitalRead (ADS1220_DRDY_PIN)= HIGH) { //等待 DRDY 停止运行 //不是一件好事 //代码可能卡在此处 //需要改进后 的} 静态字节数据数组[3]; for (int x=0;x<3;x++) { dataarray[x]= spi.transfer (spi_master_dummy); } delayMicroseconds (1);// TD (CSSC) digitalWrite (ADS1220_CS_PIN、HIGH)的最小值; return dataarray; } void ADS1220:::sendCommand (uint8_t 命令){ //遵循 Prototral 的代码、不确定具体情况。 digitalWrite (ADS1220_CS_PIN、低电平); delay (2); digitalWrite (ADS1220_CS_PIN、高电平); 延迟(2); digitalWrite (ADS1220_CS_PIN、LOW); 延迟(2); SPI.transfer (command); delay (2); digitalWrite (ADS1220_CS_PIN、HIGH); } void ADS1220:::writeRegisterMasked (uint8_t value、uint8_t mask、uint8_t address){ //使用掩码将值写入寄存 器、以保持//寄存器的其余部分不变。 这不会改变该值、因此应提供 //将其转移到适当的位置。 //立即读取寄存器中的内容 uint8_t register_contents = readRegister (address); //翻转掩码以使掩码为零,我们将在此处放置数据,并将零输出到// 寄存器内容的一部分 register_contents = register_contents &~遮罩; //或要写入的值 register_contents = register_contents | value; //将其写回 writeRegister (address、register_contents); } void ADS1220:::setMultiplexer (uint8_t value){ //设置多路复用 器| value | AINp | AINn | |-- |---|--- | | 0x00 | AIN0 | AIN1 | | 0x01 | AIN0 | AIN2 | | 0x02 | AIN0 | AIN3 | || 0x03 | AIN1 | AIN2 | | 0x04 | AIN1 | AIN3 | | 0x05 | AIN2 | AIN3 | | 0x06 | AIN1 | AIN0 | AIN0 | AIN0 | AIN0 | AIN0 | AIN0 | AIN0 | AIN0 | AIN | 0x07 | AIN3 | AIN2 | | 0x08 | AIN0 | AVSS | | 0x09 | AIN1 | AVSS | | 0x0A | AIN2 | AVSS | | 0x0B | AIN3 | AVSS | | 0x0C | REF/4 MON | | 0x0D | APWR/4 MON | | 0x0E | 短接| */ //确保值处于有效范围内。 否则、 如果(值> 0x0E){、则设为0x00 值= 0x00; } 值=值<< 4;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_MUX、CONFIG_REG0_ADDRESS); } void ADS1220::setGain (uint8_t 增益){ //设置 ADC 增益。 可能的值包括1、2、4、8、16、 32、64、128。 */ uint8_t value = 0x00; switch (gain){ 案例1: 值= 0x00; 中断; 案例2: 值= 0x01; 中断; 案例4: 值= 0x02; 中断; 案例8: 值= 0x03; 中断; 案例16: 值= 0x04; 中断; 案例32: 值= 0x05; 中断; 情况64: 值= 0x06; 中断; 情况128: 值= 0x07; 中断; 默认值: 值= 0x00; break; } value = value << 1;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_GAIN、CONFIG_REG0_ADDRESS); } void ADS1220:::setPGAbbnes (bool value){ //如果为 true 则绕过 PGA。 PGA 只能针对增益1、2、4禁用。 // writeRegisterMasked (value、REG_MASK_PGA_BYPASS、CONFIG_REG0_ADDRESS); } void ADS1220:::setDataRate (uint8_t value){ //设置 ADC 的数据速率。 有关数据速率、请参阅数据表中的表18 不同的工作模式。 // //确保该值在有效范围内。 否则、 如果(值> 0x07){、则设为0x00 值= 0x00; } 值=值<< 5;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_datarate、CONFIG_REG1_ADDRESS); } void ADS1220::setOpMode (uint8_t value){ //设置 ADC 工作模式: 0 -正常模式 1 -占空比模式 2 - Turbo 模式 */ //确保值在有效范围内。 否则、 如果(值> 0x02){、则设为0x00 值= 0x00; } 值=值<< 3;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_OP_MODE、CONFIG_REG1_ADDRESS); } void ADS1220::setConversionMode (uint8_t value){ //设置 ADC 转换模式。 0 -单次触发模式 1 -连续转换模式 */ /确保该值处于有效范围内。 否则、 如果(值> 0x01){、则设为0x00 值= 0x00; } 值=值<< 2;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_CONV_MODE、CONFIG_REG1_ADDRESS); } void ADS1220::setTemperatureMode (uint8_t value){ //控制内部温度传感器的状态。 0 -禁用温度传感器 1 -启用温度传感器 */ //确保该值处于有效范围内。 否则、 如果(值> 0x01){、则设为0x00 值= 0x00; } 值=值<< 1;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_TEMP_MODE、CONFIG_REG1_ADDRESS); } void ADS1220::setBurnoutCurrentSources (bool value){ //打开或关闭10uA 烧毁电流源。 // writeRegisterMasked (value、REG_MASK_Burrnout_Sources、CONFIG_REG1_ADDRESS); } void ADS1220:::setVoltageRef (uint8_t value){ //设置 ADC 使用的电压基准。 0 -内部2.048V 1 - REFP0和 REFN0输入端的外部 2 - AIN0/REFP1和 AIN3/REFN1输入上的外部 3 -使用模拟电源作为参考 */ /确保该值处于有效范围内。 否则、 如果(值> 0x03){、则设为0x00 值= 0x00; } 值=值<< 6;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_VOLTGE_REF、CONFIG_REG2_ADDRESS); } void ADS1220::setFIR (uint8_t value){ //控制 ADC 上的 FIR 滤波器。 0 -无50Hz 或60Hz 抑制 1 -同时抑制50Hz 和60Hz 2 - 50Hz 抑制 3 - 60Hz 抑制 */ //确保该值处于有效范围内。 否则、 如果(值> 0x03){、则设为0x00 值= 0x00; } 值=值<< 4;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_FIR_CONF、CONFIG_REG2_ADDRESS); } void ADS1220::setPowerSwitch (uint8_t value){ //配置 AIN3/REFN1和 AVSS 之间低侧开关的行为。 0 -始终打开 1 -发送 START/SYNC 命令后自动关闭、并在发送后打开 POWERDOWN 命令有问题。 // //确保该值在有效范围内。 否则、 如果(值> 0x01){、则设为0x00 值= 0x00; } 值=值<< 3;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_PWR_switch、CONFIG_REG2_ADDRESS); } void ADS1220::setIDACcurrent (uint8_t value){ //设置 IDAC1和 IDAC2激励源的电流。 0 -关闭 1 - 10uA 2 - 50uA 3 - 100uA 4-250 uA 5 - 500uA 6 - 1000uA 7 - 1500uA */ //确保该值在有效范围内。 否则、 如果(值> 0x07){、则设为0x00 值= 0x00; } writeRegisterMasked (value、REG_MASK_IDAC_CURRENT、CONFIG_REG2_ADDRESS); } void ADS1220::setIDAC1路由(uint8_t value){ //选择 IDAC1路由到的位置。 0 -禁用 1 - AIN0/REFP1 2 - AIN1 3 - AIN2 4 - AIN3/REFN1 5 - REFP0 6 - REFN0 */ //确保该值在有效范围内。 否则、 如果(值> 0x06){、则设为0x00 值= 0x00; } 值=值<< 5;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_IDAC1_routing、CONFIG_REG3_address); } void ADS1220::setIDAC2routing (uint8_t value){ //选择 IDAC2路由到的位置。 0 -禁用 1 - AIN0/REFP1 2 - AIN1 3 - AIN2 4 - AIN3/REFN1 5 - REFP0 6 - REFN0 */ //确保该值在有效范围内。 否则、 如果(值> 0x06){、则设为0x00 值= 0x00; } 值=值<< 2;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_IDAC2_routing、CONFIG_REG3_address); } void ADS1220::setDRDYMODE (uint8_t value){ //控制 DOUT/DRDY 引脚在新数据就绪时的行为。 0 -仅使用专用 DRDY 引脚 1 - DOUT/ DRDY 和 DRDY 指示的数据就绪 */ //确保该值处于有效范围内。 否则、 如果(值> 0x01){、则设为0x00 值= 0x00; } 值=值<< 1;//移位以匹配掩码 writeRegisterMasked (value、REG_MASK_DRDY_MODE、CONFIG_REG3_ADDRESS); } void ADS1220:::reset (){ sendCommand (CMD_RESET); } void ADS1220:startSync (){ sendCommand ( ADS1220):void RDn (void RDn);void ADSRDn (void Data (void)(void:void RDn )(void CMDCMDCMDn):void (void);void (void DCMDCMDCMDn) digitalWrite (ADS1220_CS_PIN、低电平); //发送命令字节 SendByte (CMD_RREG |(((StartAddress<<2)& 0x0c)|((NumRegs-1)&0x03))); //获取寄存器内容 对于(i=0;i< NumRegs;i++) { *pData++= ReceiveByte(); } digitalWrite (ADS1220_CS_PIN、高电平); return; } void ADS1220::SendByte (unsigned char 值) { spi.transfer (value); } unsigned int ADS1220:::ReceiveByte (void) { unsigned int readvalue; readvalue = spi.transfer (0x00); return readvalue; }

头文件

#ifndef ADS1220_h
#define ADS1220_h

#include "Arduino .h"

#define SPI_MASTER_Dummy_0xFF
// ADC 的命令
#define CMD_RESET 0x07
#define CMD_START_SYNC 0x08
#define CMD_PWRDWN 0x03
#define CMD_RDATA 0x1f #define CMD_RREG_CONFIG






0x20寄存器#define 0x02 0xGREGADDR_CONFIG 0x20 #define 0xGATE 0x20寄存器#define CMD_REGADDRESD/ CONFIG_CONFIG 0x02 #define 0xGTRIG_CONFIG 0x20 #define 0xGTRIG_CONFIG 0x0 0xG3 0x03 #define 0x03 #define


用于设置
//寄存器0
#define REG_MASK_MUX 0xF0
#define REG_MASK_GAIN 0x0E
#define REG_MASK_PGA_BYPASS 0x01

//寄存器1
#define REG_MASK_DATARATE 0xE0
#define REG_MASK_OP_MODE 0x18
#define REG_MASK_CONV_MODE 0x04 #define REG_PWR_CONF_MASK_MODE0x07

#define 0xREG_CONF_MASK_MODE/ CONF_MASK_#REF_MASK_#REF_MASK_#REF_MASK_MODE/ CONF_MASK




0x07 0x30 #REF_MASK_MODE/ CONF_MASK 0x07_MASK 0x07_MASK #REF_MASK_MODE/ CONF_MASK
0x0 #define 0x07_MASK #


#define REG_MASK_IDAC1_ENDRESS 0xE0
#define REG_MASK_IDAC2_ENDR1C
#define REG_MASK_DRDY_MODE 0x02
#define REG_MASK_RESERVED 0x01

CLASS ADS1220{
public:
ADS1220();
uint8_t ADS1220_CS_PIN;
uint8_t ADS1220_DRDY_PIN;
void writeRegister (uint8_t address、uint8_t value);
uint8_t readRegister (uint8_t 地址);
void begin (uint8_t cs_pin、uint8_t drdy_pin);
bool isDataReady (void);
long readadc (void);
字节* readadc_Array (void);
long readadc_Single (void);
字节* readadc_SingleArray (void);
void sendCommand (uint8_t 命令);
void reset (void);
void startSync (void);
void powdown (void);
void RDATA (void);
void writeRegisterMasked (uint8_t value、uint8_t mask、uint8_t address);
void setMultiplexer (uint8_t value);
void setGain (uint8_t 增益);
void setPGAb旁 路(bool 值);
void setDataRate (uint8_t value);
void setOpMode (uint8_t value);
void setConversionMode (uint8_t value);
void setTemperatureMode (uint8_t 值);
void setBurnoutCurrentSources (bool 值);
void setVoltageRef (uint8_t value);
void setFIR (uint8_t value);
void setPowerSwitch (uint8_t value);
void setIDACcurrent (uint8_t value);
void setIDAC1路由(uint8_t 值);
void setIDAC2routing(uint8_t value);
void setDRDYMODE (uint8_t value);

void SendByte (unsigned char cData); //向 ADS1220发送字节
unsigned int ReceiveByte (void); //从 ADS1220
int GetChannel (void)接收字节;
void ReadRegister (int StartAddress、int NumRegs、unsigned * pData);
};
#endif

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Oleg、

    欢迎来到 E2E 论坛! 您看到的问题与 PGA 启用时的共模输入范围有关。 PGA 类似于仪表放大器、放大器的输出无法将输出驱动到电源轨。 这在第21页的8.3.2节开始的数据表中进行了讨论。 您需要特别注意8.3.2.1、其中详细说明了共模电压要求、并且必须满足方程式13至15。

    使用单极模拟电源(+5V/GND)时、唯一可以进行接地基准测量的方法是禁用并绕过 PGA。 如果您希望在启用 PGA 的同时进行接地参考测量、则需要使用双极电源(+/-2.5V)。

    此致、
    Bob B
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:

    感谢您的解释。 现在很明显,我的主要错误是我没有仔细阅读数据表 )

    如果我正确地理解了双极电源、我需要将负输入连接到接地。

    是这样吗? 还是可选?

    例如:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Oleg、

    如果为模拟电源使用双极电源(AVDD=+2.5V、AVSS=-2.5V)、则需要将其中一个输入连接到模拟接地、如图所示。 单端多路复用器配置仅在单极模拟电源下有用、因为测量是以 AVSS 为基准(例如、AINp = AIN0、AINn = AVSS)。 因此、您需要使用2个输入(例如 AINp = AIN0、AINn = AIN1)进行差分测量、其中一个输入连接到模拟接地。

    此致、
    Bob B
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bob、非常感谢!