Страница 1 из 1

Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 07:59:59
Gap
Решил собрать устройство измеряющую температуру с помощью двух термопар.
Собрал печатную плату, по следующей схеме:
СпойлерИзображение
*Красной линией обвёл часть отвечающую за усиление сигнала с термопар.

Написал код:
Спойлер

Код: Выделить всё

#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>

void Display(char Rank, char Number, char Point)
{
	switch(Rank)
	{
		case 0:
		PORTB = 0b00000000;
		break;
		case 1:
		PORTB = 0b00000001;
		break;
		case 2:
		PORTB = 0b01000000;
		break;
		case 3:
		PORTB = 0b10000000;
		break;
	}
	
	switch(Number)
	{
		case 0:
		PORTD = 0b00010100;
		break;
		case 1:
		PORTD = 0b01110111;
		break;
		case 2:
		PORTD = 0b01001100;
		break;
		case 3:
		PORTD = 0b01000101;
		break;
		case 4:
		PORTD = 0b00100111;
		break;
		case 5:
		PORTD = 0b10000101;
		break;
		case 6:
		PORTD = 0b10000100;
		break;
		case 7:
		PORTD = 0b01010111;
		break;
		case 8:
		PORTD = 0b00000100;
		break;
		case 9:
		PORTD = 0b00000101;
		break;
	}
	
	if(Point == 1)
	PORTD &= 0b11111011;
	
	_delay_ms(1);
}
void Complex_Display(int Number, char Point1, char Point2, char Point3)
{
	int Number1, Number2, Number3;
	
	Number1 = (char) (Number / 100);
	Number2 = (char) (Number - Number1*100)/10;
	Number3 = (char) (Number - Number1*100 - Number2*10)/1;
	
	Display(3, Number1, Point1);
	Display(2, Number2, Point2);
	Display(1, Number3, Point3);
}

int main(void)
{
	int data = 0;  //+++
	int Real_Temperature = 0;  //+++
	
	//PD5 - A, PD7 - B, PD3 - C, PD1 - D, PD0 - E, PD6 - F, PD4 - G, PD2 - DP;
	DDRD = 0xFF;
	PORTD = 0x00;
	
	//PB7 - 0 разряд, PB6 - 1 разряд, PB0 - 2 разряд; 
	DDRB = 0b11000001;
	PORTB = 0b00001110;
	
	SFIOR = 0x00;  //+++
	ADCSRA = 0x85;   //+++
	while(1)  
	{
		//Первый режим
		while(1)
		{
			ADMUX = 0x40;    //+++
			ADCSRA |= 0x40;     //+++
			data = ADCW;    //+++
			
			Real_Temperature = data*0.0048828*170;     //+++
			Real_Temperature = Real_Temperature;     //+++
			
			for(int x = 0; x < 100; x++)
			Complex_Display(Real_Temperature, 0, 0, 0);
			
			if(!((1 << PINB1)&PINB))
			{
				while(!((1 << PINB1)&PINB)){}
				break;
			}
		}
		
		//Второй режим
		while(1)
		{
			ADMUX = 0x42;    //+++
			ADCSRA |= 0x40;    //+++
			data = ADCW;    //+++
			
			Real_Temperature = data*0.0048828*200;    //+++
			Real_Temperature = Real_Temperature;    //+++
			
			for(int x = 0; x < 100; x++)
			Complex_Display(Real_Temperature, 0, 0, 0);
			
			if(!((1 << PINB1)&PINB))
			{
				while(!((1 << PINB1)&PINB)){}
				break;
			}
		}
	}
}
*Код отвечающий непосредственно за измерения пометил комментарием: "//+++".

Как видно, обе части отвечающих за измерение температуры построены абсолютно одинаково, как аппаратно, так и программно.
Но значения меряют по разному. Если подышать на термопары, то термопара подключённая к PC0 покажет изменения в температуре, а термопара подключённая к PC2 никак не отреагирует. В теплой воде PC0 показывает температуру примерно на 7 выше, чем PC2. Температуру пара в чайнике показывают одну и туже. Это не просто разница в чувствительности, разница между PC0 и PC2 не стабильно 7 градусов.

*Термопары одинаковые. Менял местами, ничего не изменилось.

В чем может быть проблема?

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 08:51:29
Flasher
C такой смехатехникой, не удивительно...
Зачем R4 R8 ?
Кто разрешил 358 нагружать на емкость? Почему не нагружен на активное сопротивление?
Кто решил ставить в обратной связи подстроечники?
У тебя там самовозбуд, наверняка...

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 09:22:47
Gap
Подсмотрел в гугле...)
СпойлерИзображение
Изображение
Изображение
Ещё тут: http://avrproject.ru/publ/kak_podkljuch ... u/2-1-0-70

Насколько я понимаю R4, R8 с составляющие фильтра. А подстроечные резисторы для калибровки термопары.

А можно по подробнее, как правильно?

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 09:36:41
Flasher
Обрати внимание на последнюю картинку-схему. Она самая грамотная, так как является вольной переделкой весьма продуманной схемы от аналог девайсес.
Там хоть и поставили подстроечник, но при этом избавились от возбуда, добавив конденсатор в ОС. R9 там является частью схемы усилителя, а не просто последовательным резистором.
А 358 нагрузи 10 кОм.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 09:42:59
uk8amk
1. При однополярном питании на входы + ОУ принято подавать некоторое напряжение смещения. После усиления это напряжение вычитают.
2. Перед чтением результата АЦП
data = ADCW; //+++
рекомендуется подождать флага готовности. АЦП - штука медленная и не выдаёт ответ сразу.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 10:14:27
Gap
Ради интереса... провёл эксперимент. Налил в кружку кипяток и каждые 30 секунд мерял температуру. Построил график:
СпойлерИзображение
*Температура приведена без компенсации холодного спая.

