Jump to content
artos5

ADS1220 STM32F100 не считываются данные с АЦП

Recommended Posts

Приветствую всех на этом форуме!

Есть необходимость измерять сигнал при помощи данного АЦП. С помощью этого АЦП можно измерять 4 аналоговых не дифференциальных сигнала . Схема следующая:

Schematic_Temp_opto_sens_V2_20190817124112.pdf

Картинками с более низким разрешением:

Скрытый текст

 

f581ff30-7993-4e16-b313-f8eb18a6140b.png.4d40f1ac5f1439284f28be0a0384a401.pnge176fc98-a09e-4489-87ae-60f41656f80b.png.21860c52aa089f11cfb43e4306b6b0f7.pngca6a98a5-549b-49e1-9aea-dfd53e214878.png.1e0b0ee109409d9c89d067f40ecc021f.png

 

 

 

библиотеку за основу взял эту:

https://github.com/nsaspook/nidaq700/blob/master/supermoon/example/ADS1220.c

Путем незначительного допиливания, получилась такая библиотека:

 

Поправил только эти функции:

void ADS1220SendByte(unsigned char Byte)
{
unsigned char Result = 0x01, i=0, flg=0;
MOSI_LO;
Delay_us(1);
for(i=0;i<8;i++)
  {  

     SCK_LO; //ADC_CLK=0
     Delay_us(4);
     if (flg) MOSI_LO;
     Delay_us(1);
     SCK_HI; //ADC_CLK=1
     Delay_us(1);
     if (Byte&Result){ MOSI_HI; flg=1; }
	 else             MOSI_LO;
     Delay_us(4);
     Result<<=1;
  }
SCK_LO; //ADC_CLK=0
}

unsigned char ADS1220ReceiveByte(void)
{
   unsigned char Result = 0, i=0;
   
  for(i=0;i<8;i++)
  {  
	     Result<<=1;
     SCK_LO; //ADC_CLK=0
     Delay_us(5);

     //Delay_us(5);
     SCK_HI; //ADC_CLK=1
     Delay_us(3);
     if (MISO) Result++;
     Delay_us(2);

  }
  SCK_LO; //ADC_CLK=0
	return Result;
}

И добавил эту функцию:

void ADS1220Config_MUX_GAIN(uint8_t mux, uint8_t gain)
{
	unsigned Temp;

	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);

	// clear prev value;
   	Temp &= 0x0f;
   	Temp |= gain;
   	Temp |= mux;

   	// write the register value containing the new value back to the ADS
   	ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &Temp);

	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);

	// clear prev DataRate code;
	Temp &= 0x1f;
	Temp |= (ADS1220_DR_600 + ADS1220_CC);		// Set default start mode to 600sps and continuous conversions

	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &Temp);


}
Скрытый текст

//ADS1220.c

#include "main.h"

#define data1 3
#define data2 4
#define sck1 1
#define sck2 2
#define cs 0

#define MCP3551_PORT GPIOB->ODR

#define MCP3551_PIN  GPIOB->IDR

#define MOSI_HI  GPIOB->ODR|=(1<<1)
#define MOSI_LO  GPIOB->ODR&=~(1<<1)
#define MISO  GPIOB->IDR&(1<<3)
#define DRDY  GPIOB->IDR&(1<<2)

#define SCK_HI  GPIOB->ODR|=(1<<4)
#define SCK_LO  GPIOB->ODR&=~(1<<4)
#define CS_HI  GPIOB->ODR|=(1<<0)
#define CS_LO  GPIOB->ODR&=~(1<<0)

#define delay HAL_Delay(1)
#define RESAMPL 20

#include "ADS1220.h"

/* This is MSP430 Code */

void ADS1220Init(void)
{
     

}

// ADS1220 Initial Configuration
void ADS1220Config(void)
{
	unsigned Temp;
	
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
   
	// clear prev value;
   	Temp &= 0x0f;
   	Temp |= ADS1220_MUX_0_G;
   
   	// write the register value containing the new value back to the ADS
   	ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &Temp);
   
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
   
	// clear prev DataRate code;
	Temp &= 0x1f;
	Temp |= (ADS1220_DR_600 + ADS1220_CC);		// Set default start mode to 600sps and continuous conversions
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	
}

void ADS1220Config_MUX_GAIN(uint8_t mux, uint8_t gain)
{
	unsigned Temp;

	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);

	// clear prev value;
   	Temp &= 0x0f;
   	Temp |= gain;
   	Temp |= mux;

   	// write the register value containing the new value back to the ADS
   	ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &Temp);

	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);

	// clear prev DataRate code;
	Temp &= 0x1f;
	Temp |= (ADS1220_DR_600 + ADS1220_CC);		// Set default start mode to 600sps and continuous conversions

	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &Temp);


}
/*  Polling Function */
int ADS1220WaitForDataReady(int Timeout)
{
   if (Timeout > 0)
   {
      // wait for /DRDY = 1
      while (!(DRDY) && (Timeout-- >= 0))
         ;
      // wait for /DRDY = 0
      while ( (DRDY) && (Timeout-- >= 0))
         ;
      if (Timeout < 0)
         return 0; //ADS1220_TIMEOUT_WARNING;
   }
   else
   {
      // wait for /DRDY = 1
      while (!(DRDY))
         ;
      // wait for /DRDY = 0
      while ( (DRDY))
         ;
   }
   return ADS1220_NO_ERROR;
}

__STATIC_INLINE void Delay_us (uint32_t __IO us) //Функция задержки в микросекундах us
{
us *=(SystemCoreClock/1000000)/5;
	while(us--);
}

void ADS1220AssertCS( int fAssert)
{
   if (fAssert)
   {
		CS_LO; 
		Delay_us(50);
   }
   else
   {
	   Delay_us(50);
		CS_HI;
   }
}





void ADS1220SendByte(unsigned char Byte)
{
unsigned char Result = 0x01, i=0, flg=0;
MOSI_LO;
Delay_us(1);
for(i=0;i<8;i++)
  {  

     SCK_LO; //ADC_CLK=0
     Delay_us(4);
     if (flg) MOSI_LO;
     Delay_us(1);
     SCK_HI; //ADC_CLK=1
     Delay_us(1);
     if (Byte&Result){ MOSI_HI; flg=1; }
	 else             MOSI_LO;
     Delay_us(4);
     Result<<=1;
  }
SCK_LO; //ADC_CLK=0
}

