|
Проблема с термопарой, ... или с АЦП ? |
|
|
|
Aug 5 2010, 15:23
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Делаю терморегулятор для печи. Термопару для отладки взял от китайского тестера (в фторопластовой изоляции с разъемом на конце). Индикация - четыре 7-сегментных знакоместа. Вывожу значение напряжения с первого канала, куда подключена термопара. Отрицательный вывод термопары соединен с опорным напряжением +2,5В, которое является опорным для АЦП (AD7799). Режим измерения - биполярный. Проблема в том, что при правильном подключении термопары ("-" к AIN1-, "+" к AIN1+) значение напряжения неизменное от температуры (прикладываю конец ТП к включенной настольной лампе). Если же подключить ТП наоборот к АЦП, то, значение меняется по температуре, но, естественно, в обратную сторону. В чем может быть дело?
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
|
Aug 6 2010, 11:04
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Выкладываю сырцы. Код // HEADER //----------------------
// AD7799 macro definitions #define AD7799_CS_ACTIVE PORTC &= ~(1 << CS) #define AD7799_CS_INACTIVE PORTC |= (1 << CS)
#define NMAX 3
#define AVCC 5.0 // AVCC = +5.0 V #define VREF 2.5 // VREF = +2.5 V #define TMP_SEN 0.01 // Temperature sensor sensitivity tmp36, V/C #define OFFSET_VOLTAGE 0.5 // Offset voltage of TMP36 (0.5 V)
#define STEPS_U 16777216.0 // Full-Scale 2^24 for unipolar operation #define STEPS_B 8388608.0 // Full-Scale 2^(24-1) for bipolar operation
#define TC 0 #define CJ 1
typedef struct { unsigned char Channel; // каналы //double TemperatureCJ; // температура TMP36 double TemperatureTC; // температура термопары long Data[2]; // Значения АЦП для двух каналов }RESULT;
extern RESULT Result;
typedef struct { int Index; // номер диапазона температур int Threshold; // температурный порог int Hysteresis; // гистерезис int Average; // усреднение double Offset[6]; // значения смещений для разных диапазонов температур double Reference[6]; // реперные точки }VALUE;
extern VALUE Value;
typedef struct { unsigned char volatile One; // Первое (младшее) знакоместо unsigned char volatile Ten; // Второе знакоместо unsigned char volatile Hundred; // Третье знакоместо unsigned char volatile Thousand;// Четвертое (старшее) знакоместо }DIGIT;
//////////////////////////////////////// // SOURCE //-----------------------------------
// AD7799 Initialization //------------------------------------------------------------------------------ void ad7799_Init() { ad7799_Reset(); delay_ms(500); ad7799_InitStatus = ad7799_Status(); }
// Запуск непрерывного преобразования на AIN1 //------------------------------------------------------------------------------ void ad7799_StartMeasure() { AD7799_CS_ACTIVE; ad7799_WriteConfig(1, 0, AD7799_128_GAIN, 1, 1, AD7799_AIN1_CHAN); // burnout, bipolar, gain, ref_det, buf, chan ad7799_SetMode(AD7799_CONTINUOUS_CONVERSION_MODE, 0, AD7799_16_7_1_HZ); // mode, psw=0(OFF), rate }
//------------------------------------------------------------------------------ void ad7799_Measure() { Result.Data[Result.Channel] = 0; while(!ad7799_DataReady()); // Ждать окончания преобразования АЦП (RDY => 0) ad7799_RequestData(CONTINUOUS_READ); // 1 -> Continuous Read PORTD &= ~(1 << DIN); // Held Low in Continuous-Read mode for(unsigned char i = 0; i < Value.Average; i++) // (1 << NMAX) { while(!ad7799_DataReady()); // Ждать окончания преобразования АЦП (RDY => 0) Result.Data[Result.Channel] += ad7799_ReadData(); // Накапливаем результат } Result.Data[Result.Channel] /= Value.Average; // >>= NMAX; // Усреднение результата while(!ad7799_DataReady()); // Ждать окончания преобразования АЦП (RDY => 0) ad7799_RequestData(NOT_CONTINUOUS_READ); // 0 -> Not Continuous Read // Maintain multiplexing of input channels //if(++Result.Channel > 2) // Result.Channel = 0; switch(Result.Channel) { case AD7799_AIN1_CHAN: ad7799_WriteConfig(1, 0, AD7799_128_GAIN, 1, 1, AD7799_AIN1_CHAN + Result.Channel); // burnout, bipolar, gain, ref_det, buf, chan break; case AD7799_AIN2_CHAN: ad7799_WriteConfig(1, 0, AD7799_2_GAIN, 1, 1, AD7799_AIN1_CHAN + Result.Channel); // burnout, bipolar, gain, ref_det, buf, chan break; } }
void Initialise() { ..... Result.Channel = 0; ad7799_Init(); ad7799_StartMeasure(); }
void main() { Initialise(); // set up I/O registers, flags & variables
__enable_interrupt(); // allow all enabled interrupts for(;;) { ad7799_Measure();
Result.TemperatureTC = Vtc(Result.Data[TC]) * 1000;
__sleep(); //Idle. Спать до следующего прерывания } }
// Вычисление напряжения термопары, В //------------------------------------------------------------------------------ double Vtc(long AdcValue) { return (AdcValue - STEPS_B) * VREF / 128 / STEPS_B; }
// Timer/Counter0 Overflow ISR: Вызывается с интервалом 4 мс // Вывод значения на индикатор и обработка нажатия кнопок. //------------------------------------------------------------------------------ #pragma vector=TIMER0_OVF_vect __interrupt void TIMER0_OVF_ISR() { // Динамическая индикация четырехразрядного индикатора switch(znak) { case 0: { int temp = (pValue == &Result.TemperatureTC) ? (int)(Result.TemperatureTC * 10) : *(int*)pValue; // Преобразовать значение *pValue в BCD число: bin2bcd(ABS(temp)); if(temp < 0) { if(temp > -10) { Digit.Ten = MINUS; Digit.Hundred = EMPTY; Digit.Thousand = EMPTY; } else if(temp > -100) { Digit.Hundred = MINUS; Digit.Thousand = EMPTY; } else if(temp > -1000) Digit.Thousand = MINUS; } else { if(temp < 10) Digit.Ten = EMPTY; if(temp < 100) Digit.Hundred = EMPTY; if(temp < 1000) Digit.Thousand = EMPTY; } } digit(znak++); // Включить первый (младший) разряд индикатора // Преобразовать значение единиц индикатора в 7-сегментный код и вывести в порт display(Digit.One); break; case 1: digit(znak++); // Включить второй разряд индикатора // Преобразовать значение десятков индикатора в 7-сегментный код и вывести в порт display(Digit.Ten); if((pValue == &Result.TemperatureTC) && (Result.TemperatureTC < 1000)) { PORTB |= (1 << POINT); } else { PORTB &= ~(1 << POINT); } break; case 2: digit(znak++); // Включить третий разряд индикатора // Преобразовать значение сотен индикатора в 7-сегментный код и вывести в порт display(Digit.Hundred); break; case 3: digit(znak); // Включить четвертый (старший) разряд индикатора // Преобразовать значение тысяч индикатора в 7-сегментный код и вывести в порт display(Digit.Thousand); znak = 0; break; } }
|
|
|
|
Сообщений в этой теме
alux Проблема с термопарой Aug 5 2010, 15:23 Tanya Цитата(alux @ Aug 5 2010, 19:23) Отрицате... Aug 5 2010, 15:54 alux по даташиту напряжение на входе при включенном буф... Aug 5 2010, 20:23  Tanya Цитата(alux @ Aug 6 2010, 00:23) по даташ... Aug 6 2010, 03:10 MrYuran Цитата(alux @ Aug 5 2010, 19:23) Отрицате... Aug 5 2010, 20:32 alux Цитата(MrYuran @ Aug 5 2010, 23:32) Поясн... Aug 6 2010, 05:57  MrYuran Цитата(alux @ Aug 6 2010, 09:57) Покажите... Aug 6 2010, 06:05  Tanya Цитата(alux @ Aug 6 2010, 09:57) Что имен... Aug 6 2010, 06:28 alux Блин, ерунда какая-то...
Подключил отрицательный в... Aug 6 2010, 07:54 MrYuran Цитата(alux @ Aug 6 2010, 11:54) Блин, ер... Aug 6 2010, 08:04  alux Цитата(MrYuran @ Aug 6 2010, 11:04) А на ... Aug 6 2010, 08:18   Tanya Цитата(alux @ Aug 6 2010, 12:18) В принци... Aug 6 2010, 09:50 Tanya Цитата(alux @ Aug 6 2010, 11:54) В чем де... Aug 6 2010, 08:09 sensor_ua Странно это. Выглядит как попутанные шнурки тестер... Aug 6 2010, 10:04 sgrig Самое интересное вот здесь:
Цитата(alux @ Aug... Aug 6 2010, 11:43  alux продолжение...
Код//------------------------------... Aug 6 2010, 11:51   Tanya Цитата(alux @ Aug 6 2010, 15:51) продолже... Aug 6 2010, 12:10 sensor_ua Код(AdcValue - STEPS_B) * VREF / 128 / STE... Aug 6 2010, 13:37 alux Цитата(sensor_ua @ Aug 6 2010, 16:37) Код... Aug 6 2010, 13:45 sensor_ua ЦитатаОбратили внимание
Обратил. Но там тоже есть ... Aug 6 2010, 14:04 Tanya Цитата(sensor_ua @ Aug 6 2010, 18:04) В д... Aug 6 2010, 14:39 alux В симуляторе проверил функцию Result.TemperatureTC... Aug 6 2010, 18:36 MrYuran А если откинуть пока лишнюю математику и посмотрет... Aug 6 2010, 18:42 alux Для этого необходимо либо UART, либо ЖКИ. Aug 6 2010, 18:55 Tanya Цитата(alux @ Aug 6 2010, 22:55) Для этог... Aug 7 2010, 03:36 alux чтобы выводить 8-значные числа кодов АЦП.
PS. Оч... Aug 7 2010, 06:19 sgrig Burnout выключите. Какой проц используете? JTAG ил... Aug 7 2010, 07:12 alux Burnout выключен, - проблема та же.
ATmega8535. Б... Aug 7 2010, 07:47 sgrig А сколько сегментов на индикаторе?
Для меня сомни... Aug 7 2010, 08:02 alux я переделал под целочисленную арифметику, по совет... Aug 7 2010, 10:53 Tanya Цитата(alux @ Aug 7 2010, 14:53) На индик... Aug 7 2010, 11:11 sensor_ua Так сколько показывает? И какое напряжение сигнала... Aug 7 2010, 11:44 alux Цитата(sensor_ua @ Aug 7 2010, 14:44) Так... Aug 7 2010, 12:11  Tanya Цитата(alux @ Aug 7 2010, 16:11) Объяснит... Aug 7 2010, 12:18 sensor_ua Самое простое, если у Вас 8-и-сегментные индикатор... Aug 7 2010, 13:15 alux Цитата(sensor_ua @ Aug 7 2010, 16:15) Пос... Aug 7 2010, 14:42 sensor_ua Насчёт long long Вы написали всё правильно и я на... Aug 7 2010, 15:53 alux Подключил UART. Отдельная плата с MAX232, соединяе... Aug 8 2010, 05:13 Krys Цитата(MrYuran @ Aug 6 2010, 03:32) Что-т... Aug 10 2010, 07:38 sensor_ua ЦитатаПолностью поддерживаю! Это следует из пр... Aug 10 2010, 14:45 Krys Цитата(sensor_ua @ Aug 10 2010, 21:45) АЦ... Aug 11 2010, 04:15
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|