реклама на сайте
подробности

 
 
> Проблема с термопарой, ... или с АЦП ?
alux
сообщение Aug 5 2010, 15:23
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Делаю терморегулятор для печи. Термопару для отладки взял от китайского тестера (в фторопластовой изоляции с разъемом на конце). Индикация - четыре 7-сегментных знакоместа. Вывожу значение напряжения с первого канала, куда подключена термопара. Отрицательный вывод термопары соединен с опорным напряжением +2,5В, которое является опорным для АЦП (AD7799). Режим измерения - биполярный.

Проблема в том, что при правильном подключении термопары ("-" к AIN1-, "+" к AIN1+) значение напряжения неизменное от температуры (прикладываю конец ТП к включенной настольной лампе). Если же подключить ТП наоборот к АЦП, то, значение меняется по температуре, но, естественно, в обратную сторону. В чем может быть дело?
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
alux
сообщение Aug 6 2010, 11:04
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 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;
    }
}
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 15:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.01451 секунд с 7
ELECTRONIX ©2004-2016