unsigned char ADS1220ReceiveByte(void)
{
   unsigned char Result = 0, i=0;
   
  for(i=0;i<8;i++)
  {  
	     Result<<=1;
     SCK_LO; //ADC_CLK=0
     Delay_us(5);

     //Delay_us(5);
     SCK_HI; //ADC_CLK=1
     Delay_us(3);
     if (MISO) Result++;
     Delay_us(2);

  }
  SCK_LO; //ADC_CLK=0
	return Result;
}
/*
******************************************************************************
 higher level functions
*/
long ADS1220ReadData(void)
{
   long Data;
   
      
   // assert CS to start transfer
   ADS1220AssertCS(1);

   // send the command byte
   ADS1220SendByte(ADS1220_CMD_RDATA);
      
   // get the conversion result
#ifdef ADS1120
   Data = ADS1220ReceiveByte();
   Data = (Data << 8) | ADS1220ReceiveByte();
   //Data = (Data << 8) | ADS1220ReceiveByte();

   // sign extend data
   if (Data & 0x8000)
      Data |= 0xffff0000;
#else
   Data = ADS1220ReceiveByte();
   Data = (Data << 8) | ADS1220ReceiveByte();
   Data = (Data << 8) | ADS1220ReceiveByte();

   // sign extend data
   if (Data & 0x800000)
      Data |= 0xff000000;
   
#endif
   // de-assert CS
   ADS1220AssertCS(0);
   return Data;
}

void ADS1220ReadRegister(int StartAddress, int NumRegs, unsigned * pData)
{
   int i;

	// assert CS to start transfer
	ADS1220AssertCS(1);
   
	// send the command byte
	ADS1220SendByte(ADS1220_CMD_RREG | (((StartAddress<<2) & 0x0c) |((NumRegs-1)&0x03)));
   
	// get the register content
	for (i=0; i< NumRegs; i++)
	{
		*pData++ = ADS1220ReceiveByte();
	}
   
	// de-assert CS
	ADS1220AssertCS(0);
	
	return;
}

void ADS1220WriteRegister(int StartAddress, int NumRegs, unsigned * pData)
{
	int i;
   
	// assert CS to start transfer
	ADS1220AssertCS(1);
   
	// send the command byte
	ADS1220SendByte(ADS1220_CMD_WREG | (((StartAddress<<2) & 0x0c) |((NumRegs-1)&0x03)));
   
    // send the data bytes
	for (i=0; i< NumRegs; i++)
	{
		ADS1220SendByte(*pData++);
	}
   
	// de-assert CS
	ADS1220AssertCS(0);
   
	return;
}

void ADS1220SendResetCommand(void)
{
	// assert CS to start transfer
	ADS1220AssertCS(1);
   
	// send the command byte
	ADS1220SendByte(ADS1220_CMD_RESET);
   
	// de-assert CS
	ADS1220AssertCS(0);
   
	return;
}

void ADS1220SendStartCommand(void)
{
	// assert CS to start transfer
	ADS1220AssertCS(1);
   
	// send the command byte
	ADS1220SendByte(ADS1220_CMD_SYNC);
   
	// de-assert CS
	ADS1220AssertCS(0);
     
	return;
}

void ADS1220SendShutdownCommand(void)
{
	// assert CS to start transfer
	ADS1220AssertCS(1);
   
	// send the command byte
	ADS1220SendByte(ADS1220_CMD_SHUTDOWN);
   
	// de-assert CS
	ADS1220AssertCS(0);
     
	return;
}

/*
******************************************************************************
register set value commands
*/

int ADS1220SetChannel(int Mux)
{
	unsigned int cMux = Mux;	   
   // write the register value containing the new value back to the ADS
   ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &cMux);
   
   return ADS1220_NO_ERROR;
}

int ADS1220SetGain(int Gain)
{
	unsigned int cGain = Gain;   
	// write the register value containing the new code back to the ADS
	ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &cGain);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetPGABypass(int Bypass)
{
	unsigned int cBypass = Bypass;
	// write the register value containing the new code back to the ADS
	ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &cBypass);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetDataRate(int DataRate)
{
	unsigned int cDataRate = DataRate;  
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &cDataRate);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetClockMode(int ClockMode)
{
	unsigned int cClockMode = ClockMode;
   
	// write the register value containing the value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &cClockMode);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetPowerDown(int PowerDown)
{
	unsigned int cPowerDown = PowerDown;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &cPowerDown);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetTemperatureMode(int TempMode)
{
	unsigned int cTempMode = TempMode;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &cTempMode);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetBurnOutSource(int BurnOut)
{
	unsigned int cBurnOut = BurnOut;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &cBurnOut);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetVoltageReference(int VoltageRef)
{
	unsigned int cVoltageRef = VoltageRef;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_2_REGISTER, 0x01, &cVoltageRef);
	
	return ADS1220_NO_ERROR;
}

int ADS1220Set50_60Rejection(int Rejection)
{
	unsigned int cRejection = Rejection;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_2_REGISTER, 0x01, &cRejection);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetLowSidePowerSwitch(int PowerSwitch)
{
	unsigned int cPowerSwitch = PowerSwitch;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_2_REGISTER, 0x01, &cPowerSwitch);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetCurrentDACOutput(int CurrentOutput)
{
	unsigned int cCurrentOutput = CurrentOutput;
   
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_2_REGISTER, 0x01, &cCurrentOutput);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetIDACRouting(int IDACRoute)
{
	unsigned int cIDACRoute = IDACRoute;
	
	// write the register value containing the new value back to the ADS
	ADS1220WriteRegister(ADS1220_3_REGISTER, 0x01, &cIDACRoute);
	
	return ADS1220_NO_ERROR;
}

int ADS1220SetDRDYMode(int DRDYMode)
{
	unsigned int cDRDYMode = DRDYMode;
   
	// write the register value containing the new gain code back to the ADS
	ADS1220WriteRegister(ADS1220_3_REGISTER, 0x01, &cDRDYMode);
	
	return ADS1220_NO_ERROR;
}

