Перейти к содержанию
    

13 minutes ago, Ruslan1 said:

Это несколько интересных эффектов:

1. перезаряд всех имеющихся в схеме емкостей на входе АЦП (и внешних реальных-паразитных и внутренней) от неизвестного уровня предыдущего входа к новому измеряемому уровню током нового подключенного измеряемого входа, с учетом входного сопротивления АЦП и других токов утечки.

2. перегрузка фильтр АЦП новыми данными. Процесс и технология обычно описаны в даташите АЦП. Но следует понимать, что сеачала должно произойти (1) и тольео потом начаться (2).

 

У меня был случай, когда, паразитные емкости электронных коммутаторов мешали. Вводил даже специальный вход, перезаряжающий все емкости измерителя до среднего уровня, от которого уже можно было посчитать максимальное время перезаряда до измеряемого уровня. То есть In1-Ref-In2-Пауза-Измерение_In2.

Это все считается (ну или хоть симулируется в симуляторе как набор цепочек R-C), подбирать тут опасно- будет на одном входе -Vmax, а  на другом входе +Vmax, и окажется что емкости недоперезарядились.

тензодатчик же низкоомный прибор. ток перезарядки этих емкостей будет достаточно большим

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Reystlin said:

тензодатчик же низкоомный прибор. ток перезарядки этих емкостей будет достаточно большим

обратите внимание на Table 5. Output RMS Noise (µV) vs. Gain and Output Update Rate for the AD7798 Using a 2.5 V Reference

и на табл. Table 14. Update Rates Available. Чем выше частота запуска АЦП, тем меньше у Вас получится достоверная разрядность.

При переключении канала следует учитывать время на "установление" режима входа АЦП (при наличии внешних RC фильтров, усилителей, конденсаторов).

Это аналогично настройке времени отработки УВХ для АЦП посл. приближения.

После старта АЦП готовность данных определяйте по биту в регистре статуса. То что вы показали на видео, похоже на несвоевременное считывание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 minutes ago, k155la3 said:

обратите внимание на Table 5. Output RMS Noise (µV) vs. Gain and Output Update Rate for the AD7798 Using a 2.5 V Reference

и на табл. Table 14. Update Rates Available. Чем выше частота запуска АЦП, тем меньше у Вас получится достоверная разрядность.

При переключении канала следует учитывать время на "установление" режима входа АЦП (при наличии внешних RC фильтров, усилителей, конденсаторов).

Это аналогично настройке времени отработки УВХ для АЦП посл. приближения.

После старта АЦП готовность данных определяйте по биту в регистре статуса. То что вы показали на видео, похоже на несвоевременное считывание.

считывание сейчас сделано вот таким кодом

  unsigned char rdy = 0;
  unsigned long reg_stat= AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_STAT,1);
  rdy = (reg_stat & 0x80);
  if((rdy==0x80)&&((reg_stat& 0x07)==0x00))
    rdy=1;
  if((rdy==0x80)&&((reg_stat& 0x07)==0x01))
    rdy=2;
  if((rdy==0x80)&&((reg_stat& 0x07)==0x02))
    rdy=3;
weigt[0]=reg_stat;
weigt[1]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_MODE,2);
weigt[2]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_CONF,2);
weigt[3]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_OFFSET,3);
weigt[4]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_FULLSALE,3);
      switch(rdy)
        {
        case 1:

          weigt[5] = filter(ADCFilter(4,AD7799_GetRegisterValue(AD7799_CHIP3, AD7799_REG_DATA,3)));
              break;
        case 2:
          //weigt[5]=AD7799_GetRegisterValue(AD7799_CHIP3, AD7799_REG_DATA,3);
              break;
        }
    }

т.е. происходит только по наличию бита готовности в регистре статуса

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас работа с одним чипом АЦП и одним его каналом получается корректно ?

Не знаю, по-моему Вам надо пересмотреть построение (логику) функций интерфейса. Если это не Ваш код изначально, тем более.

Так как наличие и время устновки CS я не вижу. 

Где-то в подобном стиле (хотя, "дело вкуса")

int AD77xx_IsReady(void) { if( AD77xx_GetStatus() & 0x80 ) return(0); else return(1);  }; // не помню, возможно инверсно

тогда считывание 

SPI_CS_ACTIVE_ADC_00    (макро, устанавливает нолик на нужный пин порта)
// ----------------

if( AD77xx_IsReady() )

{

	AD77xx_SetChannel( 0 );
	if( AD77xx_IsReady() ) 
		AD77xx_Go();
	else
		.... error 
}
else
	. . . . wait or error .....

// ----------------
SPI_CS_PASSIVE_ADC_00    

 

ps Вы проверяли (осцилографом) корректность настроке SPI - полярность и фазу тактирования ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, k155la3 said:

