ATmega128 проблема переключения каналов АЦП

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Здравствуйте, не как не могу разобраться с данной проблемой.
Ацп работает в режиме автоматического перезапуска с частотой 12 кГц и тактовая частотой АЦП 156 кГц (1 такт АЦП 64 такта процессора). Прерывания внутри АЦП разрешены для работы таймера. Приведённый ниже код работает, переключение каналов происходит. Буфер накапливается и значения АЦП по USART забирается (с периодом 300мс). Но примерно пару раз в минуту данные идут не с того канала в частности в обработке канала I2_MAIN проскакивают значения из канала I_42_MAIN почему такое происходит?

Спойлер

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

////=============ADCinitialization=============
////ADCSRA=0;
//ADMUX=2;  //I1
//ADCSRA=(1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
//
//ADC_I42
//ADMUX=1; //slave in
//ADCSRA=(1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
////====================
interrupt [ADC_INT] void adc_isr(void){
#asm("sei")
    switch(adc_main){   
        case I1_MAIN:{     
             adc_main=I_42_MAIN;    //  Переход на измерения следующего канала 
             ADC_BUF->test_int[4]=ADCW;  //записали в буфер(данный буфер выдаётся в UART по запросу)
             ADMUX_TEMP=3; //I2 переключаемся на канал I2 через итерацию(для установления переходных процессов) с задержкой в 200 тактов
             //ADC_I28
            break;
        }    
        case I_42_MAIN:{
             adc_main=I2_MAIN;    //  Переход на измерения следующего канала
             ADC_BUF->test_int[3]=ADCW; //записали в буфер(данный буфер выдаётся в USART по запросу)
             ADMUX_TEMP=1;  //I28    переключаемся на канал I28 через итерацию (для установления переходных процессов) с задержкой в 200 тактов
            break;
        }
        case I2_MAIN:{     
        // Правильно значение АПЦ равно 647 в основном оно так и приходит но время от времени (пару раз в минуту)
        // Проскакивает значение с АЦП c предыдущего канала.
        // функция DEBUGER заносит в очередь ошибку(и значение АЦП) для отправки по USART 
   
                           if(ADCW>700){DEBUGER("ADCW_HIGEST=",0,ADCW,var2);}            
                           if(ADCW<600){
                             DEBUGER("ADC_INT_ADCW=",0,ADCW,var2);
                             LED_GREEN_DOWN();
                             test_I2[test_I2_index]=ADCH;
                             test_I2[test_I2_index+1]=ADCL;
                             test_I2_index++;
                             if(test_I2_index>14){test_I2_index=0;}
                           }            
                ADC_BUF->test_int[1]=ADCW; 
                adc_main=I28_SLAVE;
                ADMUX_TEMP=2;   //I
                //ADC_I42                 
            break;   
        }
        case I28_SLAVE:{
             adc_main=I1_MAIN;
             ADC_BUF->test_int[5]=ADCW;
             ADMUX_TEMP=1;
            break;
        }          
        default:{
            adc_main=I1_MAIN;            
            DEBUGER("adc_main=error",0,0,MESEGER);        
        }
    }   

#include <nop2.c>   // задержка 200 nop
 ADMUX=ADMUX_TEMP;
}
Реклама
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

nirq, то о чём говориться в той теме очень мало вероятно, так как у pokk-а она проявляется эпизодически и чётко различимы результаты. Если бы это были проблемы с качеством сэмплинга, то показания плавали бы.

pokk, каким компилятором пользуетесь?
Зачем 200 nop-ов? Они не нужны. Читайте внимательно спецификацию.
Раздел "Changing Channel or Reference Selection", прямо в начале.
Раздел "Register Description" - "ADMUX - ADC Multiplexer Selection Register" про соответствующие биты.
Рисунок "ADC Timing Diagram, Free Running Conversion".

Могу предположить (глядя на 200 nop-ов), что у вас есть ещё очень "длинные" обработчики прерываний или области кода с запрещёнными прерываниями. Соответственно, вероятна ситуация, и она иногда складывается, когда возникает пропуск вычитывания данных АЦП. Проанализируйте ваш алгоритм в этом направлении.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

Kavka, если телевизор не включается - начинаем ремонт с проверки напряжения в розетке, шнура от розетки до телевизора, кнопки ВКЛ в телевизоре или строчной развёртки? Почему не с кадровой развёртки начинаем?
Откуда известно, что мы вообще ремонтируем телевизор, а не например холодильник?