/*
******************************************************************************
register get value commands
*/

int ADS1220GetChannel(void)
{
	unsigned Temp;
	
	//Parse Mux data from register
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return (Temp >>4);
}

int ADS1220GetGain(void)
{
	unsigned Temp;
	
	//Parse Gain data from register
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x0e) >>1);
}

int ADS1220GetPGABypass(void)
{
	unsigned Temp;
	
	//Parse Bypass data from register
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return (Temp & 0x01);
}

int ADS1220GetDataRate(void)
{
	unsigned Temp;
	
	//Parse DataRate data from register
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( Temp >>5 );
}

int ADS1220GetClockMode(void)
{
	unsigned Temp;
	
	//Parse ClockMode data from register
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x18) >>3 );
}

int ADS1220GetPowerDown(void)
{
	unsigned Temp;
	
	//Parse PowerDown data from register
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x04) >>2 );
}

int ADS1220GetTemperatureMode(void)
{
	unsigned Temp;
	
	//Parse TempMode data from register
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x02) >>1 );
}

int ADS1220GetBurnOutSource(void)
{
	unsigned Temp;
	
	//Parse BurnOut data from register
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( Temp & 0x01 );
}

int ADS1220GetVoltageReference(void)
{
	unsigned Temp;
	
	//Parse VoltageRef data from register
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( Temp >>6 );
}

int ADS1220Get50_60Rejection(void)
{
	unsigned Temp;
	
	//Parse Rejection data from register
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x30) >>4 );
}

int ADS1220GetLowSidePowerSwitch(void)
{
	unsigned Temp;
	
	//Parse PowerSwitch data from register
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x08) >>3);
}

int ADS1220GetCurrentDACOutput(void)
{
	unsigned Temp;
	
	//Parse IDACOutput data from register
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( Temp & 0x07 );
}

int ADS1220GetIDACRouting(int WhichOne)
{
	// Check WhichOne sizing
	if (WhichOne >1) return ADS1220_ERROR;
	
	unsigned Temp;
	
	//Parse Mux data from register
	ADS1220ReadRegister(ADS1220_3_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	if (WhichOne) return ( (Temp & 0x1c) >>2);
	
	else return ( Temp >>5 );
	
}

int ADS1220GetDRDYMode(void)
{
	unsigned Temp;
	
	//Parse DRDYMode data from register
	ADS1220ReadRegister(ADS1220_3_REGISTER, 0x01, &Temp);
	
	// return the parsed data
	return ( (Temp & 0x02) >>1 );
}

/* Useful Functions within Main Program for Setting Register Contents
*
*  	These functions show the programming flow based on the header definitions.
*  	The calls are not made within the demo example, but could easily be used by calling the function
*  		defined within the program to complete a fully useful program.
*	Similar function calls were made in the firwmare design for the ADS1220EVM.
*  
*  The following function calls use ASCII data sent from a COM port to control settings 
*	on the ADS1220.  The data is recontructed from ASCII and then combined with the
*	register contents to save as new configuration settings.
*
* 	Function names correspond to datasheet register definitions
*/
void set_MUX(char c)
{
	int mux = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	if (mux>=49 && mux<=54) mux -= 39;
	
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);

	Temp &= 0x0f;									// strip out old settings
	// Change Data rate
	switch(mux) {
		case 0:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_0_1);
			break;
		case 1:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_0_2);
			break;
		case 2:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_0_3);
			break;
		case 3:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_1_2);
			break;
		case 4:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_1_3);
			break;
		case 5:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_2_3);
			break;
		case 6:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_1_0);
			break;
		case 7:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_3_2);
			break;
		case 8:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_0_G);
			break;
		case 9:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_1_G);
			break;
		case 10:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_2_G);
			break;
		case 11:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_3_G);
			break;
		case 12:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_EX_VREF);
			break;
		case 13:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_AVDD);
			break;
		case 14:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_DIV2);
			break;
		case 15:
			dERROR = ADS1220SetChannel(Temp + ADS1220_MUX_DIV2);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;												
	}
	
	if (dERROR==ADS1220_ERROR)
		set_ERROR();
	
}

void set_GAIN(char c)
{
	int pga = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
	
	Temp &= 0xf1;									// strip out old settings
	// Change gain rate
	switch(pga) {
		case 0:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_1);
			break;
		case 1:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_2);
			break;
		case 2:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_4);
			break;
		case 3:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_8);
			break;
		case 4:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_16);
			break;
		case 5:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_32);
			break;
		case 6:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_64);
			break;
		case 7:
			dERROR = ADS1220SetGain(Temp + ADS1220_GAIN_128);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;	
		}
											
	
	
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
}

void set_PGA_BYPASS(char c)
{
	int buff = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp);
		
	Temp &= 0xfe;									// strip out old settings
	// Change PGA Bypass
	switch(buff) {
		case 0:
			dERROR = ADS1220SetPGABypass(Temp);
			break;
		case 1:
			dERROR = ADS1220SetPGABypass(Temp + ADS1220_PGA_BYPASS);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_DR(char c)
{
	int spd = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	Temp &= 0x1f;									// strip out old settings
	// Change Data rate
	switch(spd) {
		case 0:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_20);
			break;
		case 1:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_45);
			break;
		case 2:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_90);
			break;
		case 3:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_175);
			break;
		case 4:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_330);
			break;
		case 5:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_600);
			break;
		case 6:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_1000);
			break;
		case 7:
			dERROR = ADS1220SetDataRate(Temp + ADS1220_DR_1000);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
			
}

void set_MODE(char c)
{
	int spd = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	Temp &= 0xe7;									// strip out old settings
	// Change Data rate
	switch(spd) {
		case 0:
			dERROR = ADS1220SetClockMode(Temp + ADS1220_MODE_NORMAL);
			break;
		case 1:
			dERROR = ADS1220SetClockMode(Temp + ADS1220_MODE_DUTY);
			break;
		case 2:
			dERROR = ADS1220SetClockMode(Temp + ADS1220_MODE_TURBO);
			break;
		case 3:
			dERROR = ADS1220SetClockMode(Temp + ADS1220_MODE_DCT);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
		}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();

}

