Перейти к содержанию
    

При работе с АЦП делаю заранее заданное демпфирование по каналам. То есть порядок выборки каналов у меня постоянно скачет. Это поменять нельзя. АЦП запущено в "Free running mode" и проверяется по таймеру. Время с момента переключения канала и до выборки значения АЦП вдвое превышает означенные 25 тактов (пробовал и увеличивать).

 

По каким-то, для меня непонятным причинам, иногда (достаточно редко) с АЦП в память попадает не текущее значение АЦП (точнее не то, что должно быть), а с предыдущего канала. Причём если я в данной точке останавливаюсь по JTAG, то в АЦП микросхемы вижу правильное значение. Например:

    127             default:
    128               x0=Adc[TekChan].X1=ADCH;                            // Прочитать значение АЦП
   \                     ??pvPWWLvl1_7:
   \   000000B8   91300079           LDS     R19, 121
   \                     ??pvPWWLvl1_9:
   \   000000BC   8334               STD     Z+4, R19
   \   000000BE   2E23               MOV     R2, R19

То есть по databreakpoint останавливаюсь в последней строчке и вижу в АЦП значение FF к примеру, а в ячейку уже занесено 83. Каналы и всё прочее выставляется верно.

 

Создаётся впечатление, что АЦП не успевает завершить операцию. Но, как я уже писал, при увеличении времени в разы сама ошибка остаётся.

 

Может я чего не знаю. Может необходимо как то обновить значение. Типа прочитать два раза или что-то ещё.

 

Я в непонятках.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Но я "Free running mode" никогда не применял, поэтому это только догадки. В datasheet этот момент описан как-то обтекаемо и я до конца его смысл не понимаю :( Там в явном виде не написано, что допускается переключать канал в любое время.

 

А почему вы применили "Free running mode"? Я всегда применяю одиночные преобразования по таймеру и никогда таких проблем не имел. Для гарантии окончания переходных процессов после переключения каналов можно просто проводить АЦП через раз:

перекл.канал / вкл.АЦП / прочитали результат, перекл.канал / вкл.АЦП / прочитали результат, перекл.канал / и т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При переключении мультиплексора, вроде, рекомендуют делать холостое измерение, это даже гдето в даташитах написано...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я тоже склоняюсь к мысли, что это биения от несовпадения частоты преобразования и частоты чтения/смены канала.

АЦП запущено в "Free running mode" и проверяется по таймеру.
Т.е. вы его читаете в прерывании таймера и иногда меняете канал? В описании сказано примерно так, что если преобразование уже началось, то смена канала подействует только при следующем преобразовании. Это не ваш случай?

Если я правильно понял раздел ADC Input Channels, то в вашем случае сделал бы так: сбросил ADIF, вычитал ADCH, проверил бы ADIF, если он снова стоит - повторил бы сброс и чтение, записал в ADMUX новый канал, дождался ADIF, отбросил бы этот результат (он скорее всего от предыдущего канала), ждал следующего ADIF.

 

Но я тоже не использовал его в режиме FreeRunning.

 

это даже гдето в даташитах написано...
Где конкретно? Покажите мне это место в даташите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну может не в даташитах :) но на форуме эта тема поднималась и не раз... и каждый раз все говорили - "ну его ф топку этот фри ран..." :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"ну его ф топку этот фри ран..." :)
Вот и я при чтении даташита пришел к тому же выводу - в режиме FreeRunning, если канал переключается не в прерывании АЦП первое измерение после переключения канала может относится как к старому, так и к новому каналу, поэтому его нужно отбросить. Это логически вытекает из описания и понятно. Но именно в режиме FreeRunning, если канал переключается не в прерывании АЦП, а не просто "При переключении мультиплексора". Поэтому я и уточнил - может есть еще какие-то тонкости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Где конкретно? Покажите мне это место в даташите.

Рекомендация о пропуске первого результата при смене канала во Free Running Mode действительно где-то была (то ли в даташитах, то ли в аппнотах).

