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

 
 
> Xmega АЦП
Xeon
сообщение Mar 11 2012, 07:26
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 140
Регистрация: 21-04-11
Пользователь №: 64 524



Сначала приведу код , а потом расскажу в чём проблема:

Хэдер для АЦП:

Код
#define ADC_BUFFER_SIZE 256

/*
AdcConvertionMode - режим преобразования, знаковый или без знаковый (см. в даташите на странице )
        == 0 - беззнаковый режим
        == 1 - знаковый режим
Resolution - разрядность
        == 00 - 12 бит выравнивание справа
        == 01 - зарезервированно
        == 10 - 8 бит выравневание справа
        == 11 - 12 бит выравнивание слева
Reference - опорное напряжения
        == 00 - внутреннее 1.00V
        == 01 - внешнее VCC/1.6
        == 10 - внешнее на порту A.
        == 11 - внешнее на порту B.
Prescaler - делитель частоты АЦП
        == 000 - 4
        == 001 - 8
        == 010 - 16
        == 011 - 32
        == 100 - 64
        == 101 - 128
        == 110 - 256
        == 111 - 512
AdcPin - Вход АЦП
        == 000 - ADC0 pin
        == 001 - ADC1 pin
        == 010 - ADC2 pin
        == 011 - ADC3 pin
        == 100 - ADC4 pin
        == 101 - ADC5 pin
        == 110 - ADC6 pin
        == 111 - ADC7 pin
Values[ADC_BUFFER_SIZE] - буфер в котором хранятся преобразованные значения
CurVal - текущее количество значений в буфере
ConversionCnt - количество измерений которые надо сделать
Flags - текущее состояние АЦП
*/
struct ADC_cfg
{
    unsigned char    AdcConvertionMode;
    unsigned char    Resolution;
    unsigned char    Reference;
    unsigned char    Prescaler;
    unsigned char    AdcPin;
    
    unsigned short    Values[ADC_BUFFER_SIZE];
    unsigned short    CurVal;
    unsigned short    ConversionCnt;
    
    unsigned char    Flags;
} ADC_config;

#define ADC_STOPED                    0
#define ADC_STARTED                    1
#define ADC_CONVERSION_COMPLETE        2

void ADC_init();
void ADC_deinit();
void ADC_flush();
void ADC_start();
void ADC_wait();


Соурс для АЦП:

Код
void ADC_init()
{
    // нужную ногу настраиваем на вход
    PORTA.DIRCLR = 1 << ADC_config.AdcPin;
    
    // CTRLA - ADC Control Register A (см. в даташите на странице 302)
    // здесь просто включаем АЦП выставляя нуливой бит
    ADCA.CTRLA = 1;
    
    //     CTRLB - ADC Control Register B
    // здесь в зависимосте от настроек выставляем знак, режим, разрядность
    ADCA.CTRLB = ((ADC_config.AdcConvertionMode << ADC_CONMODE_bp) | (ADC_config.Resolution << 1));
    
    // REFCTRL - ADC Reference Control register
    // выставляем опорное напряжение
    ADCA.REFCTRL = (ADC_config.Reference << 4) | 2;
    
    // делитель частоты АЦП, по даташиту максимальная частота 2 МГц
    ADCA.PRESCALER = ADC_config.Prescaler;
    
    // Настраиваем мультиплексор
    ADCA.CH0.CTRL = 1;
    ADCA.CH0.MUXCTRL = ADC_config.AdcPin << 3;
    ADCA.CH0.INTCTRL = 3;
    
    ADC_config.CurVal = 0;
    ADC_config.Flags = ADC_STOPED;
}

void ADC_deinit()
{
    // отключаем АЦП
    ADCA.CTRLA = 0;
    ADC_config.Flags = ADC_STOPED;
}

void ADC_flush()
{
    // очистить АЦП
    ADCA.CTRLA |= 2;
    
    ADC_config.CurVal = 0;
    ADC_config.Flags = ADC_STOPED;
}    

void ADC_start()
{
    // начать преобразование
    //ADCA.CH0.CTRL |= 128;
    ADCA.CTRLA |= 4; // start channel 0
    ADC_config.Flags = ADC_STARTED;
}        

void ADC_wait()
{
    do {} while(ADC_config.Flags != ADC_CONVERSION_COMPLETE);
}