void set_CM(char c)
{
	int pwrdn = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	Temp &= 0xfb;									// strip out old settings
	// Change power down mode
	switch(pwrdn) {
		case 0:
			dERROR = ADS1220SetPowerDown(Temp);
			break;
		case 1:
			dERROR = ADS1220SetPowerDown(Temp + ADS1220_CC);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_TS(char c)
{
	int tmp = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	Temp &= 0xfd;									// strip out old settings
	// Change Temp Diode Setting
	switch(tmp) {
		case 0:
			dERROR = ADS1220SetTemperatureMode(Temp);
			break;
		case 1:
			dERROR = ADS1220SetTemperatureMode(Temp + ADS1220_TEMP_SENSOR);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_BCS(char c)
{
	int bo = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp);
	
	Temp &= 0xfe;									// strip out old settings
	// Change PGA Bypass
	switch(bo) {
		case 0:
			dERROR = ADS1220SetBurnOutSource(Temp);
			break;
		case 1:
			dERROR = ADS1220SetBurnOutSource(Temp + ADS1220_BCS);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
	
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
		
}

void set_VREF(char c)
{
	int ref = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	Temp &= 0x3f;									// strip out old settings
	// Change Reference
	switch(ref) {
		case 0:
			dERROR = ADS1220SetVoltageReference(Temp + ADS1220_VREF_INT);
			break;
		case 1:
			dERROR = ADS1220SetVoltageReference(Temp + ADS1220_VREF_EX_DED);
			break;
		case 2:
			dERROR = ADS1220SetVoltageReference(Temp + ADS1220_VREF_EX_AIN);
			break;
		case 3:
			dERROR = ADS1220SetVoltageReference(Temp + ADS1220_VREF_SUPPLY);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
		
}
void set_50_60(char c)
{
	int flt = (int) c - 48;
	int dERROR;
	unsigned Temp;
	
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	Temp &= 0xcf;									// strip out old settings
	// Change Filter
	switch(flt) {
		case 0:
			dERROR = ADS1220Set50_60Rejection(Temp + ADS1220_REJECT_OFF);
			break;
		case 1:
			dERROR = ADS1220Set50_60Rejection(Temp + ADS1220_REJECT_BOTH);
			break;
		case 2:
			dERROR = ADS1220Set50_60Rejection(Temp + ADS1220_REJECT_50);
			break;
		case 3:
			dERROR = ADS1220Set50_60Rejection(Temp + ADS1220_REJECT_60);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
		
}

void set_PSW(char c)
{
	int sw = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	Temp &= 0xf7;									// strip out old settings
		// Change power down mode
	switch(sw) {
		case 0:
			dERROR = ADS1220SetLowSidePowerSwitch(Temp);
			break;
		case 1:
			dERROR = ADS1220SetLowSidePowerSwitch(Temp + ADS1220_PSW_SW);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_IDAC(char c)
{
	int current = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_2_REGISTER, 0x01, &Temp);
	
	Temp &= 0xf8;									// strip out old settings
	// Change IDAC Current Output
	switch(current) {
		case 0:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_OFF);
			break;
		case 1:
		  #ifdef ADS1120
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_OFF);
		  #else
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_10);
		  #endif

			break;
		case 2:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_50);
			break;
		case 3:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_100);
			break;
		case 4:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_250);
			break;
		case 5:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_500);
			break;
		case 6:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_1000);
			break;
		case 7:
			dERROR = ADS1220SetCurrentDACOutput(Temp + ADS1220_IDAC_2000);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
		
		}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_IMUX(char c, int i)
{
	int mux = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_3_REGISTER, 0x01, &Temp);
	
	if (i==1) {
		Temp &= 0xe3;									// strip out old settings
		
		// Change IDAC2 MUX Output
	
		switch(mux) {
			case 0:
				Temp |= ADS1220_IDAC2_OFF;
				break;
			case 1:
				Temp |= ADS1220_IDAC2_AIN0;
				break;
			case 2:
				Temp |= ADS1220_IDAC2_AIN1;
				break;
			case 3:
				Temp |= ADS1220_IDAC2_AIN2;
				break;
			case 4:
				Temp |= ADS1220_IDAC2_AIN3;
				break;
			case 5:
				Temp |= ADS1220_IDAC2_REFP0;
				break;
			case 6:
				Temp |= ADS1220_IDAC2_REFN0;
				break;
			case 7:
				Temp |= ADS1220_IDAC2_REFN0;
				break;
			default:
				dERROR = ADS1220_ERROR;
				break;
		
		}
	}
	else {
		Temp &= 0x1f;
		// Change IDAC1 MUX Output
		switch(mux) {
			case 0:
				Temp |= ADS1220_IDAC1_OFF;
				break;
			case 1:
				Temp |= ADS1220_IDAC1_AIN0;
				break;
			case 2:
				Temp |= ADS1220_IDAC1_AIN1;
				break;
			case 3:
				Temp |= ADS1220_IDAC1_AIN2;
				break;
			case 4:
				Temp |= ADS1220_IDAC1_AIN3;
				break;
			case 5:
				Temp |= ADS1220_IDAC1_REFP0;
				break;
			case 6:
				Temp |= ADS1220_IDAC1_REFN0;
				break;
			case 7:
				Temp |= ADS1220_IDAC1_REFN0;
				break;
			default:
				dERROR = ADS1220_ERROR;
				break;
		}
	}
	
	if (dERROR==ADS1220_NO_ERROR) 
		dERROR = ADS1220SetIDACRouting(Temp); 
	
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_DRDYM(char c)
{
	int drdy = (int) c - 48;
	int dERROR;
	unsigned Temp;
		
	// the DataRate value is only part of the register, so we have to read it back
	// and massage the new value into it
	ADS1220ReadRegister(ADS1220_3_REGISTER, 0x01, &Temp);
	
	Temp &= 0xfd;									// strip out old settings
	// Change DRDY Mode Setting
	switch(drdy) {
		case 0:
			dERROR = ADS1220SetDRDYMode(Temp);
			break;
		case 1:
			dERROR = ADS1220SetDRDYMode(Temp + ADS1220_DRDY_MODE);
			break;
		default:
			dERROR = ADS1220_ERROR;
			break;
	
	}
								
	if (dERROR==ADS1220_ERROR) 
		set_ERROR();
	
}