Вот и я при чтении даташита пришел к тому же выводу - в режиме FreeRunning, если канал переключается не в прерывании АЦП первое измерение после переключения канала может относится как к старому, так и к новому каналу, поэтому его нужно отбросить.

Не совсем так. С точки зрения АЦП измерение по-любому будет относиться к старому каналу, а переключение на новый произойдет только после окончания преобразования по старому каналу. Более того, старый результат будет читаться вплоть до окончания первого преобразования по новому каналу.

Ну а с точки зрения программы действительно непредсказуемо.

 

Если чтение выполняется по какому-нибудь тику с периодом, заведомо большим времени преобразования АЦП, то проще всего переключение и чтение синхронизировать софтовым флагом, взводимым при переключении канала и сбрасываемым при чтении результата АЦП.

// on ADC channel change
   SkipADCResult = 1;
...
// on ADC read
   if(SkipADCResult) SkipADCResult = 0;
   else x0=Adc[TekChan].X1=ADCH;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понимаю процесс жизнедеятельности этого АЦП, мультиплексор каналов никак не синхрится от самого процесса преобразования.

Поэтому вполне очевидно, что при переключении мультиплексора в произвольные моменты времени на выходе АЦП могут быть любые результаты, в том числе, и вообще не относящиеся к какому-либо каналу. Ведь выборка УВХ длится 1,5 такта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понимаю процесс жизнедеятельности этого АЦП, мультиплексор каналов никак не синхрится от самого процесса преобразования.

Поэтому вполне очевидно, что при переключении мультиплексора в произвольные моменты времени на выходе АЦП могут быть любые результаты, в том числе, и вообще не относящиеся к какому-либо каналу. Ведь выборка УВХ длится 1,5 такта.

Неправильно понимаете.

Физическое переключение каналов выполняется только по окончании текущего преобразования.

The MUXn and REFS1:0 bits in the ADMUX Register are single buffered through a temporary

register to which the CPU has random access. This ensures that the channels and reference

selection only takes place at a safe point during the conversion. The channel and reference

selection is continuously updated until a conversion is started. Once the conversion starts, the

channel and reference selection is locked to ensure a sufficient sampling time for the ADC.

Соответственно выборка производится с совершенно конкретного канала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понимаю процесс жизнедеятельности этого АЦП, мультиплексор каналов никак не синхрится от самого процесса преобразования.
Напрасно вы так понимаете. В описании написано другое - запись из регистра в мультиплексор блокируется в начале преобразования. Т.е. что было в регистре на момент начала преобьразования - то и окажется в мультиплексоре.

 

 

Не совсем так. С точки зрения АЦП измерение по-любому будет относиться к старому каналу, а переключение на новый произойдет только после окончания преобразования по старому каналу.
Ну да. А поскольку оно FreeRunning, то предугадать, когда этот момент наступит относительно нашей записи в регистр мультиплексора невозможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хочу тоже задать вопрос!

МК ATmega8, задействован только один канал.

При непрерывном преобразовании нужно ли разрешать прерывания АЦП?

 

И ещё такой вопрос. Можно ли в режиме одиночного преобразования запускать АЦП (ADSC=1) один раз в 1 мсек, например в прерываниях таймера ТС0. Сделать 16 измерений, все 16 результатов просуммировать и сумму сдвинуть вправо на 4 разряда. Такими действиями можно убрать колебания 2 мл разрядов АЦП? И ещё: нужно ли потом результат обрабатывать по алгоритму скользящего среднего?

Может туманно написал, так извините! :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При непрерывном преобразовании нужно ли разрешать прерывания АЦП?

Можно не разрешать

 

Можно ли в режиме одиночного преобразования запускать АЦП (ADSC=1) один раз в 1 мсек, например в прерываниях таймера ТС0. Сделать 16 измерений, все 16 результатов просуммировать и сумму сдвинуть вправо на 4 разряда. Такими действиями можно убрать колебания 2 мл разрядов АЦП?