ISR(ADCA_CH0_vect)
{
    ADC_config.Values[ADC_config.CurVal] = ADCA.CH0.RES;
    //ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm;
    
    ADC_config.CurVal++;
    ADC_config.ConversionCnt--;
    
    if(ADC_config.ConversionCnt != 0)
    {
        ADC_start();
    }    
    else
    {
        ADC_config.Flags = ADC_CONVERSION_COMPLETE;
    }            
}


И как пользуюсь:

Код
// заполняем конфигурационную структуру
            ADC_config.AdcConvertionMode    = 0;    // без знаковый
            ADC_config.Resolution            = 0;    // 12 бит, выравневание справа
            ADC_config.Reference            = 0;    // внутрений источник опорного напряжения 1 В
            ADC_config.Prescaler            = 2;    // делитель частоты 64 (частота АЦП получается 2 МГц при тактовой частоте камня 500 КГц)
            ADC_config.AdcPin                = 0;    // выбираем ногу ADC0
            // инициализируем АЦП
            ADC_init();
            
            // устанавляваем количество преобразований
            ADC_config.ConversionCnt = ((unsigned short) ParseBuf[1]) << 8;
            ADC_config.ConversionCnt |= (unsigned short) ParseBuf[0];
            
            // запускаем цикл измерений
            ADC_flush();
            ADC_start();

            // ожидаем завершения цикла измерений
            [color="#FF0000"]_delay_us(50); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!![/color]
            ADC_wait();
            // отключаем АЦП
            ADC_deinit();



Проблема в следующем: если есть строка _delay_us(50); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! то всё работает норм, делаются нужное количество преобразований и отсылаются мне на комп... А вот если я убираю данную строку то программа зависает в функции ADC_wait(); (там цикл выполняется пока все преобразования не выполнятся). Флаг выставляется в прерывании АЦП (строчка ADC_config.Flags = ADC_CONVERSION_COMPLETE;)... Без вот этой задержки почему то не каких преобразований не делается, может конечно они делаются но прерывание не срабатывает!!!
Люди, может я что то упускаю из особенностей работы с данным АЦП?

Вот если нужно проект для AVR Studio 5: Прикрепленный файл  ADC.rar ( 290.39 килобайт ) Кол-во скачиваний: 106

Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Xeon   Xmega АЦП   Mar 11 2012, 07:26
- - Палыч   Вероятно, не хватает volatile при описании Flags   Mar 11 2012, 07:40
|- - Xeon   Цитата(Палыч @ Mar 11 2012, 10:40) Вероят...   Mar 11 2012, 08:34
|- - Палыч   Цитата(Xeon @ Mar 11 2012, 12:34) А зачем...   Mar 11 2012, 08:54
|- - Xeon   Цитата(Палыч @ Mar 11 2012, 11:54) Поскол...   Mar 11 2012, 09:24
|- - Палыч   Цитата(Xeon @ Mar 11 2012, 13:24) А можно...   Mar 11 2012, 09:42
|- - Xeon   Цитата(Палыч @ Mar 11 2012, 13:42) Выполн...   Mar 11 2012, 12:58
|- - Палыч   Цитата(Xeon @ Mar 11 2012, 16:58) Если я ...   Mar 11 2012, 15:37
|- - Xeon   Цитата(Палыч @ Mar 11 2012, 19:37) Да, эт...   Mar 11 2012, 16:53
- - Xeon   И снова Всем привет! Ситуация следующая нужно ...   Mar 28 2012, 10:39
- - ASDFG123   Как у Xmega 32 A4 дела с ацп ? померить нужно импу...   Apr 5 2013, 06:19
|- - Herz   Цитата(ASDFG123 @ Apr 5 2013, 09:19) Как ...   Apr 5 2013, 06:36
- - ASDFG123   почитал отзывы по ней, и ацп в пред. ревизиях не р...   Apr 5 2013, 07:11
|- - _Артём_   Цитата(ASDFG123 @ Apr 5 2013, 10:11) дата...   Apr 5 2013, 08:10
|- - Herz   Цитата(ASDFG123 @ Apr 5 2013, 10:11) Нужн...   Apr 5 2013, 10:46
|- - vitas56   Цитата(ASDFG123 @ Apr 5 2013, 11:11) почи...   Apr 27 2013, 04:13
- - ASDFG123   да 6 мс, ну вольтметр это я очень упрощенно сказал...   Apr 26 2013, 16:24


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

 


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


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