void set_ERROR(void)
{
	/* Add some error routine here is desired */
}

 

ADS1220.h :

Скрытый текст

//******************************************************************************
//    ADS1220 Header File for Demo Functions
//
//
//    Description: Use of the STM32F100C8T6
//    communicating to the ADS1220 24-bit ADC.
//
//
//
//                 STM32F100Cxxx
//             ------------------
//         /|\|                  |
//          | |                  |
//          --|RST           PB.3|<-- MISO (DOUT)
//            |                  |
//            |              PB.1|--> MOSI (DIN)
//            |                  |
//            |              PB.4|--> SCLK
//            |                  |
//            |              PB.2|<-- INT (DRDY)
//            |                  |
//            |              PB.0|--> CS
//             ------------------
//
//******************************************************************************
#ifndef ADS1220_H_
#define ADS1220_H_

/* Definition of GPIO Port Bits Used for Communication */
// P1.2
#define ADS1220_CS      	0x04
// P3.3
#define ADS1220_DIN     	0x08
// P3.4
#define ADS1220_DOUT    	0x10
// P2.6
#define ADS1220_DRDY    	0x40
// P2.7
#define ADS1220_SCLK    	0x80

/* Error Return Values */
#define ADS1220_NO_ERROR           0
#define ADS1220_ERROR				-1

/* Command Definitions */
#define ADS1220_CMD_RDATA    	0x10
#define ADS1220_CMD_RREG     	0x20
#define ADS1220_CMD_WREG     	0x40
#define ADS1220_CMD_SYNC    	0x08
#define ADS1220_CMD_SHUTDOWN    0x02
#define ADS1220_CMD_RESET    	0x06

/* ADS1220 Register Definitions */
#define ADS1220_0_REGISTER   	0x00
#define ADS1220_1_REGISTER     	0x01
#define ADS1220_2_REGISTER     	0x02
#define ADS1220_3_REGISTER    	0x03


/* ADS1220 Register 0 Definition */
//   Bit 7   |   Bit 6   |   Bit 5   |   Bit 4   |   Bit 3   |   Bit 2   |   Bit 1   |   Bit 0
//--------------------------------------------------------------------------------------------
//                     MUX [3:0]                 |             GAIN[2:0]             | PGA_BYPASS
//
// Define MUX
#define ADS1220_MUX_0_1   	0x00
#define ADS1220_MUX_0_2   	0x10
#define ADS1220_MUX_0_3   	0x20
#define ADS1220_MUX_1_2   	0x30
#define ADS1220_MUX_1_3   	0x40
#define ADS1220_MUX_2_3   	0x50
#define ADS1220_MUX_1_0   	0x60
#define ADS1220_MUX_3_2   	0x70
#define ADS1220_MUX_0_G		0x80
#define ADS1220_MUX_1_G   	0x90
#define ADS1220_MUX_2_G   	0xa0
#define ADS1220_MUX_3_G   	0xb0
#define ADS1220_MUX_EX_VREF 0xc0
#define ADS1220_MUX_AVDD   	0xd0
#define ADS1220_MUX_DIV2   	0xe0

// Define GAIN
#define ADS1220_GAIN_1      0x00
#define ADS1220_GAIN_2      0x02
#define ADS1220_GAIN_4      0x04
#define ADS1220_GAIN_8      0x06
#define ADS1220_GAIN_16     0x08
#define ADS1220_GAIN_32     0x0a
#define ADS1220_GAIN_64     0x0c
#define ADS1220_GAIN_128    0x0e

// Define PGA_BYPASS
#define ADS1220_PGA_BYPASS 	0x01

/* ADS1220 Register 1 Definition */
//   Bit 7   |   Bit 6   |   Bit 5   |   Bit 4   |   Bit 3   |   Bit 2   |   Bit 1   |   Bit 0
//--------------------------------------------------------------------------------------------
//                DR[2:0]            |      MODE[1:0]        |     CM    |     TS    |    BCS
//
// Define DR (data rate)
#define ADS1220_DR_20		0x00
#define ADS1220_DR_45		0x20
#define ADS1220_DR_90		0x40
#define ADS1220_DR_175		0x60
#define ADS1220_DR_330		0x80
#define ADS1220_DR_600		0xa0
#define ADS1220_DR_1000		0xc0

// Define MODE of Operation
#define ADS1220_MODE_NORMAL 0x00
#define ADS1220_MODE_DUTY	0x08
#define ADS1220_MODE_TURBO 	0x10
#define ADS1220_MODE_DCT	0x18

// Define CM (conversion mode)
#define ADS1220_CC			0x04

// Define TS (temperature sensor)
#define ADS1220_TEMP_SENSOR	0x02

// Define BCS (burnout current source)
#define ADS1220_BCS			0x01

/* ADS1220 Register 2 Definition */
//   Bit 7   |   Bit 6   |   Bit 5   |   Bit 4   |   Bit 3   |   Bit 2   |   Bit 1   |   Bit 0
//--------------------------------------------------------------------------------------------
//         VREF[1:0]     |        50/60[1:0]     |    PSW    |             IDAC[2:0]
//
// Define VREF
#define ADS1220_VREF_INT	0x00
#define ADS1220_VREF_EX_DED	0x40
#define ADS1220_VREF_EX_AIN	0x80
#define ADS1220_VREF_SUPPLY	0xc0

// Define 50/60 (filter response)
#define ADS1220_REJECT_OFF	0x00
#define ADS1220_REJECT_BOTH	0x10
#define ADS1220_REJECT_50	0x20
#define ADS1220_REJECT_60	0x30

// Define PSW (low side power switch)
#define ADS1220_PSW_SW		0x08