Добавлено after 16 minutes 52 seconds:
Flasher, спасибо за указание правильного направления. Но, обвязка неправильная как на PC0, так и на PC2, тогда почему измерения разные?

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 10:55:09
bob1
[uquote="Gap",url="/forum/viewtopic.php?p=3126209#p3126209"]В чем может быть проблема?[/uquote] Отсоединить один выход LM358. Соединить PC0 и PC2 вместе. Определитесь камень или аналоговая часть. Можно в принципе и цешкой замерить на выходах LM358. АЦП работает в диапазоне до 100ед.....???

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 12:03:12
Gap
uk8amk, добавил флаг готовности следующим образом:

Код: Выделить всё

while(ADCSRA != 0x95){}
data = ADCW;
ADCSRA |= 0x10;
Ничего не изменилось.

Добавлено after 1 hour 4 minutes 22 seconds:
bob1, отсоединил один выход LM385, которая идет к PC2. И соединил на Atmega8A PC0 и PC2. Разница есть, причем чем выше температура, тем выше разница. При измерении температуры пара в чайнике, разница в 13 градусов. Причем PC0 < PC2.

P.s. Забыл сказать. Прежде, когда PC0 не было соединено c PC1. Я, когда мерял температуру пара, с помощью подстроечных резисторов настроил термопары так, что б они показывали одинаковую температуру. Возможно именно поэтому на графике в моей предыдущем сообщении, чем ниже температура, тем выше разница.

P.s.s. Сейчас вспомнил... Достаточно давно, я случайно сделал КЗ на этом микроконтроллере (подключил AREF и AVCC к земле), которое заметил, только после того как он раскалился. Возможно здесь собака и зарыта. К сожалению на данный момент не имею другого кристалла для проверки.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 18:54:13
COKPOWEHEU
Код ужасен. Динамическую индикацию обычно делают на прерывании таймера либо в бесконечном цикле с низкой частотой (порядка 200-1000 Гц), делать как у вас сейчас - нарываться на неодинаковую яркость сегментов, гашение первых и засветы. Для выбора комбинации диодов для каждой цифры заводят массив констант, из которого выбирают по индексу. Также и с разрядами. Отдельные биты стоит оборачивать в макросы чтобы было удобно изменять если что:

Код: Выделить всё

#define SEG_A (1<<0)
#define SEG_B (1<<4)
#define SEG_C (1<<7)
...
#define SEG_PORT PORTA
const uint8_t segs[] = {
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, //0
  SEG_B | SEG_C, //1
  SEG_A | SEG_B | SEG_D | SEG_E | SEG_G,
...
};
#define DIGIT_1 (1<<0)
#define DIGIT_2 (1<<1)
#define DIGIT_3 (1<<5)
const uint8_t digits[3] = {DIGIT_1, DIGIT_2, DIGIT_3};
#define DIGIT_PORT PORTB

uint8_t videobuf[3] = {0,0,0};

ISR( TIMER0_OVF_vect){
  static uint8_t digit = 0;
  SEG_PORT = 0;
  DIGIT_PORT |= digits[ digit ];
  digit++;
  if(digit > 3)digit = 0;
  DIGIT_PORT &=~ digits[ digit ];
  SEG_PORT |= videobuf[ digit ];
}

void display_int(uint8_t x){
  videobuf[0] = x % 10;
  x /= 10;
  videobuf[1] = x % 10;
  videobuf[2] = x / 10;
}
примерно так. Писал из головы, только чтобы общая идея была понятна. Тут - полноценная реализация.

ADMUX = 0x42; //+++
ADCSRA |= 0x40; //+++
data = ADCW;
Почему не дожидаетесь окончания преобразования?
У вас вроде еще PC1 свободен, что если подключить его в параллель к PC0 или PC2 - может он более линеен? Соединять AREF с VCC - плохая идея.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Ср июн 14, 2017 19:30:29
Gap
COKPOWEHEU, спасибо за наводку по индикации.
К PC1 у меня подключён терморезистор, который измеряет температуру помещения для компенсации холодного спая.
В одном из моих предыдущих комментариев, добавил в код ожидание окончания преобразования.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Пт июн 16, 2017 16:14:32
Gap
Короче говоря... Поставил другую Atmega8A, разница в измерениях осталась, как PC0 показывал меньше PC2 так и показывает... и тут я в панике вспоминаю код... вспоминаю следующие строки:

Код: Выделить всё

Real_Temperature = data*0.0048828*170;     //+++
Real_Temperature = data*0.0048828*200;    //+++
Температуру на PC0 я рассчитывал по одной формуле, а на PC2 по другой)
В общем одинаковые значения показывают АЦП PC0 и PC2. Значит ошибка где то в аналоговой части.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Вс июн 18, 2017 07:50:21
Demiurg
Динамическая индикация реализуется и в основном цикле. Если итерация основного цикла выполняется с запасом по значению времени системного тика.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Вс июн 18, 2017 18:24:55
COKPOWEHEU
Можно и в основном цикле. Главное чтобы за одну итерацию обрабатывалось не более одного разряда. Тем более что требования к точности временных интервалов там минимальны.

Re: Существует ли разница между АЦП в Atmega8A?

Добавлено: Пн июн 19, 2017 04:31:53
Demiurg
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=3128807#p3128807"]Главное чтобы за одну итерацию обрабатывалось не более одного разряда.[/uquote]
Пффф. Дык этта... Флаги или программные таймеры. И точность обеспечена. Плюс-минус десяток-другой мкс в расчет не берем.

Добавлено after 9 hours 42 minutes 11 seconds:
Кстати, жареный мк лучше либо выбросить, либо отказаться от ацп.