Получается как бы всё тот же анекдот про мужика, искавшего ключи под фонарём, только наоборот: у него украли паспорт в трамвае, а он ищет ключи с металлоискателем - потому что ключи искать он УМЕЕТ.
Но тут даже ещё смешнее, мужик сам не знает, что у него украли (но понимает, что явно чего-то не хватает в наличии). И поэтому ищет ключи. А советчики помогают их искать советами, ну которые тоже специалисты по поиску ключей.
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Я всего лишь написал, что это маловероятно. Если тебе будет легче, то это IMHO. Краткое обоснование моей точки зрения я тоже привёл. А ты про телевизор с фонарём... Лучше бы написал как описанная ситуация возникает по твоему мнению. Полезнее было бы.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

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

#asm("sei")
А для чего это в прерывании ? Вы представляете возможные последствия этого действия ?
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Благодарю всех за ответы, но так как тут долго не было ответа я ещё больше упростил программу до двух каналов и отписался в этой теме.
pokk, каким компилятором пользуетесь?
CodeVisionAVR
Зачем 200 nop-ов? Они не нужны. Читайте внимательно спецификацию.
Раздел "Changing Channel or Reference Selection", прямо в начале.
Изображение
Вот тут в течении 1.5 такта АЦП что происходит ? я понял что там происходит переключение MUX и фиксация текущего напряжения по этому переключением MUX суда за лазить не желательно. Ну и ещё эта задержка типа имитация программного кода. Так же хотел по смотреть как программа будет вести себя (сколько тактов будет выполнятся обработчик АЦП) при прерывании в обработчике АЦП от таймера несколько раз, а без задержки это очень редко происходит.
Могу предположить (глядя на 200 nop-ов), что у вас есть ещё очень "длинные" обработчики прерываний или области кода с запрещёнными прерываниями. Соответственно, вероятна ситуация, и она иногда складывается, когда возникает пропуск вычитывания данных АЦП. Проанализируйте ваш алгоритм в этом направлении.
Это вы имеет ввиду то что прерывание от таймера может забить обработчик АЦП, и из за того возникнет пропуск одного преобразования АЦП ? В принципе возможно так и происходит, но я смотрел по осциллографу там был запас.

Сейчас я переключил работу АЦП в режим однократного преобразования и в конце обработчика АЦП запускаю новое преобразование. Частота работы АЦП уменьшилась с 12 до 10 кГц. пр этом пока таких проскоков между каналами не наблюдаю. Но меня всё ещё интересуют описанные выше вопросы.
Друг Кота
Аватара пользователя
Сообщения: 6339
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

А кто заставляет использовать режим Free Running ? Мой опыт, да и Вы это подтвердили - режим однократного преобразования вполне решает задачу. Если, конечно, задача не : создать себе проблему а зачем, ломая голову : а почему так ? - героически ее преодолевать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

а почему Free-Running с прерываниями давало вам 12 кгц, а однократное с прерыванием всего 10? не думаю, что несколько тактов МК на перезапуск АЦП повлияли так заметно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

ARV, 12 кгц это где-то 833 тактов в однократном режиме на один такт ацп идёт больше это уже около 900 ну и на выполнение программы тактов 60 итого получается около 1000 тактов, а это уже как раз 10 кгц.
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

pokk писал(а):Вот тут в течении 1.5 такта АЦП что происходит ? я понял что там происходит переключение MUX и фиксация текущего напряжения
Переключение входа и "опоры" происходит в момент обозначенный левой вертикальной штрихорой линией. Затем, в течении 1.5 тактов идут все переходные процессы. В том числе и выравнивание напряжения на конденсаторе в АЦП с напряжением на входе выбранного канала. А окончание процесса выравнивания (фиксация) напряжения происходит в момент показанный правой штриховой линией.
Соответственно, в режиме непрерывного преобразования переключение канала может произойти только в момент окончания/начала преобразования, и регистр ADMUX можно записывать в любой момент так как он буфферизирован. О чём и написано в описании регистра ADMUX.
ARV писал(а):не думаю, что несколько тактов МК на перезапуск АЦП повлияли так заметно...
После установки бита ADSC запуск преобразования происходит не моментально, а по нарастающему фронту ADC clock. У pokk-а делитель 64...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Kavka, Благодарю за помощь теперь мне стало понятно почему что с задержками что без них всё одинакового работало =)
Ответить

Вернуться в «AVR»