// Define IDAC (IDAC current)
#define ADS1220_IDAC_OFF	0x00
#define ADS1220_IDAC_10		0x01
#define ADS1220_IDAC_50		0x02
#define ADS1220_IDAC_100	0x03
#define ADS1220_IDAC_250	0x04
#define ADS1220_IDAC_500	0x05
#define ADS1220_IDAC_1000	0x06
#define ADS1220_IDAC_2000	0x07

/* ADS1220 Register 3 Definition */
//   Bit 7   |   Bit 6   |   Bit 5   |   Bit 4   |   Bit 3   |   Bit 2   |   Bit 1   |   Bit 0
//--------------------------------------------------------------------------------------------
//               I1MUX[2:0]          |               I2MUX[2:0]          |   DRDYM   | RESERVED
//
// Define I1MUX (current routing)
#define ADS1220_IDAC1_OFF	0x00
#define ADS1220_IDAC1_AIN0	0x20
#define ADS1220_IDAC1_AIN1	0x40
#define ADS1220_IDAC1_AIN2	0x60
#define ADS1220_IDAC1_AIN3	0x80
#define ADS1220_IDAC1_REFP0	0xa0
#define ADS1220_IDAC1_REFN0	0xc0

// Define I2MUX (current routing)
#define ADS1220_IDAC2_OFF	0x00
#define ADS1220_IDAC2_AIN0	0x04
#define ADS1220_IDAC2_AIN1	0x08
#define ADS1220_IDAC2_AIN2	0x0c
#define ADS1220_IDAC2_AIN3	0x10
#define ADS1220_IDAC2_REFP0	0x14
#define ADS1220_IDAC2_REFN0	0x18

// define DRDYM (DOUT/DRDY behaviour)

#define ADS1220_DRDY_MODE	0x02

/* Low Level ADS1220 Device Functions */
void ADS1220Init(void);							// Device intialization
int ADS1220WaitForDataReady(int Timeout);		// DRDY polling
void ADS1220AssertCS(int fAssert);				// Assert/deassert CS
void ADS1220SendByte(unsigned char cData );		// Send byte to the ADS1220
unsigned char ADS1220ReceiveByte(void);			// Receive byte from the ADS1220

/* ADS1220 Higher Level Functions */
long ADS1220ReadData(void);						// Read the data results
void ADS1220ReadRegister(int StartAddress, int NumRegs, unsigned * pData);	// Read the register(s)
void ADS1220WriteRegister(int StartAddress, int NumRegs, unsigned * pData); // Write the register(s)
void ADS1220SendResetCommand(void);				// Send a device Reset Command
void ADS1220SendStartCommand(void);				// Send a Start/SYNC command
void ADS1220SendShutdownCommand(void);			// Place the device in powerdown mode


/* Register Set Value Commands */
void ADS1220Config(void);
int ADS1220SetChannel(int Mux);
int ADS1220SetGain(int Gain);
int ADS1220SetPGABypass(int Bypass);
int ADS1220SetDataRate(int DataRate);
int ADS1220SetClockMode(int ClockMode);
int ADS1220SetPowerDown(int PowerDown);
int ADS1220SetTemperatureMode(int TempMode);
int ADS1220SetBurnOutSource(int BurnOut);
int ADS1220SetVoltageReference(int VoltageRef);
int ADS1220Set50_60Rejection(int Rejection);
int ADS1220SetLowSidePowerSwitch(int PowerSwitch);
int ADS1220SetCurrentDACOutput(int CurrentOutput);
int ADS1220SetIDACRouting(int IDACRoute);
int ADS1220SetDRDYMode(int DRDYMode);

/* Register Get Value Commands */
int ADS1220GetChannel(void);
int ADS1220GetGain(void);
int ADS1220GetPGABypass(void);
int ADS1220GetDataRate(void);
int ADS1220GetClockMode(void);
int ADS1220GetPowerDown(void);
int ADS1220GetTemperatureMode(void);
int ADS1220GetBurnOutSource(void);
int ADS1220GetVoltageReference(void);
int ADS1220Get50_60Rejection(void);
int ADS1220GetLowSidePowerSwitch(void);
int ADS1220GetCurrentDACOutput(void);
int ADS1220GetIDACRouting(int WhichOne);
int ADS1220GetDRDYMode(void);

/* Useful Functions within Main Program for Setting Register Contents
*
*  	These functions show the programming flow based on the header definitions.
*  	The calls are not made within the demo example, but could easily be used by calling the function
*  		defined within the program to complete a fully useful program.
*	Similar function calls were made in the firwmare design for the ADS1220EVM.
*
*  The following function calls use ASCII data sent from a COM port to control settings
*	on the ADS1220.  The data is recontructed from ASCII and then combined with the
*	register contents to save as new configuration settings.
*
* 	Function names correspond to datasheet register definitions
*/
void set_MUX(char c);
void set_GAIN(char c);
void set_PGA_BYPASS(char c);
void set_DR(char c);
void set_MODE(char c);
void set_CM(char c);
void set_TS(char c);
void set_BCS(char c);
void set_VREF(char c);
void set_50_60(char c);
void set_PSW(char c);
void set_IDAC(char c);
void set_IMUX(char c, int i);
void set_DRDYM(char c);
void set_ERROR(void);
void ADS1220Config_MUX_GAIN(uint8_t mux, uint8_t gain);

#endif /*ADS1220_H_*/

 

в результате получаю такую осциллограмму :

565589729_.jpg.c7d46918138769153d0586d8a3632f83.jpg

То есть , постоянно считывается 0.

А вот регистры конфигурации:

Задаю номер входа MUX и усиление :

 

562700078_2.jpg.0226746a03560f0e0c39df665bc8bba7.jpg646785441_3.jpg.a3bf228f73f046bf079e53838cb8a537.jpg

 

Читаю данные так:

 ADS1220Config_MUX_GAIN(ADS1220_MUX_0_G, ADS1220_GAIN_1);
	 HAL_Delay(10);
	 temp_[0] = ADS1220ReadData();

Это для 0 канала. 

Пробовал и так:

ADS1220SetChannel(ADS1220_MUX_0_G);
	 ADS1220SetGain(ADS1220_GAIN_1);
	 temp_[0] = ADS1220ReadData();