У Вас работа с одним чипом АЦП и одним его каналом получается корректно ?

Не знаю, по-моему Вам надо пересмотреть построение (логику) функций интерфейса. Если это не Ваш код изначально, тем более.

Так как наличие и время устновки CS я не вижу. 

Где-то в подобном стиле (хотя, "дело вкуса")

int AD77xx_IsReady(void) { if( AD77xx_GetStatus() & 0x80 ) return(0); else return(1);  }; // не помню, возможно инверсно

тогда считывание 


SPI_CS_ACTIVE_ADC_00    (макро, устанавливает нолик на нужный пин порта)
// ----------------

if( AD77xx_IsReady() )

{

	AD77xx_SetChannel( 0 );
	if( AD77xx_IsReady() ) 
		AD77xx_Go();
	else
		.... error 
}
else
	. . . . wait or error .....

// ----------------
SPI_CS_PASSIVE_ADC_00    

 

Я взял пример от аналогдевайс, переписал там ф-и раоты в SPI и дописал нехватающих функций

вот код где CS дергается и происходит отправка и прием данных

unsigned long AD7799_GetRegisterValue(unsigned char CS,unsigned char regAddress, unsigned char size)
{
	unsigned char data[4] = {0x00, 0x00, 0x00, 0x00};
	unsigned long receivedData = 0x00;	
	data[0] = AD7799_COMM_READ |  AD7799_COMM_ADDR(regAddress);
	AD7799_CS_LOW(CS);  
	AD7799_SpiTransferByte(data[0]);
        for(char i=0;i<size;i++)
          data[i]=AD7799_SpiTransferByte(data[i]);
	AD7799_CS_HIGH(CS);
	if(size == 1)
	{
		receivedData += (data[0] << 0);
	}
	if(size == 2)
	{
		receivedData += (data[0] << 8);
		receivedData += (data[1] << 0);
	}
	if(size == 3)
	{
		receivedData += (data[0] << 16);
		receivedData += (data[1] << 8);
		receivedData += (data[2] << 0);
	}
    return receivedData;
  
}
void AD7799_SetRegisterValue(unsigned char CS,unsigned char regAddress,
                             unsigned long regValue, 
                             unsigned char size)
{
  unsigned char data[4] = { 0x00, 0x00, 0x00, 0x00};	
  data[0] = AD7799_COMM_WRITE |  AD7799_COMM_ADDR(regAddress);
    if(size == 1)
    {
        data[1] = (unsigned char)regValue;
    }
    if(size == 2)
    {
		data[2] = (unsigned char)((regValue & 0x0000FF) >> 0);
        data[1] = (unsigned char)((regValue & 0x00FF00) >> 8);
    }
    if(size == 3)
    {
		data[3] = (unsigned char)((regValue & 0x0000FF) >> 0);
		data[2] = (unsigned char)((regValue & 0x00FF00) >> 8);
        data[1] = (unsigned char)((regValue & 0xFF0000) >> 16);
    }
    
    AD7799_CS_LOW(CS);
    for(char i=0;i<=(size);i++)
          AD7799_SpiTransferByte(data[i]);
    AD7799_CS_HIGH(CS);
}

На данный момент задействован 1 ацп и 1 его канал

Изменено пользователем Reystlin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AD7799_CS_LOW(3)

Макро, которое сбрасывает в 0 бит 3, те 1111-0111  ?

Все-таки, у Вас есть возможность проверить осцилографом на "железе" наличие правильных CS и соотв-ие диаграммы SCK-MOSI-MISO тем, которые приведены в даташите ? Так как если SPI настроен не так как требуется - можно долго и безнадежно отлаживать софт.

По крайней мере, даже если нет осцилографа, убедитесь (в режиме дебагера) что нет одновременно выставленных активных уровней на CS нескольких чипов.

Можно также оставить на SPI только один чип (разрешить управление от процессора только одним CS, на CS остальных - временно подать постоянный неактивный уровень 1)

Я в первую очередь проверил бы настройку SPI а во-вторую - запустил бы работу одного чипа AD7799 и его одного канала, на "гарантированно-успешном" интервале опроса, например 2 Гц.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Reystlin said:

тензодатчик же низкоомный прибор. ток перезарядки этих емкостей будет достаточно большим

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

У меня, например, выходная емкость 561КП2 меняла заряд на канальном конденсаторе входного RC-фильтра, все от желаемой точности и скорости измерений зависит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ps Если есть сомнения в работе ф-ий AD - выложите архив библиотеки интерфейса. Это исключить доп.вопросы.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

59 minutes ago, k155la3 said:

AD7799_CS_LOW()

По крайней мере, даже если нет осцилографа, убедитесь (в режиме дебагера) что нет одновременно выставленных активных уровней на CS нескольких чипов.

