Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с АЦП ADuC841
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
Лядин Олег
Работаю с АЦП ADuC841.
Программу пишу в IAR.
Просто считываю значения с ацп и передаю на жк.
Переодически проскакивают левые значения (с жк всё в порядке).
И по прерываниям пробовал и единичные преобразования.
Что-то делаю не так, не могу понять что.
Вот кусок программы (один из вариантов):
IE=0x00;
// Инициализация АЦП
SCON=0x52;
ADCCON1=0xEC; // насторойка регистра АЦП
ADCCON2=0x00; // выбор установленного канала
DACCON=0x3D;
// считывание данных с АЦП
ADCCON2=0x10; // еденичное преобразование
dalay(50);
if (ADCCON3<127) // проверяю бит готовности
{
j=ADCDATAH; // регистры данных АЦП
i=ADCDATAL;
ADCCON2=0x00;
KK=i+256*j; // в KK - значения с АЦП
shreck
Вот рабочий кусок кода. (сори, в вашем коде нет времени разбираться).
Хотел приатичить файл, но что-то не сумел, так что код в теле.

Код
/********************************************************************************
****

Выполняется измерение емкости, температуры и разряда батарей.
Используется timer2 autoreload

********************************************************************************
*****/

#include <ADUC841.H>
#include "settings.h"
#include "main.h"


extern void wait_us(uchar);

// полный период измерения
#define MEAS_PER    (65536-500*12)

// количество измерений каждого типа
#define C_NUM       500
#define T_NUM       300
#define B_NUM       100
// сумма T_NUM + B_NUM должна делиться на 4 нацело


//----------------------------------------------------------------------------------
//  global func. prototype
//----------------------------------------------------------------------------------
void init_meas(void);

        


//----------------------------------------------------------------------------------
//  static func. prototype
//----------------------------------------------------------------------------------
static void read_adc (void);



//----------------------------------------------------------------------------------
//  var
//----------------------------------------------------------------------------------

volatile bit meas_done=0;   // все измерения закончены

//dacs
static uchar code dacl1[4] = {0x99, 0x00, 0x00, 0x00};
static uchar code dach1[4] = {0x09, 0x00, 0x00, 0x00};
static uchar code dacl0[4] = {0x00, 0x00, 0x99, 0x00};
static uchar code dach0[4] = {0x00, 0x00, 0x09, 0x00};

static uchar idata l_state=0;   // состояние линий подергивания

// adc
static uint idata adc_result;

static ulong xdata _cap[2], _tmp, _bat; // изм. емкость, температура и батарея

static uint xdata meas_cnt; // счетчик измерения

enum {s_cap, s_tmp, s_bat} meas_state;  // текущее измерение




//----------------------------------------------------------------------------------
//  
//----------------------------------------------------------------------------------
void init_meas(void)
{
    meas_state = s_cap;

    meas_cnt = 0;
    _cap[0] = _cap[1] = 0x00L; _tmp = _bat = 0x00L;

    // adc
    ADCCON1 = 0xB8;  // ADC power up, int. ref, 6MHz-clock, 3 aq time(3.2uS)
    CFG841 |= 0x20;  // buffer off
    ADCCON2 = 0x05;

    // dacs
    DACCON = 0x1B;  // power on, 12bit, range: 0-Vref, sync
    

    // timer2 autoreload 500 uS
    RCAP2L = (uchar)(MEAS_PER & 0x00FF);
    RCAP2H = (uchar)(MEAS_PER >> 8);
    TH2 = RCAP2H;
    TL2 = RCAP2L;

    ET2 = 1;    // int. enable
    PT2 = 1;    // high priority

    TR2 = 1;    // start  
}



//----------------------------------------------------------------------------------
//  
//----------------------------------------------------------------------------------
void TIMER2_OVF(void) interrupt 5 using 2
{
    TF2 = 0;    // reset int. flag
    
    // подергивание
    DAC0L = dacl0[l_state]; DAC0H = dach0[l_state];
    DAC1L = dacl1[l_state]; DAC1H = dach1[l_state];
    DACCON |= 0x04; DACCON &= ~0x04;    // update dacs
    if (++l_state == 4) l_state = 0;



    wait_us(50);
    SCONV = 1;              // statrt conversion
    while (ADCCON3 & 0x80); // wait end of conv.
    read_adc();




    if (meas_state == s_cap)
    {
        if (l_state == 1) _cap[0] += adc_result; else
        if (l_state == 3) _cap[1] += adc_result;
        
        if (l_state == 0)   // цикл измерения закончен
        {
            if (++meas_cnt == C_NUM)    // измерение емкости закончено
            {
                if (!meas_done)
                {
                    cap = C0*((float)_cap[0]/(float)_cap[1]);
                    _cap[0] = _cap[1] = 0x00L;
                }

                meas_cnt = 0;
                meas_state = s_tmp;
                ADCCON2 = 0x00; // tmp chanal
            }
        }
    } else

    if (meas_state == s_tmp)
    {
        _tmp += adc_result;
        if (++meas_cnt == T_NUM)    // измерение температуры закончено
        {
            if (!meas_done)
            {
                tmp = _tmp/T_NUM;
                _tmp = 0x00L;
            }
            
            meas_cnt = 0;
            meas_state = s_bat;
            ADCCON2 = 0x06;     // batlow chanal
        }
    }

    else
    {
        _bat += adc_result;
        if (++meas_cnt == B_NUM)    // измерение разряда батарей закончено
        {
            if (!meas_done)
            {
                bat = _bat/B_NUM;
                _bat = 0x00L;

                meas_done = 1;
            }

            meas_cnt = 0;
            meas_state = s_cap;
            ADCCON2 = 0x05;     // cap chanal
        }
    }
}



//----------------------------------------------------------------------------------
//               Read ADCL and ADCH data registers
//----------------------------------------------------------------------------------
static void read_adc (void)
{
    uchar i;
    i = ADCDATAL;
    adc_result = (unsigned int)(i + (ADCDATAH & 0x0F )*256);
    return;
}
Roma_te
Попробуйте по входу АЦП поставить ВЧ конденсатор
Лядин Олег
Поставил емкость - получше стало. Но ещё есть над чем работать.
Roma_te
Цитата(Лядин Олег @ Oct 9 2006, 11:01) *
Поставил емкость - получше стало. Но ещё есть над чем работать.

Я когда работал с АЦП был приятно удивлен его стабильностью работы, поетому возможно у Вас проблема в следующем:
- слишком малая емкость конденсатора по входу
- большие пульсации опорного напряжения (Vref) и/или напряжения питания аналоговой части (AVdd)
- большие токи гуляют по линии AGND (неправильная разводка)
Лядин Олег
Да, конечно опора у меня не идеальна да и разводка тоже. Это пока макет.
Но быват что значения проскакивают такие, что биением опорного напряжения их не обьяснить. допустим принимаю значение 3Ah - в течении 10 сек, и вдруг проскакиват к примеру FFh. Опора я думаю не причём.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.