Результат аналогичный. Кто что подскажет? Может кто заметит какой косяк в коде? Уже голова дымит ..

Share this post


Link to post
Share on other sites

попробуй для начала избавиться от либы и пропиши своими руками все согласно мануала

Share this post


Link to post
Share on other sites

Я осциллографом замерял сигналы , вроде все как надо работает. Только АЦП не выдает данных.

 

Share this post


Link to post
Share on other sites

Конденсаторы Panasonic. Часть 4. Полимеры – номенклатура

В заключительной, четвертой статье из цикла «Конденсаторы Panasonic» рассматриваются основные достоинства и особенности использования конденсаторов этого японского производителя на основе полимерной технологии. Главной конструктивной особенностью таких конденсаторов является полимерный материал, используемый в качестве проводящего слоя. Полимер обеспечивает конденсаторам высокую электрическую проводимость и пониженное эквивалентное сопротивление (ESR). Номинальная емкость и ESR отличается в данном случае высокой стабильностью во всем рабочем диапазоне температур. А повышенная емкость при низком ESR идеальна для решения задач шумоподавления и ограничения токовых паразитных импульсов в широком частотном диапазоне.

Читать статью

Что-то я не могу понять, что за изврат сделан в коде? Что помешало использовать обычный аппаратный SPI?

Share this post


Link to post
Share on other sites

Не на тех ногах аппаратный SPI . Да и SPI вроде нормально программный работает . Проблема скорее в правильности конфигурации АЦП

Share this post


Link to post
Share on other sites
                     

STM32G0 - средства противодействия угрозам безопасности

Результатом выполнения требований безопасности всегда является усложнение разрабатываемой системы. Особенно чувствительными эти расходы стали теперь, в процессе массового внедрения IoT. Обладая мощным набором инструментов информационной безопасности, микроконтроллеры STM32G0 производства STMicroelectronics, объединив в себе невысокую цену, энергоэффективность и расширенный арсенал встроенных аппаратных инструментов, способны обеспечить полную безопасность разрабатываемого устройства.

Подробнее...

Кто подскажет что за бит? :

PGA_BYPASS

Цитата

Disables and bypasses the internal low-noise PGA Disabling the PGA reduces overall power consumption and allows the commonmode voltage range (VCM) to span from AVSS – 0.1 V to AVDD + 0.1 V. The PGA can only be disabled for gains 1, 2, and 4. The PGA is always enabled for gain settings 8 to 128, regardless of the PGA_BYPASS setting. 0 : PGA enabled (default) 1 : PGA disabled and bypassed

обход чего-то , только чего? И какое значение нужно выставить?

Вот даташит:

http://www.ti.com/lit/ds/symlink/ads1220.pdf

Share this post


Link to post
Share on other sites
43 минуты назад, artos5 сказал:

Кто подскажет что за бит? :

PGA_BYPASS

обход чего-то , только чего? И какое значение нужно выставить?

На первой же странице даташита - programmable gain amplifier

Share this post


Link to post
Share on other sites

Так , уже "почти" заработало. Почему почти? Потому что данные теперь уже получаю , но получаю кашу .

Буду дальше разбираться. Как доведу библиотеки "до ума" кому они нужны будут -  скину по запросу в личку.

Share this post


Link to post
Share on other sites
Posted (edited)

лучше не надо

вот сколько пользовался чужими библиотеками, столько раз и были проблемы с кодом. Давно правда это было, и другим с тех пор не советую. Почитал даташит, сделал все сам за 15 минут, сэкономил пару суток. Вообще не понимаю смысла в библиотеках для внешних устройств

Edited by mail_robot

Share this post


Link to post
Share on other sites

Глупости. В чужой библиотеке все почти сделано. Небольшая доработка , и она готова под собственные задачи.

Вот сейчас делаю все правильно , а считываются постоянно "0".

сейчас скрины покажу.

Скрытый текст

 

Посылаю команду сброса:

IMG_20190819_003732.thumb.jpg.4956b960b50c9c613ac931290e06b5a1.jpg

Жду 1мс. Чтобы АЦП пришел в себя.

Потом шлю конфигурацию , номер канала АЦП , усиление и т.д. и сразу команду чтения АЦП :

IMG_20190819_003757.thumb.jpg.e1dfc0b3afa2af0b443c5de6e16fb78c.jpg

И после собственно читаю данные с АЦП , после установки в 0 пина DRDY :

IMG_20190819_003822_1.thumb.jpg.89fe07b3578f2a2864daf50f5266b549.jpg

 

 

В итоге всегда читается 0.

Share this post


Link to post
Share on other sites
2 hours ago, artos5 said:

всегда читается 0.

Судя по картинкам, у Вас в регистре Reg1 записаны все биты нулями. Вот, на среднем скрине наблюдается команда записи 0x44 с параметром 0x00. Далее чтение регистра Reg1 команда 0х24 возвращает 0х00.

Значит АЦП находится в режиме однократного измерения Single-Shot. Поэтому для старта измерения нужно послать команду START/SYNC, код 0x08, которой нет на приведенных скринах.

Получается АЦП ничего не измеряет, а просто ждет старта.

Тут надо либо послать START/SYNC и ждать готовности результата по спаду DRDY, либо установить в Reg1 бит непрерывного измерения командой 0х44 с параметром 0х04, и тогда АЦП будет непрерывно генерить результаты измерения.

Share this post


Link to post
Share on other sites

Да , команду не ту отправлял всего лишь .. я отправлял 0х10 , а нужно было 0х08... Теперь всё работает . С термодатчиком только пока непонятно . Значения какие-то конские.

Share this post


Link to post
Share on other sites
1 hour ago, artos5 said:

какие-то конские

А какие конкретно? Должно быть всё просто. Устанавливаем бит TS, запускаем преобразование, считываем 3 байта, сдвигаем на 10 вправо и умножаем на 0.03125. Получаем градусы Цельсия.

Share this post


Link to post
Share on other sites