Я не продавец китайских 10-долларовых логических анализаторов, но посоветовал бы Топикстартеру такой купить и применить :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Quote

 

Ready Bit. Cleared when data is written to the data register. Set after the data register is read or after a period of time before the data register is updated with a new conversion result to indicate to the user not to read the conversion data. It is also set when the part is placed in power-down mode. The end of a conversion is indicated by the DOUT/RDY pin. This pin can be used as an alternative to the status register for monitoring the ADC for conversion data.

 

Может оно ?

Ну, еще уровень функций интерфейса SPI надо проверять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, k155la3 said:

Может оно ?

Ну, еще уровень функций интерфейса SPI надо проверять.

так я же ничего в дата регистр не пишу.

unsigned char AD7799_SPI_Init( void )
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//Включаем тактирование SPI1
  
  //Настройка внутреннего SPI1
  SPI_InitTypeDef spi;  
  SPI_StructInit(&spi);
    spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//Направление передачи        
    spi.SPI_Mode = SPI_Mode_Master;                     //Режим передачи
    spi.SPI_DataSize = SPI_DataSize_8b;                 //Размер пакета
    spi.SPI_CPOL = SPI_CPOL_High;                        //idle тактового сигнала
    spi.SPI_CPHA = SPI_CPHA_2Edge;                      //рабочий фронт тактового сигнала
    spi.SPI_NSS = SPI_NSS_Soft;                         //режим работы пина NSS
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//Предделитель
    spi.SPI_FirstBit = SPI_FirstBit_MSB;                //Первый бит - младший
    spi.SPI_CRCPolynomial = 7;                          //Контрольная сумма
    SPI_Init(SPI1, &spi);
    SPI_Cmd(SPI1, ENABLE);
    //Насройка выводов под SPI1
  GPIO_InitTypeDef port;
  GPIO_StructInit(&port);
    port.GPIO_Mode = GPIO_Mode_AF_PP;
    port.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    port.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &port);    

  //Насройка выводов под ~CS
  GPIO_StructInit(&port);
    port.GPIO_Mode = GPIO_Mode_Out_PP;
    port.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
    port.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(AD7799_CS_PORT, &port);
    AD7799_CS_PORT->ODR |=((1<<4)|(1<<5)|(1<<6));
    return(1);
}

unsigned char AD7799_SpiTransferByte(unsigned char data)
{
	unsigned char temp;

	SPI1->DR = data; 
	while(!(SPI1->SR & SPI_SR_RXNE));

	temp = SPI1->DR; 
	return temp;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имеется ввиду STATUS REGISTER 

и моя гипотеза, что 0 в старшем (7) разряде означает, что ацп-ированные данные достоверны и их можно считывать из чипа. Как только Вы их прочитаете, этот бит устанавливается в 1, пока не пройдет следующий цикл оцифровки входного аналогового значения. Если Вы после считывания данных из регистра данных не запустите АЦП на оцифровку, то бит так и останется в "1", что означает "нет данных в рег. данных" или "данные недостоверны" (например, АЦП уже перенес в регистр данных старшие разряды, а младшие еще остались от предыдущей оцифровки)

Quote

так я же ничего в дата регистр не пишу.

"Пишет" чип "внутрисебя", из рабочего регистра АЦП в буферный регистр данных (из которого мы считываем данные оцифровки).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ps

Начните вообще с работы с чипом по SPI, только своим кодом.

Проще всего - прочитайте ID REGISTER  The identification number for the AD7798/AD7799 is stored in the ID register. This is a read-only register.

CS0, SPI_Write_8(0x60), CS1      коммуникационный регистр - установить режим чтения, работа с регистром ID
delay(10)  ms
CS0, x = SPI_Read_8(), CS1       читаем данные из ID

Считанный байт должен быть 0x*9. Если это работает (без сбоев), выполните туже операцию с использованием Ваших "старых" функций.

(что писать в коммуникационный регистр - 0x60 или .... проверьте)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ацп у меня работает в непрерывном режиме измерений. после считывания данных измерение должно запускаться автоматически. Reg_ID считывается как 0х49

#define AD7799_CS_LOW(selected_chip) AD7799_CS_PORT->ODR &=~(selected_chip);
#define AD7799_CS_HIGH(selected_chip) AD7799_CS_PORT->ODR |=(selected_chip);

AD7799_CS_LOW(AD7799_CHIP3);
	SPI1->DR = 0x60; 
	while(!(SPI1->SR & SPI_SR_RXNE));

	weigt[3] = SPI1->DR; 
AD7799_CS_HIGH(AD7799_CHIP3);
AD7799_CS_LOW(AD7799_CHIP3);
	SPI1->DR = 0x60; 
	while(!(SPI1->SR & SPI_SR_RXNE));

	weigt[3] = SPI1->DR; 
AD7799_CS_HIGH(AD7799_CHIP3);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...