Можно. Это и есть оверсамплинг.

 

И ещё: нужно ли потом результат обрабатывать по алгоритму скользящего среднего?

А это как вы хотите. Если больше колебаний не наблюдается, то зачем это делать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно не разрешать

Можно. Это и есть оверсамплинг.

А это как вы хотите. Если больше колебаний не наблюдается, то зачем это делать?

 

спасибо, это то что я хотел услышать!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не буду утверждать, так как для каких либо утверждений требуется произвести соответствующие исследования. Но на мой взгляд, я делаю всё верно. Тем не менее хомуты есть. Особенно настораживает то что происходят они не регулярно, а крайне редко. Что наводит на размышления о каких то хомутах отнюдь не в проге.

 

Спасибо всем - я всё устранил. Теперь всё работает.

 

Общие замечания такие. Согласно даташиту (в моём прочтении) в режиме FRM, не требуется сбрасывать флаг ADIF как и не требуется запускать преобразование. Это происходит автоматически. Ты можешь просто читать текущее значение. Я не нашёл время первого измерения относительно смены канала, но похоже оно должно быть 25 тактов АЦП. Все последующие по 13 тактов. Таким образом максимальное время выставления нового значения должно быть не больше 13*2+25=51 такт. Я проверял на 75. Это как-то не согласуется с даташитом. В то же время прямого хомута в проге нет, так как я сейчас просто перевёл прогу на одиночное преобразование (Изменил инициализацию и вставил запуск) и всё стало работать как часы.

 

Ранее я применял FRM правда на м8/м88 и время считывания показаний значительно превышало время преобразования. Всё работало. Остаётся только гадать сколько именно требуется АЦП для правильного отображения инфы.

 

2 Anjey_N

 

при непрерывном или любом другом преобразовании можно разрешать или запрещать прерывания от АЦП. Это к самому преобразованию не относится. Это только определяет каким образом вы будете обрабатывать результат. Я, к примеру, никогда не применяю прерывание от АЦП. Похоже что и вам это тоже не надо. Вы можете сделать прерывание от таймера 1мс, запустить преобразование от АЦП например в том же FRM и просто в прерывании читать значение. А можно каждый раз запускать одиночное преобразование и тоже читать значение.

 

Алгоритм скользящего среднего обычно делают так. Хранят в кольцевом буфере 16 последних значений и хранят сумму этих значений (а не высчитывают её каждый раз) при получении нового значения прибавляют его к сумме, а из суммы вычитают затираемое. И затирают новым значением старое. Используют нужное колличество бит. Если буфер расчитан на 256 значений, то можно просто использовать старший байт суммы (при 8 битовом АЦП).

 

Колебания младшего бита АЦП убрать никаким образом нельзя так как это ваша точность. Таким способом вы просто сглаживаете кривую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот и я при чтении даташита пришел к тому же выводу - в режиме FreeRunning, если канал переключается не в прерывании АЦП первое измерение после переключения канала может относится как к старому, так и к новому каналу, поэтому его нужно отбросить. Это логически вытекает из описания и понятно.
Ну и где Вы такое прочитали в даташите ?

Читаем внимательно:

In Free Running mode, always select the channel before starting the first conversion.

The channel selection may be changed one ADC clock cycle after writing one to ADSC.

Правда это относится только к старту первого преобразования...

Еще раз читаем внимательно, разговор о Free Running и выставление флага ADSC касается

только первого преобразования...

Для подтверждения этой мысли читаем даташит еще чуть подробнее:

Note that the conversion starts on the following rising ADC clock edge after ADSC is written.

А вот это нам указывает на то что преобразование будет запущенно не в момент когда мы скажем

ADSC, а когда наступит этот самый "rising ADC clock edge", тока не нужно расказывать что он придет

абсолютно в произвольный момент времени.... Он придет абсолютно синхронно через считаемое

количество тактов после ADEN и ADSC, тока нужно научится считать эти такты...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...