Все заработало. В даташите не доглядел этот пункт по термометру .

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By maxssau
      Продам адаптеры USB-I2S. 

       
      Возможности:
       
      стерео ввод/вывод PCM 16-32 бита, 44.1-384 кГц. Ввода DSD нет, как и драйверов для ввода DSD.
      вывод DSD в режиме DoP 64-128, в режиме Native 64-256. Native доступен в Linux без "хитрых" драйверов.
      Тактирование от платы ЦАП/АЦП, частоты 512 fs (22.5792/24.576 МГц). Теоретически возможно и 1024fs(скорости 768кГц и DSD512 Native), но это не опробовано.
      Гальваническая изоляция на Si8662/Si8640.
      Питание возможно как Self так и Bus Powered. В режиме Bus Powered необходимо самостоятельно позаботиться о мастерклоке, т.к. возможны сильные глюки при выключенном генераторе мастерклока.
       
      Тема: 
      срок изготовления 3-5 недель (сильно зависит от поставок процессоров).
      На данный момент полностью реализован интерфейс Legacy. Для отладки Native режима пока нет платы ЦАП, в процессе разработки, будет не раньше осени.
      Цена 6000 + пересылка (в среднем 250 р.).
    • By pryanic
      Доброго времени суток. Понадобилось разобраться с АЦП.  Основной материал использовал Евстифеева (микроконтроллеры семейства мега) и учебный курс Di-Halt.
      На первый раз задача простая - обработать напряжение с переменного резистора и послать по UART в терминал. С терминалом уже кое-что делал, так что тут вряд ли косяк есть.
      Кратко опишу программу: каждую секунду в обработчике прерывания таймера (не совсем точно, прерывание по переполнению Т0) запускаю преобразование АЦП установкой в 1 бита ADSC. 
      В обработчике прерывания АЦП читаю байт ADCH (выравнивание по левому краю ADLAR=1) и шлю по уарт. Но в терминал приходят одни FF независимо от положения движка потенциометра (подключен к PC1 средним контактом, крайними на землю и AVCC)
       
       
      ADC_test.zip
    • By dav1977
      Кто-нибудь запускал скоростные  АЦП  AD7606(последовательного приближения)
       в последовательном режиме считывания данных ?,
      из 4 шт одна заработала, остальные на выводе последовательного вывода DOUT ничего не выдают постоянно 0.
      пробовал переключаться с внутренним опорным источником(выдает 2.49), и с внешним без разницы.
      Может у них есть какая то очередность включения?
       

    • By dommax
      Распродаю остатки радиодеталей.
      Для удобного поиска написал WEB страничку http://detali.syremo.com.ua/
      Количество может не совпадать. Пишите - отвечу. Договоримся...
      Отправляю только по Украине. Перед отправкой смогу сделать фото.
  • Сообщения

    • Вряд ли. Просто в последнее время в магазинах появилось большое число малогабаритных импульсных зарядных устройств по цене менее $50. И тема потеряла актуальность. Тем не менее, в одной из последующих версий мне удалось таки разработать вариант с очень хорошим стабилизатором тока зарядки на базе нелинейного И-регулятора. Именно этот вариант я упоминал 14 октября 2015 года. Схема, разумеется, усложнилась, хотя и не катастрофически. Причем, в ней по-прежнему нет ни одного операционного усилителя, – своего рода продолжение деревенско-гаражной традиции. Нет в ней и привычного сложного в изготовлении и сильно греющегося датчика тока. В качестве шунта запланирован либо амперметр, либо вообще провод сечением 1,5мм2 и длиной 4,5м, который все равно нужно использовать для подключения аккумулятора. Разработка этой схемы – это у меня теперь такое развлечение в обеденный перерыв. Благо, мощный компьютер всегда доступен.
    • Устройство для ручной подачи припоя. Припой диаметром 1 мм наматывается на катушку от 13 мм ленты для пишущих машинок и помещается в их же коробочку. В коробочке сверлится отверстие 2,5 мм для выхода припоя. В куске изоленты проделывается отверстие и коробочка оборачивается с краёв  для фиксации крышки. Нужное количество припоя  вытягивается вручную. На катушку помещается около 15 м припоя диаметром 1 мм. Диаметр  готового устройства 55 мм, толщина 20 мм. Остальное понятно по фото.
    • почему же не стабилитрон  затвор - эмиттер ?. реальная схема  Lenze . :
    • Возможен и такой вариант.  Ламповый усилитель со своими 12-15вт.  вовлекает слушателя в атмосферу исполнителя,  а транзисторный со своими 150вт. не вовлекает, он может хорошо, очень хорошо или замечательно, громко или тихо, но просто играть  музыку.  Как то вот у меня сложилось такое впечатление. 
    • @FonSchtirlitz Справедливое утверждение! При покупке надо подключать и слушать с тем устройством, с которым они будут работать. Я тоже всегда так поступаю. Да и колонки для УНЧ тоже надо подбирать и реально прослушивать с тем усилителем с которым они будут работать, для того, чтобы добиться идеальной согласованности и качества. 
    • Ну тогда открою Вам маленькую тайну - 99% частотников в дистанционном режиме успешно работают вообще без пульта, который можно смело снять  даже во время работы и выбросить, например, в мусорное ведро, поскольку исполнительная программа находится не в пульте, а в самом частотнике. В пульт можно скопировать программу и перенести на бесконечное число подобных частотников. Большинство крупных предприятий, имеющих возможность заключать прямые договоры с изготовителем так и поступают - покупают 100 частотников и ...один пульт. Большинство мировых брендов не нуждаются вообще в пультах, поскольку имеют в арсенале соответствуюшие программы-оболочки, позволяющие программировать частотники напрямую с ПК. Теперь об индикации. Нет такого параметра, который нельзя было бы вывести на индикацию , используя совершенно другие индикационные устройства, нежели пульт, используя стандартные аналого-цифровые входы-выходы частотника. Их нужно только правильно запрограммировать. Большинство мануалов потому и напоминвют китайскую грамоту, поскольку большинство разделов посвящено именно этой теме - как программировать входы-выходы, чтобы расширить функционал помимо пульта. И, наконец последнее.что мешает перенести пульт(если уж без него никак) на расстояние достаточное большое, используя тот же FTP?
    • Есть такая защита, плата китайская. Много всего наворочено, что эта защита может?  
  • Покупай!

×
×
  • Create New...