Глава 14 Этот безумный аналоговый мир
Принимая во внимание тот факт, что основной задачей цифровых микроконтроллеров является отслеживание и управление состоянием реального окружения, которое по своей природе имеет аналоговый характер, нам придется рассмотреть методы взаимодействия между аналоговым и цифровым миром. Часто все, что нам требуется, — это сравнить уровни двух аналоговых сигналов. Однако в более сложных случаях входной аналоговый сигнал необходимо преобразовывать в его цифровой эквивалент, т. е. выполнять аналого-цифровое преобразование (АЦП). В дальнейшем полученный двоичный код можно будет обработать привычным образом. И наоборот, если выходной сигнал должен быть аналоговым, необходимо выполнять цифро-аналоговое преобразование (ЦАП).
Из этих операций, схематично изображенных на Рис. 14.1, наиболее сложной является операция аналого-цифрового преобразования. Во многих микроконтроллерах PIC имеется встроенный модуль многоканального АЦП. А вот для формирования аналогового выходного сигнала, как правило, приходится использовать дополнительные внешние элементы.
Рис. 14.1. Аналоговый мир — цифровая обработка
В данной главе мы с вами познакомимся с характеристиками аналоговых и цифровых сигналов, а также рассмотрим преобразование этих сигналов в обоих направлениях применительно к микроконтроллерам PIC. После прочтения этой главы, вы:
• Поймете взаимосвязь между аналоговыми и цифровыми сигналами.
• Осознаете причину, по которой выборку аналогового сигнала необходимо производить с частотой, превышающей максимальную частоту этого сигнала, по крайней мере, в 2 раза.
• Узнаете, как с помощью метода последовательного приближения можно преобразовать аналоговое напряжение в его двоичный эквивалент.
• Разберетесь в работе модулей аналогового компаратора, источника опорного напряжения и АЦП, а также научитесь конфигурировать эти модули.
• Узнаете, как следует конфигурировать линии ввода/вывода микроконтроллера, чтобы они могли работать с аналоговыми или цифровыми сигналами.
• Сможете писать ассемблерные программы, считывающие значения аналоговых сигналов с использованием опроса, прерываний, «спящего» режима, а также опрашивающие состояние аналогового компаратора.
• Сможете писать программы на языке высокого уровня Си, осуществляющие инициализацию различных аналоговых модулей и взаимодействие с ними.
• Узнаете, как можно управлять микросхемой внешнего ЦАП через параллельный порт.
Информация, передаваемая при помощи аналогового сигнала, содержится в определенных параметрах, таких как амплитуда, частота или фаза, которые могут принимать любые значения из непрерывного диапазона величин. Хотя такое определение подразумевает изменение аналоговых значений в диапазоне ±, на практике этот диапазон обычно ограничен. Так, ртутный термометр может измерять температуру в диапазоне, скажем, от -10 до +180 °C. При температуре, меньшей нижней границы, вся ртуть окажется спрятанной в колбе. А при температуре, превышающей верхнее значение, термометр просто взорвется!
Теоретически квантовая природа вещества подразумевает наличие некоторого нижнего предела, после которого изменения любых параметров приобретают дискретный характер. Однако на практике максимальное значение разрешающей способности, необходимое для обработки, определяется шумами и ограниченной точностью источников сигналов.
В цифровых сигналах информация представляется в виде совокупности дискретных символов. В зависимости от числа и типа этих символов возможно представление только конечного числа значений. Так, в двоичной системе n-битное число может в лучшем случае представлять 2n уровней. Хотя такое грубое представление может показаться несопоставимым с бесконечным числом значений, которые с равной вероятностью может принимать эквивалентный аналоговый сигнал, сетку (шаг) квантования можно подобрать таким образом, чтобы обеспечить точность, требуемую для решения каждой конкретной задачи. Так, в системах передачи голоса по телефонным линиям вполне достаточно точности около 1 %. В этом случае можно использовать 8-битное представление аналогового сигнала, которое даст нам 256 дискретных значений, что соответствует разрешающей способности около 0.5 %. В музыкальном компакт-диске используется 16-битное представление (65 536 разрядов) — разрешающая способность около 0.0015 %.
Из сказанного можно понять, что любой процесс, включающий в себя преобразование между аналоговым и цифровым представлением, пройдет через этап квантования. Соответственно, нам необходимо рассмотреть, каким образом этот этап влияет на информационное содержимое соответствующих сигналов.
В качестве примера рассмотрим ситуацию, представленную на Рис. 14.2. В данном случае входной сигнал преобразуется в 3-битный код. Процесс квантования (оцифровки) сигнала заключается в сравнении аналогового значения со значениями фиксированного числа уровней — в данном случае восемью. В качестве цифрового эквивалента исходного сигнала принимается ближайший по значению уровень. Так, на Рис. 14.2 входное напряжение величиной 0.0536 из полного диапазона 0.4285 оказывается больше напряжения, соответствующего 3-му уровню. Соответственно, его квантованное значение принимается равным 3-му уровню и выражается числом Ь’011’.
Получившаяся ошибка, равная -0.0536, называется шумом квантования, и полностью ее избежать невозможно (см. также Рис. 14.3, г). Кривая распределения
Рис. 14.2. Процесс квантования
ошибки квантования приведена в нижней части Рис. 14.2, и, как можно увидеть, она зависит только от числа уровней квантования. Эту ошибку можно легко определить, вычислив квадрат среднего значения интеграла вероятности ошибок. Взяв квадратный корень от результата, мы получим среднеквадратичное значение шума:
Среднеквадратичное значение вычисляется по формул:
Таким образом, среднеквадратичное значение шума равно L/√12 = L/2√3, где L — число уровней квантования.
Основной оценкой качества системы является отношение сигнал/шум (S/N). Если принять, что сигнал имеет синусоидальную форму с размахом 2n∙L, то среднеквадратичное значение сигнала будет равно (2n∙L/2)/√2, т. е. пик. значение/√2. Таким образом, n-разрядная двоичная система имеет отношение сигнал/шум:
или в децибелах:
S/N = 20 log1.22 x 2n = (6.02n + 1.77)дБ.
Динамический диапазон квантованной системы определяется отношением полной шкалы (2n∙L) к разрешающей способности L. То есть он равен 2й, или, в децибелах, 20log2n =20∙n∙log2 = 6.02n. Разрешающая способность может также выражаться в процентах — такой параметр называется процентной разрешающей способностью (см. Табл. 14.1).
Из Табл. 14.1 четко виден экспоненциальный характер изменения этих параметров относительно разрядности двоичного значения. Однако сложность реализации этого преобразования и, соответственно, ее стоимость тоже подчиняется этому закону. Так, при использовании 20-битного преобразования на полной шкале 1 В, уровень квантования получится меньше 1 мкВ. В телефонных системах с импульсно-кодовой модуляцией (ИКМ) используется 8-битное кодирование, однако уровни квантования расположены неравномерно — более часто при меньших значениях амплитуды. Такое решение позволяет снизить шипение в трубке во время пауз в разговоре! Линейное 8-битное преобразование подходит для большинства общих применений, обеспечивая разрешающую способность лучше ± 1/4 %. На самом деле видеоизображение имеет приемлемое качество уже при 4-битном разрешении, а для воспроизведения музыки вообще достаточно однобитного квантования, т. е. простого указания полярности сигнала!
Величины отношения S/N, приведенные в Табл. 14.1, являются теоретически достижимыми максимальными значениями, поскольку ошибки преобразования между представлениями сигнала, а также эффект наложения спектров (мы обсудим это чуть ниже) вносят свой вклад в искажение сигнала.
С точки зрения аналогового мира время является величиной непрерывной, тогда как в цифровых системах выборка значений происходит через дискретные промежутки времени. Теорема отсчетов Шеннона[177] гласит, что при частоте отсчетов, большей или равной удвоенному значению частоты самой высокочастотной составляющей в сигнале, потери информации не произойдет. Физический смысл этого нижнего предела, называемого частотой Найквиста (Котельникова), можно понять, рассмотрев спектр последовательности амплитудно-модулированных импульсов. Идеальные импульсы (импульсы нулевой длительности и единичной площади) представляются в частотной области бесконечной последовательностью гармоник одинаковой амплитуды, отстоящих друг от друга на величину, равную частоте следования импульсов. Реальные импульсы имеют похожий спектр, однако амплитуда гармоник снижается с ростом частоты.
Если мы промодулируем эту импульсную последовательность узкополосным сигналом Asincωft, то в частотной области эта операция будет эквивалентна умножению гармонического спектра (импульс) на величину Asincωft, давая суммарную и разностную составляющие:
Asincωft x Bsincωht = AB/2∙(sin(ωh + ωf)∙t + ∙(sin(ωh - ωf)∙t)
для каждой из гармоник ωh.
Более сложные узкополосные сигналы можно представить в виде ограниченной по частоте (fm) совокупности отдельных синусоидальных сигналов. Исходя из полученного соотношения, каждая из этих гармоник будет находиться как ниже (суммарная составляющая), так и выше (разностная составляющая) центральной частоты. Из Рис. 14.3, б можно увидеть, что для того, чтобы боковые полосы не перекрывались, гармоники (кратные частоте выборки) должны располагаться с интервалом не менее 2хfm.
Для восстановления исходного узкополосного сигнала из импульсной последовательности можно воспользоваться фильтром нижних частот, как показано на Рис. 14.3, г. Реальные фильтры будут пропускать определенные гармоники, хотя и ослабляя их. При более внимательном рассмотрении спектра сигнала на Рис. 14.3, г можно заметить остаток нижней боковой полосы первой гармоники, попавшей в полосу пропускания фильтра. Однако наибольшие искажения в восстановленном аналоговом сигнале возникли из-за ошибок квантования, вызванных грубой 3-битной дискретизацией. Подобная система будет иметь отношение S/N на уровне 20 дБ.
Чтобы снизить требования, предъявляемые к восстанавливающему фильтру, частота отсчетов выбирается, как правило, несколько выше частоты Найквиста. За счет этого появляется защитный промежуток между спектрами. Например, системы телефонной связи с ИКМ ограничивают входной аналоговый сигнал на уровне 3.4 кГц, однако частота выборки при этом составляет 8 кГц. Аналогично, в музыкальных компакт-дисках используется частота дискретизации 44.1 кГц, при этом максимальная частота сигнала составляет всего 20 кГц.
Еще один пример дискретизации с частотой ниже частоты Найквиста показан на Рис. 14.4. В данном случае частота дискретизации составляет всего 0.75 от частоты узкополосного сигнала. Результат восстановления сигнала посредством фильтрации полученной импульсной последовательности, показанный на Рис. 14.4, б, мягко говоря, не очень похож на исходный сигнал. Этот ложный сигнал называется помехой дискретизации или ложной частотой (alias). В случае, когда во входном аналоговом сигнале присутствуют составляющие с частотой, которая больше половины частоты дискретизации, скажем, из-за шумов, они приводят к появлению искажений в восстановленном сигнале. По этой причине аналоговые сигналы перед подачей на АЦП обычно пропускают через ФНЧ. Данный процесс известен как защита от наложения спектров.
* * *
При работе с аналоговыми сигналами во многих случаях достаточно просто знать, как соотносится контролируемое напряжение с опорным значением Vref. Например, сигнал, изображенный на Рис. 14.5 (см. также Рис. 14.20), представляет собой ток разряда двухфазного дефибриллятора ЭКГ, формируемый датчиком тока (преобразователем ток — напряжение) на основе эффекта Холла. В режиме покоя (когда дефибриллятор не используется) напряжение на выходе датчика держится на уровне 2.6 В. Когда дефибриллятор начинает разряжаться, это напряжение в течение нескольких десятков микросекунд резко увеличивается до 3.6 В.
Рис. 14.3. Процесс аналого-цифрового преобразования
Рис. 14.4. Эффект наложения спектров
Если микроконтроллеру необходимо отслеживать напряжение в течение последующих нескольких десятков миллисекунд, скажем, для вычисления суммарной энергии разряда, то для запуска этого процесса ему необходимо знать, когда напряжение превысит пороговое значение. На Рис. 14.5 в качестве порогового выбрано напряжение 3.4 В. Разумеется, можно просто с большой частотой считывать аналоговый сигнал с помощью встроенного модуля АЦП (если он есть), как описано далее на стр. 511, однако на реализацию этой процедуры непрерывного считывания и проверки уйдет большая часть вычислительных ресурсов процессора. Программа получилась бы более эффективной, если бы имелась возможность автоматической генерации прерывания при превышении входным напряжением порогового значения, а уже обработчик прерывания запускал бы процедуру считывания и анализа сигнала в режиме реального времени.
На Рис. 14.5 аналоговый сигнал Vdefb подается на неинвертирующий (+) вход аналогового компаратора. К инвертирующему входу компаратора подключен источник опорного напряжения 3.4 В. Когда напряжение Vdefb становится больше напряжения Vref, сигнал на выходе компаратора меняется с лог. 0 на лог. 1, и, наоборот, при Vdefb < Vref выходе компаратора снова появляется лог. 0.
По своей сути аналоговый компаратор является дифференциальным усилителем с высоким коэффициентом усиления без отрицательной обратной связи (ООС). Имея очень большое значение коэффициента усиления при разомкнутой цепи ООС, усилитель будет переходить в состояние насыщения с уровнем выходного сигнала, близким к отрицательному или положительному напряжению источника питания, если напряжения на его входах отличаются даже на чрезвычайно малую величину. Таким образом, в качестве компаратора может применяться обычный ОУ, однако лучше использовать специализированные микросхемы, формирующие на выходе стандартные логические уровни, а также мгновенно срабатывающие при переходе медленно меняющегося сигнала через пороговое значение.
Рис. 14.5. Использование аналогового компаратора для определения начального момента разряда дефибриллятора ЭКГ
Все три используемые нами модели микроконтроллеров PIC имеют встроенный модуль компаратора. В 8-выводной модели PIC12F675 реализован только один аналоговый компаратор. Однако для моделей в корпусах с большим количеством выводов (в частности, для моделей серии PIC16F87XA) более типичным является наличие сдвоенного компаратора, различные варианты включения которого приведены на Рис. 14.6.
Рис. 14.6. Режимы работы модуля аналогового компаратора в микроконтроллерах PIC 16F87X
Регистр управления компаратора CMCON, обычно расположенный, по адресу h’9C’, используется для выбора одной из восьми возможных конфигураций модуля, показанных на Рис. 14.6. Конфигурация компаратора определяется битами режима СМ[2:0] (CMCON[2:0]). В конкретном случае PIC16F987XA при сбросе микроконтроллера в эти биты заносится число b’111’, при котором модуль аналогового компаратора полностью выключен. Во многих других устройствах режимом по умолчанию является режим Ь’000’, при котором компараторы тоже отключены, однако используемые ими выводы микроконтроллера сконфигурированы как аналоговые входы.,
Запомните универсальное правило для всех микроконтроллеров PIC с аналоговыми модулями: все выводы микроконтроллера, которые могут работать как аналоговые (обычно выводы порта А, Е или GP), всегда после сброса по включению питания становятся аналоговыми входами. Это сделано для того, чтобы предотвратить повреждение входных цифровых буферов (см. Рис. 11.7 на стр. 340) на тот случай, если при включении микроконтроллера на выводе будет присутствовать аналоговое напряжение величиной, скажем, 2.6 В. Если данный вывод будет сконфигурирован как цифровой вход, воспринимающий сигналы с напряжением, близким к 0 В или к напряжению питания, то такое промежуточное напряжение может привести к одновременному открытию обоих входных транзисторов. В результате через них потечет сквозной ток, который способен вызвать тепловой пробой. Поскольку аналоговые напряжения не имеют каких-либо четко определенных значений, то даже в случае, когда вывод сконфигурирован как аналоговый вход, в схему часто вводится внешний последовательный резистор, который служит для ограничения тока в том случае, если аналоговое напряжение превысит напряжение питания микроконтроллера или станет отрицательным, как показано на Рис. 14.20.
В микроконтроллерах линейки PIC16F87XA для сохранения совместимости с более старыми моделями PIC16F87X, не имевшими модуля аналогового компаратора, такая конфигурация (переключение) выводов полностью отключена по умолчанию. Однако все устройства данной линейки имеют модуль встроенного АЦП, который при сбросе по питанию переключает все связанные с ним выводы в режим аналоговых входов, выполняя, таким образом, описанное выше правило. При нахождении модуля компаратора в режиме Ь’111’ его потребление минимально, поэтому этот режим следует использовать, если микроконтроллер не работает с аналоговыми сигналами и модуль компаратора не используется, особенно в «спящем» режиме.
По большому счету в зависимости от режима работы модуля в распоряжении пользователя оказываются либо два полностью независимых компаратора, либо два компаратора с объединенными неинвертирующими входами, которые могут использоваться для подачи общего опорного сигнала. Выходное значение любого активного компаратора можно считать в любой момент времени из 6-го (C1OUT) и 7-го (C2OUT) битов регистра CMCON. На выходе каждого компаратора имеется программируемый инвертор, управляемый битами C1INV и C2INV регистра CMCON (CMCON[4] и CMCON[5] соответственно). При Vin+ > Vin- и сброшенном бите инвертирования выходное значение компаратора будет равно 1, в противном случае — 0[178]. Как было указано на стр. 466, в некоторых исполнениях Таймера 1 выход 2-го компаратора может использоваться для блокирования счетных импульсов таймера. Используя эту возможность, можно измерять время, в течение которого уровень аналогового сигнала превышал пороговое напряжение. В режимах Ь’011’ и b’101’ выходное значение компараторов также можно считать с выводов RA4/C10UT и RA5/C20UT микроконтроллера (в других моделях используемые линии портов могут отличаться от указанных). Для этого данные выводы должны быть сконфигурированы как выходы при помощи сброса соответствующих битов регистра TRIS.-Аналогично, любые выводы параллельных портов, используемые в качестве аналоговых входов, должны быть сконфигурированы как входы.
При изменении выходного сигнала компаратора устанавливается флаг прерывания от компаратора CMIF, расположенный у микроконтроллера PIC16F687XA в регистре PIR[2], а при установленном бите маски CMIE (Р1Е2[6] для PIC16F87XA) будет сгенерировано прерывание от компаратора, если, разумеется, бит глобального разрешения прерываний также установлен в 1. Поскольку эта линия прерывания используется обоими компараторами, программа должна хранить информацию о предыдущих значениях битов C1OUT и C2OUT, чтобы иметь возможность определить, состояние какого из компараторов действительно изменилось. Эта информация может обновляться в обработчике прерывания. После чтения регистра CM CON несоответствие между новым и предыдущим состояниями компаратора, вызвавшее установку флага прерывания, будет устранено — точно так же, как и в случае прерывания по изменению состояния выводов порта В, описанного на стр. 347. Только после выполнения этой операции можно сбрасывать флаг CMIF. Если режим компаратора изменяется «на лету», то перед этим изменением следует запретить прерывание от компаратора. Выждав после изменения режима не менее 10 мкс (в течение этого времени стабилизируются значения сигналов), регистр CMCON необходимо повторно считать для сброса возможного несоответствия, а затем сбросить флаг CMIF перед повторным разрешением работы системы прерываний.
Поскольку модуль компаратора не использует системный тактовый сигнал, активный компаратор можно задействовать для вывода микроконтроллера из «спящего» режима при переходе внешнего сигнала через пороговое значение Vref, что вызывает установку флага CMIF. После «пробуждения» микроконтроллер должен убрать несоответствие (прочитать регистр CMCON) и сбросить флаг CMIF в теле основной программы (после команды sleep) или в обработчике прерывания, если было разрешено прерывание от компаратора.
Необходимо отметить, что включенный компаратор потребляет ток, который намного больше базового значения потребления в «спящем» режиме. Например, типичный ток потребления микроконтроллеров PIC12F629/675 в «спящем» режиме составляет 2.9 нА при напряжении 5 В (995 нА mах), а модуль компаратора в среднем потребляет 11.5 мкА (16 мкА mах). Так что если компараторы не используются во время «сна» микроконтроллера, то они должны быть выключены.
В режиме b’110’ каждый из компараторов может контролировать один из двух сигналов, определяемый состоянием бита входного ключа компаратора CIS (CMCON[3]), который при включении питания сбрасывается в 0. Неинвертирующие входы обоих компараторов в этом режиме подключены к внутреннему источнику опорного напряжения, формируемого модулем опорного напряжения компаратора (Comparator Voltage Reference — CVR).
Этот модуль CVR имеется во всех моделях микроконтроллеров с модулем компаратора. Как видно из Рис. 14.7, данный модуль представляет собой аналоговый мультиплексор с подключенной к нему резистивной цепочкой, на выходе которого в соответствии со значениями битов CVR[3:0] регистра управления CVRCON (CVRCON[3:0]) может быть сформировано одно из 16 различных напряжений. Модуль опорного напряжения включается при установке бита разрешения CVREN (CVRCON[7]). При этом цепочка последовательно соединенных резисторов, номинальное сопротивление каждого из которых равно 2 кОм, подключается к шине питания VDD.
Рис. 14.7. Модуль опорного напряжения компаратора
В распоряжении пользователя имеется два диапазона опорного напряжения. Конкретный диапазон задается битом CVRR (CVRCON[5]), который подключает или отключает дополнительный резистор сопротивлением 8R в конец цепочки. Обозначив 4-битное значение CVR[3:0] как я, получим:
где n изменяется в диапазоне от 0 до 15.
Погрешность установки напряжения составляет 1/2 шага, но в реальности абсолютное значение выходного напряжения модуля прямо пропорционально напряжению питания, величина которого обычно задается не слишком точно. Кроме того, значение VDD может изменяться при уходе напряжения источника питания или батареи из-за температуры или тока нагрузки. Даже любая помеха по шине питания отразится на опорном напряжении, хотя действие помех в какой-то степени можно ослабить посредством фильтрующих конденсаторов и корректной разводкой линий питания. Поэтому в тех случаях, когда требуется точное значение напряжения, часто используются внешние прецизионные источники опорного напряжения. В частности, при работе модуля компаратора в режиме Ь’100’ этот источник подключается к выводу RA3 (см. Рис. 14.20).
Предположим, что мы собираемся получить пороговое напряжение величиной 3.4 В (Рис. 14.5) при VDD = 5 В. Нам придется использовать верхний диапазон, т. е. CVRR = 0. Вычислим значение битов CVR[3:0]:
5 х (0.25 + n/32) = 3.4
0.25 + n/32 = 3.4/5
n = (3.4/5 — 0.25) х 32 = 13.76
Таким образом, наиболее близкое к заданному напряжение получится при n = 14. Задав CVR[3:0] = b’1110’, получим Vref = 3.4375 В.
В некоторых моделях имеется дополнительный управляющий бит, подключающий выход модуля опорного напряжения к выводу порта, что позволяет использовать его с внешними узлами схемы. Когда бит CVROE (CVRCON[6]) установлен в 1, аналоговое напряжение Vref выдается на соответствующий вывод микроконтроллера. Из-за относительно высокого выходного сопротивления, которое к тому же зависит от выбранной величины опорного напряжения, компания Microchip рекомендует буферировать внутренний источник опорного напряжения — обычно с помощью операционного усилителя. При необходимости, задавая коэффициент усиления такого усилителя, можно более точно задавать напряжение Vref. С помощью внешнего ОУ также можно реализовать фильтрацию этого сигнала для снижения уровня высокочастотных помех. При таком режиме работы модуль опорного напряжения может использоваться как простой 4-битный цифро-аналоговый преобразователь.
Инициализационный код, осуществляющий настройку модулей компаратора и опорного напряжения для нашего примера с дефибриллятором (используется 1-й компаратор, вход которого подключен к RA3), будет иметь следующий вид:
include "p16f877a.inc"
bsf STATUS,RP0; Переключаемся в 1-й банк
movlw b’00001110’; Режим компаратора 110
movwf CMCON; Подключен к RA3 (CIS = 1)
movlw b’10001110’; Модуль CVREF включен (1), наружу не выведен
movwf CVRCON; Верхний диапазон (0), CVR[3:0] = 1110
bsf PIE2,CMIE; Разрешаем прерывания от компаратора
call DELAY_10US; Ждем 10 мкс, пока выходной сигнал модуля установится
movf CMCON,f; Читаем CMCON, чтобы сбросить признак изменения
bcf STATUS,RP0; Возвращаемся в 0-й банк
bcf PIR2,CMIF; Сбрасываем флаг прерывания от компаратора
bsf INTCON,PEIE; Разрешаем прерывания от периферийных устройств
bsf INTCON,GIE; Разрешаем работу системы прерываний
Обратите внимание на то, что перед разрешением прерываний формируется задержка длительностью 10 мкс, необходимая для установления внутренних аналоговых сигналов. Последующее чтение регистра CMCON сбрасывает возможное несоответствие между сохраненным и текущим состоянием компаратора, после чего сбрасывается флаг прерывания от компаратора CMIF. И наконец, как обычно, разрешается работа системы прерываний установкой битов маски PEIE и GIE регистра INTCON.
В документации на некоторые модели, например PIC12F675, данный модуль называется просто модулем опорного напряжения. В таких моделях регистр управления называется VRCON. Соответственно в названии различных битов этого регистра отсутствует первая буква «С», например VREN вместо CVREN.
* * *
Во многих случаях необходимо иметь больше информации об аналоговом сигнале, нежели мы можем получить путем «тупого» сравнения сигнала с опорным напряжением. Возьмем, к примеру, ситуацию, показанную на Рис. 14.5. В данном случае для вычисления мощности импульса нам потребуется определять квадрат отклонения уровня сигнала от базового значения и интегрировать его по времени. В таких случаях входной сигнал после считывания необходимо преобразовывать в цифровую форму.
Функция преобразования аналоговой величины в цифровой эквивалент может быть выражена следующим образом:
где ki — i-й двоичный коэффициент, имеющий значение 0 или 1, a Vin =< Vref (Vref — фиксированное аналоговое опорное напряжение). Таким образом, Vin представляется в виде двоичной доли Vref, а коэффициенты к(являются искомыми значениями разрядов двоичного числа.
Чтобы понять, как можно реализовать подобные вычисления на практике, рассмотрим механическую аналогию метода последовательного приближения. Предположим, что у нас имеется объект неизвестной массы W (эквивалент Vin), безмен (эквивалент аналогового компаратора) и набор точных гирь известной массы 1, 2, 4 и 8 г (общая масса гирь эквивалентна величине опорного напряжения Vref). Тогда для определения массы груза можно воспользоваться следующим алгоритмом:
1. Поместить 8 г на тарелку. Если груз слишком тяжелый, то убрать его (k1 = 0), в противном случае оставить (k1 = 1).
2. Поместить 4 г на тарелку. Если груз слишком тяжелый, то убрать его (k2 = 0), в противном случае оставить (k2 = 1).
3. Поместить 2 г на тарелку. Если груз слишком тяжелый, то убрать его (k3 = 0), в противном случае оставить (k3 = 1).
4. Поместить 1 г на тарелку. Если груз слишком тяжелый, то убрать его (k4 = 0), в противном случае оставить (k4 = 1).
В итоге мы получим ближайшее значение, не превышающее искомое, равное суммарной массе гирь, оставшихся на тарелке. Так, если W было равно 6.2 г, то в случае 4-битной системы мы получим 4 г + 2 г = 6 г (Ь’0110’).
В электронике для реализации метода последовательного приближения[179] используются наборы прецизионных резисторов или конденсаторов, объединенные таким образом, чтобы можно было последовательно уменьшать в 2 раза фиксированное напряжение Vref, подаваемое на аналоговый компаратор, который играет роль весов.
В большинстве микроконтроллеров для деления опорного напряжения используются наборы конденсаторов, емкости которых пропорциональны степеням двойки (Рис. 14.8). Конденсаторы небольшой емкости можно легко реализовать в кремниевом кристалле интегральной микросхемы, и, хотя точное их значение будет несколько отличаться от партии к партии, в каждом конкретном экземпляре микросхемы емкости всех конденсаторов будут соответствовать друг другу, причем это соответствие будет сохраняться при изменении температуры и напряжения питания. Емкость, кратная базовой, может быть реализована параллельным соединением конденсаторов. Как правило, роль этой емкости выполняет емкость перехода затвор-исток полевого транзистора, являющегося базовым элементом любой КМОП ИС.
Перед запуском процесса преобразования все конденсаторы подключаются к неизвестному аналоговому входному напряжению Vin как показано на Рис. 14.8, а. При осуществлении выборки (sampling) эти конденсаторы заряжаются через внутренние и внешние сопротивления с учетом времени установления внутренних аналоговых ключей. Возьмем в качестве примера модуль 10-битного АЦП, изображенный на Рис. 14.11. В этом случае к выводу AN подключается набор параллельно соединенных конденсаторов номинальной емкостью 0.12 пФ. Таким образом, их суммарная емкость равна 120 пФ (120 х 2-12 Ф). Внутреннее сопротивление имеет величину порядка 7.5 кОм, которое, однако, сильно зависит от температуры и напряжения питания. Рекомендуется, чтобы внешнее сопротивление составляло не более 2.5 кОм — в этом случае напряжение смещения, вызванное токами утечки ± 1/2 мкА, будет меньше уровня квантования (младшего значащего бита).
Рис. 14.8. Инициализация набора конденсаторов 4-битного преобразователя
Постоянная времени τ (R∙C при указанных значениях равна 120 х 10–12 х 104 = 1.2 мкс для суммарного сопротивления 7.5 + 2.5 = 10 кОм. Чтобы получить точность не хуже 0.05 % итогового напряжения, т. е. 1/2 10-битного уровня квантования, возьмем 8 х τ ~= 10 мкс. В документации максимальное время установления ключа указывается равным 10 мкс, но в нашем примере примем его равным 2 мкс. Таким образом, даже в наихудшем случае для полного заряда набора конденсаторов хватит 20 мкс.
Наш последующий анализ строится на предположении, что к моменту преобразования конденсаторы должны быть заряжены до полного значения входного напряжения. Это замечание справедливо в случае осуществления выборки по одному из нескольких аналоговых каналов или в том случае, если с момента последней выборки прошло достаточно времени для полного стекания заряда. Меньшее выходное сопротивление источника сигнала приведет к уменьшению постоянной времени. Разумеется, для оценки максимально достижимой частоты выборки к указанному времени накопления следует прибавить время собственно преобразования.
Во время выборки (S) верхние по схеме обкладки конденсаторов имеют нулевой потенциал, а нижние заряжаются до Vin. При переводе ключа в положение «хранение» (Н), как показано на Рис. 14.8, б, нижние обкладки конденсаторов оказываются соединенными с общим проводом, а верхние обкладки — ни к чему не подсоединены. Как известно, напряжение на конденсаторе может измениться только в том случае, если произойдет перенос заряда между обкладками, ΔQ = СΔV. Таким образом, изменение напряжения на нижних обкладках конденсаторов на величину ΔV = — Vin приведет к появлению на верхних обкладках потенциала, равного 0 — Vin, поскольку заряд не может исчезнуть с обкладки, которая никуда не подключена. Таким образом, в начале процесса преобразования на инвертирующем входе аналогового компаратора присутствует напряжение — Vin.
Четырехбитный вариант схемы последовательного приближения, являющейся «сердцем» модуля АЦП, в упрощенном виде показан на Рис. 14.9. Поэтапное выполнение операций осуществляется сдвиговым регистром SRG (см. Рис. 2.22 на стр. 51) после установки бита регистра управления АЦП. При поступлении на этот регистр тактовых импульсов на каждом его выходе поочередно появляется лог. 1, активизируя каждый этап преобразования:
Набор конденсаторов переключается в положение «Хранение», и все конденсаторы, начиная с конденсатора, имеющего наибольшую емкость, по очереди подключаются к линии Vref. Выходной сигнал компаратора определяет состояние соответствующего бита регистра последовательного приближения (SAR). Подробно этот процесс показан на Рис. 14.10. После четырех таких операций «установка — проверка — сброс» результат из SAR передается в регистр данных АЦП. При этом сбрасывается флаг , свидетельствуя об окончании процесса преобразования, и устанавливается флаг прерывания ADIF. И в завершение аналоговый вход снова подключается к конденсаторам (состояние «Выборка»), в результате чего они заряжаются для следующего преобразования, которое можно будет выполнить после небольшой паузы.
Суммарное время преобразования приблизительно равно шести периодам сигнала tAD, подаваемого на тактовый вход сдвигового регистра секвенсора (контроллера последовательности) — по одному периоду на каждый бит плюс один для каждого из интервалов выборки и хранения. В 10-битном модуле время преобразования приблизительно равно 12 периодам тактового сигнала АЦП. Если же говорить конкретно о микроконтроллерах PIC, то минимальный период тактового сигнала составляет примерно 1.6 мкс (~= 600 кГц) для всех устройств, кроме самых старых моделей PIC16C71/711, в которых это значение равно 2 мкс. Нижняя граница периода не нормируется, однако из-за постепенного стекания заряда из конденсаторов следует избегать тактовых частот с периодом tAD более 20 мкс (50 кГц). Из Рис. 14.11 видно, что в качестве тактового сигнала АЦП может использоваться сигнал от одного из четырех источников. Первые три сигнала получают из системного тактового сигнала, прошедшего через предделитель, а четвертый формируется встроенным RС-генератором, период tAD которого составляет около 4 мкс.
Процесс преобразования, при котором каждая последующая доля Vref добавляется и при необходимости исключается из начального значения, показан на Рис. 14.10. Как мы уже видели на Рис. 14.8, в конце этапа выборки верхние обкладки конденсаторов заряжаются до уровня — Vin. В качестве примера предположим, что Vin = 0.4285∙Vref.
Рис. 14.9. Упрощенная схема 4-битного АЦП последовательного приближения
1. Процесс начинается с подключения источника опорного напряжения Vref к нижней обкладке конденсатора самой большой емкости, что определяется защелкой SAR8 (Рис. 14.9). Это вызывает инжекцию заряда величиной ΔQ = Ctotal∙Vref, который будет одинаков как для конденсатора C1 емкостью 8 единиц, так и для остальных конденсаторов, суммарная емкость которых также равна восьми единицам (Рис. 14.10). Таким образом, напряжение на узле N возрастает на Vref/2 до уровня —0.4285 + 0.5 = +0.0715∙Vref. В общем случае ΔVN = VrefCk/Ctotal. В результате на выходе компаратора появляется лог. 0 и защелка SAR8 соответственно сбрасывается, приводя напряжение на конденсаторах к значениям, которые были перед началом данного этапа.
Рис. 14.10. Реализация метода последовательного приближения
2. SAR4 подключает источник Vref к следующему конденсатору наибольшей емкости, в результате чего напряжение на узле N возрастает на Vref/4 (т. е. на 4/16) — В итоге на инвертирующем входе компаратора появляется напряжение —0.4285 + 0.25 = —0.1785∙Vref, что приводит к появлению на выходе компаратора лог. 1. Защелка SAR4 остается установленной, при этом напряжение узла остается равным —0.1785∙Vref.
3. SAR2 подключает источник Vref к следующему конденсатору наибольшей емкости, в результате чего напряжение на узле N возрастает на Vref/8 (т. е. нa 2/16). Итоговое напряжение -0.1785 + 0.125 = -0.0535∙Vref приводит к появлению на выходе компаратора лог. 1. Защелка SAR2 остается установленной, при этом напряжение узла остается равным —0.0535∙Vref.
4. SAR1 подключает источник Vref к конденсатору наименьшей емкости, в результате чего напряжение на узле N возрастает на Vref/16 (т. е. на 1/16) — Итоговое напряжение -0.0535 + 0.0635 = +0.009∙Vref приводит к появлению на выходе компаратора лог. 0 и сбросу защелки SAR1.
Таким образом, в регистре SAR окажется код Ь’0110’ или 0.375 В, представляющий 4-битное число, наиболее близко соответствующее напряжению Vin = 0.4825∙Vref. Остаток, равный 0.0535∙Vref, представляет собой погрешность квантования.
В большинстве микроконтроллеров используется 8- или 10-битная матрица конденсаторов. Теоретически этот метод можно легко применить и для преобразования с большей разрядностью, однако на практике при этом возникают проблемы, связанные с согласованием конденсаторов большей емкости. Кроме того, наличие помех от работы внутренних логических узлов приводит к тому, что в подавляющем большинстве процессоров разрядность модуля АЦП ограничивается 12 битами. Также выпускаются внешние быстродействующие АЦП последовательного приближения разрядностью больше 12 бит, но они обычно используют наборы резисторов, соединенные по лестничной схеме, и относительно дороги (по сравнению с 8-битными микроконтроллерами).
Разброс емкостей конденсаторов, напряжения смещения, сопротивление внутренних ключей, токи утечки, а также нелинейность характеристики аналогового компаратора — все это является причиной погрешностей, возникающих при преобразовании. Анализ различных методик измерения указанных погрешностей выходит за рамки данной книги, однако в документации на любую микросхему АЦП (или модуль АЦП микроконтроллера) приводится список источников этих погрешностей и их величины, выраженные в единицах младшего значащего бита (LSB). Так, в справочных данных модуля 10-битного АЦП микроконтроллера PIC16F675 указано, что его суммарная абсолютная погрешность составляет ±1 LSB. Это гарантирует монотонность передаточной характеристики, т. е. что при любом приращении входного напряжения изменение двоичного кода никогда не произойдет в обратном направлении. Эта ошибка нормируется при Vref = VDD. Если же Vref будет меньше VDD, то точность ухудшится, хотя в большинстве случаев приемлемый результат достигается при напряжении вплоть до 2 В.
В микроконтроллере PIC12F675, а также в моделях линейки PIC16F87X имеется интегрированный модуль 10-битного АЦП. В более старых устройствах, таких как PIC16F73, использовался 8-битный вариант этого модуля, очень похожий по своей структуре и принципу работы на своего старшего 10-битного собрата, показанного на Рис. 14.11, который мы и будем рассматривать. Модули АЦП во всех микроконтроллерах PIC используют наборы конденсаторов с параметрами, указанными выше. Однако, с точки зрения пользователя, подробности процесса преобразования гораздо менее важны, нежели вопросы практического использования этого модуля.
Во всех микроконтроллерах с АЦП на входе последнего расположен аналоговый мультиплексор. Это позволяет программе обрабатывать до восьми аналоговых сигналов, по одному в каждый момент времени. Два регистра управления позволяют выбрать конкретный канал и определяют источник тактового сигнала. Кроме того, с помощью этих регистров можно сконфигурировать соответствующие выводы микроконтроллера как аналоговые (состояние по умолчанию после подачи питания) или цифровые, а также задать конфигурацию источника опорного напряжения. Преобразование инициируется установкой бита , который также служит для индикации завершения преобразования, а 10-битный результат затем можно считать из двух 8-битных регистров данных[180].
Разобьем наше описание модуля АЦП на две части. Сначала рассмотрим процесс инициализации и конфигурирования модуля, а уже только потом — собственно процесс преобразования.
Инициализация
При конфигурировании модуля необходимо учитывать следующие моменты:
1. Каким образом можно включить модуль?
2. Как следует тактировать модуль?
3. Какие каналы требуется использовать?
4. Хватит ли 8-битного результата?
Все эти опции задаются с помощью регистров управления АЦП ADCON0 и ADCON1[181].
ADON (включение модуля АЦП)
После подачи питания на микроконтроллер модуль АЦП находится в выключенном состоянии. Для его включения необходимо записать 1 в бит ADON (ADCON[0]). Включенный модуль потребляет в среднем 220 мкА (PIC16F87X), даже не осуществляя преобразований. Поэтому в тех случаях, когда энергопотребление микроконтроллера является критичным фактором, модуль АЦП следует выключать (если, разумеется, он не используется в программе). Обратите внимание, что бит нельзя устанавливать той же командой, которая выполняет включение АЦП, во избежание запуска преобразования одновременно с включением модуля.
Рис. 14.11. Модуль 8-канального 10-битного АЦП микроконтроллеров PIC16F87X
ADCS[1:0] (выбор тактового сигнала АЦП)
Для работы модулю АЦП требуется тактовый сигнал для выполнения последовательности операций установки/проверки, проиллюстрированных на Рис. 14.10. Если частота этого сигнала будет слишком высока, то при переключении элементов схемы уравновешивания требуемые значения напряжений не будут успевать устанавливаться. В справочных данных на микроконтроллер нормируется минимальное значение периода тактового сигнала АЦП tAD, равное 1.6 мкс (3 мкс при пониженном напряжении питания). Соответственно, максимальное значение частоты преобразования составляет примерно 600 кГц. Так, чтобы получить tAD = 1.6 мкс (5/8 МГц) при использовании 5-МГц резонатора, нам придется загрузить в биты ADCS[1:0] число 01, соответствующее коэффициенту деления 8. В Табл. 14.2 приведены подходящие установки для пяти наиболее часто используемых значений частот кварцевых резонаторов.
Примечания:
1. Стандартные модели, в среднем 4 мкс.
2. Модели с расширенным диапазоном температур и низковольтные исполнения, в среднем 6 мкс.
Для обеспечения функционирования АЦП в системах с низкой тактовой частотой, в частности в тех, где системный генератор работает от часового кварца 32.768 кГц, в модуле предусмотрен отдельный RС-генератор. Поскольку этот генератор полностью независим от системного тактового сигнала, то при его использовании преобразование может выполняться при нахождении микроконтроллера в «спящем» режиме. В таком случае для «пробуждения» микроконтроллера можно использовать прерывание по завершении преобразования. Выполнение преобразования при выключенном системном тактовом сигнале увеличивает точность, поскольку при этом минимизируются наводки со стороны цифровых узлов микроконтроллера. Если при системной тактовой частоте более 1 МГц АЦП работает от встроенного RС-генератора, Microchip рекомендует выполнять преобразование в «спящем» режиме, поскольку отсутствие синхронизации между двумя тактовыми сигналами увеличивает помехи, наводимые на аналоговые узлы микроконтроллера.
В отличие от других моделей в микроконтроллере PIC12F675 имеется три бита выбора тактового сигнала АЦП, что обеспечивает дополнительный коэффициент деления на 64. Эта опция полезна при работе с 20-МГц резонатором — ее использование позволяет получить минимально возможное значение периода tAD (3 мкс) при наибольшем допустимом напряжении питания для данного устройства.
CHS[2:0] (выбор канала)
Микроконтроллеры с модулями АЦП имеют возможность оцифровывать напряжение с нескольких аналоговых входов. Количество этих входов (каналов) может варьироваться от 4 (используются линии порта GP) в крошечном 8-выводном PIC12F675 до 8 (используются линии портов А и Е) в 40-выводных микроконтроллерах PIC16F874/7.
При сбросе по включению питания все разделяемые выводы портов по умолчанию конфигурируются как аналоговые входы (см. стр. 496). Как можно увидеть из Рис. 14.12, у контакта ввода/вывода, работающего в качестве аналогового входа, просто отключается входной цифровой буфер — сравните с Рис. 11.3 на стр. 333. Остальные элементы схемы при этом работают, как обычно. Из всего этого можно сделать следующие выводы:
• При чтении бита порта, сконфигурированного как аналоговый вход, из-за отключенного входного цифрового буфера всегда будет возвращаться лог. 0.
• Буфер TRIS работает, как обычно, поэтому соответствующий бит регистра TRIS должен быть установлен в 1. Таким образом, вывод порта, сконфигурированный как аналоговый, должен работать как вход для предотвращения конфликта между аналоговым сигналом Vin и цифровым выходным сигналом триггера данных.
• АЦП может считывать аналоговое напряжение с вывода микроконтроллера, даже если он не был сконфигурирован как аналоговый. Однако в этом случае находящийся в активном состоянии цифровой буфер может потреблять излишний ток, который превысит приведенный в спецификации.
Рис. 14.12. Конфигурирование аналоговых входов портов А и Е
PCFG[3:0] (конфигурация аналогового порта)
Если в данном конкретном приложении требуется меньше аналоговых каналов, чем имеется в модуле, то некоторые неиспользуемые каналы могут быть задействованы, как обычно, т. е. в качестве цифровых линий ввода/вывода. Для задания конфигурации аналогового порта предназначены биты PCFG[3:0] (ADCC)N1[3:0]). Возможные комбинации, число и положение этих битов зависит от модели микроконтроллера. Для микроконтроллеров линейки PIC16F87X возможные значения битов и соответствующие им конфигурации выводов приведены на Рис. 14.11. К примеру, если в вашем проекте требуется только один аналоговый канал, то, загрузив в указанные биты значение Ь’1110’, вы получите один аналоговый вход RA0/AIN0, а остальные выводы (RA5, RA[3:1] и RE[2:0]) сможете использовать для других целей.
Даже если не требуется обработка аналоговых сигналов, регистр ADCON1 все равно необходимо конфигурировать — в этом случае используются значения Ь’0110’ или Ь’0111’, при которых все выводы, которые могут использоваться АЦП, конфигурируются как цифровые[182]. Невыполнение этого требования представляет собой одну из наиболее распространенных ошибок, поскольку большинство современных моделей имеют аналоговые модули и, как было указано на стр. 496, при сбросе по включению питания все соответствующие выводы по умолчанию конфигурируются как аналоговые. Соответственно, при чтении состояния таких выводов будет всегда возвращаться 0. Как уже было отмечено, все выводы, используемые для считывания аналогового сигнала, должны быть сконфигурированными как входы (1 в соответствующих битах регистров TRIS).
Как мы видели из Рис. 14.10, операция последовательного приближения заключается в последовательном сравнении с долями фиксированного опорного напряжения, каждая последующая из которых в 2 раза меньше предыдущей. Соответственно, точность данной операции зависит от качества этого опорного напряжения. Как правило, указанный параметр (точность) определяется ценой единицы младшего бита (LSB), т. е. шагом квантования. В случае 10-битного преобразования эта величина составляет Vref/1024, или более 0.1 % опорного напряжения.
В качестве опорного напряжения можно использовать напряжение питания самого микроконтроллера, скажем, 5 В. Так, при значении битов PCFG[3:0] = = b’1110’ вывод RA0 конфигурируется как аналоговый, а в качестве опорного используется напряжение VDD. В этом случае значение, полученное в результате оцифровки, даст нам долю от напряжения питания, которой соответствует входное аналоговое напряжение.
Использование напряжения питания в качестве опорного является не самым лучшим выбором с точки зрения помехозащищенности. К тому же его значение может изменяться в некоторых пределах. Если требуется более высокая точность или опорное напряжение, отличное от напряжения источника питания, то для подключения внешнего источника опорного напряжения можно задействовать определенные аналоговые входы. Все модули АЦП позволяют использовать хотя бы одно внешнее напряжение. Что же касается PIC16F87X, то в этом микроконтроллере можно использовать одно или два внешних опорных напряжения. В частности, при PCFG[3:0] = Ь’0101’ выводы RA[1:0] конфигурируются в качестве аналоговых входов, а вывод RA3 используется для подключения внешнего прецизионного источника опорного напряжения Vref+ (см. Рис. 14.20)[183]. Величина Vref+ может находиться в пределах от VDD — 2.5 В до VDD + 0.3 В (при этом она не должна быть менее 2 В).
В некоторых случаях может потребоваться измерение напряжений относительно уровня, отличающегося от VSS (0 В или земля). Модули АЦП в некоторых моделях, например в PIC16F87X, позволяют задать отдельное нижнее опорное напряжение Vref-. Скажем, при PCFG[3:0] =Ь’1101’ тоже обеспечивается два аналоговых канала, а вывод RA3 используется для подачи опорного напряжения Vref+. Только вывод RA2 в этом случае используется для подачи опорного напряжения Vref-, которое должно быть в пределах -0.3…2 В. А весь диапазон Vref+ — Vref- не может быть меньше 2 В.
ADFM (формат результата преобразования)
В рассматриваемом нами модуле АЦП используется два регистра для хранения 10-битного результата. Поскольку суммарная разрядность пары регистров ADRESH: ADRESL составляет 16 бит, то возможны два способа размещения 10-битного результата в этих регистрах.
В большинстве приложений вполне хватает 8-битных значений — в таких случаях можно спокойно отбросить два младших бита результата преобразования. Из Рис. 14.13, а видно, что эту операцию проще всего осуществить, выравнивая результат преобразования влево и игнорируя содержимое регистра ADRESL.
Рис. 14.13. Выравнивание 10-битного результата в 16-битном поле
Если же необходимо полное 10-битное значение, то бит ADCONl[7] следует установить в 1 для выравнивания результата по правому краю. Как видно из Рис. 14.13, б, в этом случае результат представляет собой 10-битное число, расширенное до 16 бит заполнением старших битов нулями. Соответственно для обработки этого значения можно использовать обычную 16-битную арифметику.
Процесс преобразования
После того как модуль АЦП сконфигурирован, оцифровка выбранного аналогового канала, с точки зрения пользователя, выглядит достаточно просто. Предполагая пока, что прерывания не используются, можно выделить следующие этапы преобразования (включая, для полноты, этап инициализации), которые в графическом виде изображены на Рис. 14.14:
1. Конфигурирование модуля АЦП:
• Конфигурирование выводов портов как аналоговых входов и/или входов опорного напряжения (ADCON1).
• Выбор источника тактового сигнала АЦП (ADCON0).
• Выбор входного канала АЦП (ADCON0).
• Включение модуля АЦП (ADCON0).
2. Ожидание требуемого времени установления, около 20 мкс.
3. Запуск преобразования установкой бита GO/DONE.
4. Ожидание завершения преобразования (сброса бита ).
5. Чтение регистров результата ADRES.
6. Переход к этапу 1 или 2 для выполнения следующего преобразования (зависит от программы).
Предположим в качестве примера, что нам необходимо поочередно считывать каждый из восьми аналоговых каналов микроконтроллера PIC16F874/7, выводя старшие восемь битов результата в порт В, а номер канала — в младшие три бита порта D. Частота основного резонатора составляет 20 МГц, в качестве опорного напряжения используется напряжение питания микроконтроллера.
Код, приведенный в Программе 14.1, предполагает, что после сброса модуль АЦП был сконфигурирован следующим образом:
Переключаемся в 1-й банк
Все разделяемые линии порта А — аналоговые
include "p16f877a.
bsf STATUS,RP0; Переключаемся а 1-й банк
clrf ADCON1; Все разделяемые линии порта А — аналоговые
clrf TRISB; Все выводы порта В — выходы
movlw b’11111000’; Младшие 3 бита порта D — выходы
movwf TRISD
bcf STATUS,RP0; Возвращаемся в 0-й банк
movlw b’10000001’; fosc/32 (10), СН0 (000)
movwf ADCON0; Не запускать преобразование (0), включить АЦП (1)
В данном случае разрешается использование всех восьми аналоговых каналов с внутренним ИОН, результат преобразования выравнивается полевому краю. Регистр ADCON1 инициализируется значением , при котором в качестве источника тактового сигнала используется fOSC/32 (20/32 = 625 кГц), что соответствует периоду tAD = 1.6 мкс, выбирается 0-й канал АЦП (что в принципе без разницы) и разрешается работа модуля. Поскольку бит
сброшен, преобразование пока не запускается.
Рис. 14.14. Временная развертка процесса преобразования
Основная программа, код которой приведен в Программе 14.1, постоянно крутится в бесконечном цикле. В каждом проходе этого цикла из ADRESH считывается оцифрованный результат преобразования очередного канала и копируется в регистр данных порта В. Перед оцифровкой значение счетчика каналов CHANNEL выдается в порт D в качестве числа по модулю 3.
Программа 14.1. 8-канальная система сбора данных
MAIN clrf CHANNEL; Используется в качестве счетчика каналов
MAIN_LOOP
movf CHANNEL,w; Берем номер канала
andlw b’00000111’; Обнуляем старшие 5 бит
movwf PORTD; Копируем в порт D
call GET_ANALOG; Оцифровываем, результат возвращается в W
movwf PORTB; Копируем его в порт В
incf CHANNEL,f; Переходим к следующему каналу
goto MAIN_LOOP; и так без конца
; ********************************
; * ФУНКЦИЯ: Аналого-цифровое преобразование n-го канала *
; * РЕСУРСЫ: Подпрограмма DELAY_17US, регистр TEMP *
; * ВХОД: Номер канала в W *
; * ВЫХОД: Оцифрованное 8-битное значение в W *
; *********************************
GET_ANALOG
movwf TEMP; Копируем номер канала в TEMP
bcf STATUS,С; Сдвигаем на три бита влево,
rlf TEMP,f
rlf TEMP,f
rlf TEMP,w; помещая результат в W
bcf ADCON0,CHS0; Обнуляем биты выбора канала
bcf ADCON0,CHS1
bcf ADCONO,CHS2
addwf ADCONO,f; Заносим номер канала в ADCON0 [5:3]
call DELAY_17US; Ждем 17 мкс для установления
bsf ADCON0,GO; Запускаем преобразование
GET_ANALOG_LOOP
btfsc ADCONO,GO; Проверим завершение преобразования
goto GET_ANALOG_LOOP
movf ADRESH,w; Считываем результат после сброса бита
GO/NOT_DONE
return
; ********************************
; * ФУНКЦИЯ: Формирует 17-мкс задержку при частоте 20 МГц (85 циклов) *
; * РЕСУРСЫ: Нет *
; * ВХОД: Нет *
; * ВЫХОД: W обнуляется *
; ********************************
DELAY_17US
movlw d’20’; Параметр задержки
DELAY_17US_LOOP
addlw -1; Декрементируем
btfss STATUS,Z; до нуля
goto DELAY_17US_LOOP
return
Собственно считывание данных осуществляется в подпрограмме GET_ANALOG, при вызове которой в младших трех битах рабочего регистра передается номер требуемого канала. Это значение копируется во временный регистр TEMP, содержимое которого затем сдвигается на три бита влево, чтобы переданный номер канала оказался в позиции битов CHSn регистра ADCON0. После сброса битов CHS[2:0] полученное значение складывается с содержимым ADCON0, в результате чего в битах CHS[2:0] оказывается номер канала.
После установки требуемого номера канала вызывается подпрограмма задержки для формирования паузы, необходимой для установления (стабилизации работы) ключа. Поскольку нам достаточно 8-битного разрешения, для заряда конденсаторов с погрешностью до 0.25 % финального (установившегося) значения достаточно задержки всего 6τ ~= 7 мкс (в худшем случае — 10 мкс), см. стр. 504. Затем для запуска преобразования устанавливается бит регистра ADCON0[184]. Завершение процесса преобразования контролируется по сбросу этого бита. К этому моменту в регистре ADRESH будет находиться 8-битный результат преобразования.
В общем каждое преобразование занимает около 13 х 16 ~= 21 мкс, таким образом, на оцифровку одного канала затрачивается 17 + 21 = 38 мкс. Соответственно, оцифровка всех восьми каналов (один проход) занимает 38 х 8 ~= 300 мкс, что дает нам скорость, примерно равную 3300 проходам в секунду.
Вместо того чтобы опрашивать состояние бита, окончание преобразования можно определять по генерации прерывания. В частности, если преобразование выполняется в то время, пока микроконтроллер находится в «спящем» режиме, то прерывание может использоваться для его «пробуждения». Модуль АЦП может работать во время «сна» микроконтроллера, поскольку имеет собственный тактовый генератор, независимый от системного тактового генератора микроконтроллера. Основным положительным моментом в выполнении преобразования во время «сна» микроконтроллера является то, что благодаря выключенному системному генератору оно выполняется в более спокойной электромагнитной обстановке. Отрицательной стороной можно назвать увеличение длительности преобразования, поскольку при выходе микроконтроллера из «спящего» режима формируется задержка длительностью 1024 такта, необходимая для перезапуска системного генератора (см. стр. 309).
Этот собственный генератор может использоваться и при работе микроконтроллера в нормальном режиме. Однако из-за отсутствия синхронизации между ним и системным тактовым генератором, возникают помехи от наложения тактовых сигналов, представляющие достаточно серьезную проблему, особенно при тактовых частотах микроконтроллера выше 1 МГц.
Для выполнения преобразования в «спящем» режиме необходимо выполнить следующее:
1. Выбрать в качестве источника тактового сигнала АЦП собственный RС-генератор модуля (ADCS1:0 =11).
2. Сбросить флаг ADIF для предотвращения немедленной генерации прерывания.
3. Установить биты масок ADIE и PEIE для разрешения прерывания от АЦП, которое будет использоваться для вывода микроконтроллера из «спящего» режима.
4. Если вы не хотите, чтобы после пробуждения микроконтроллера произошел переход к обработчику прерывания, необходимо сбросить бит общего разрешения прерываний GIE.
5. Для запуска преобразования сбросить бит регистра ADCON0, после чего сразу же выполнить команду sleep.
6. После «пробуждения» микроконтроллера считать оцифрованное значение из регистров ADRESH: L.
В качестве примера напишем новый вариант подпрограммы GET_ANALOG из Программы 14.1, использующий «спящий» режим. На этот раз в секции инициализации необходимо указанным выше образом сконфигурировать систему прерываний, чтобы обеспечить вывод микроконтроллера из «спящего» режима при установке флага ADIF (которая происходит одновременно со сбросом бита ) после завершения преобразования.
include "p16f877а. inc"
bsf STATUS,RP0; Переключаемся в 1-й банк
clrf ADCON1; Все разделяемые линии порта А — аналоговые
clrf TRISB; Все выводы порта В — выходы
movlw b’11111000’; Младшие 3 бита порта D — выходы
movwf TRISD
bsf PIE1,ADIE; Разрешаем прерывание от АЦП
bcf STATUS,RP0; Возвращаемся в 0-й банк
movlw b’11000001’; Xta1/32 (10), СН0 (000)
moywf ADCQN0; Не запускать преобразование (0), включить АЦП (1)
bcf PIR1,ADIF; Сбрасываем флаг прерывания
bsf INTCON,PEIE; Разрешаем прерывания от периферийных устройств
bsf INTCON,GIE; и прерывания вообще
Помимо инициализации системы прерываний, еще одно изменение связано с установкой битов ADCONO[7:6], которые на этот раз равны Ь’11’, чтобы выбрать внутренний RC-генератор для тактирования АЦП.
Код подпрограммы GET_ANALOG для работы в «спящем» режиме, приведенной в Программе 14.2, практически идентичен исходному варианту, за исключением следующих моментов:
1. Если запрос на прерывание может генерироваться другими периферийными устройствами, то бит GIE необходимо сбрасывать.
2. Перед запуском преобразования необходимо сбрасывать флаг ADIF для предотвращения преждевременного выхода из «спящего» режима.
3. Команда sleep расположена сразу после команды установки бита . При работе АЦП от собственного тактового генератора перед началом преобразования автоматически вставляется дополнительная задержка длительностью tDA, гарантирующая, что преобразование начнется только после исполнения команды sleep.
4. В данном случае нет необходимости опрашивать состояние флага , поскольку микроконтроллер возобновит выполнение программы только после завершения преобразования. В нашем примере бит маски GIE сбрасывается, поэтому при наличии прерываний от других периферийных устройств этот бит после «пробуждения» необходимо установить повторно. Если перед входом в «спящий» режим не сбрасывать бит GIE, то после «пробуждения» процессор автоматически перейдет к выполнению обработчика прерывания.
Программа 14.2. Оцифровка канала в 8-канальной системе сбора данных
; ******************
; * ФУНКЦИЯ: Аналого-цифровое преобразование n-го канала *
; * РЕСУРСЫ: Подпрограмма DELAY_17US, регистр TEMP *
; * ВХОД: Номер канала в W *
; * ВЫХОД: Оцифрованное 8-битное значение в W *
; ******************
GET_ANALOG
movwf TEMP ; Копируем номер канала в TEMP
bcf STATUS,С; Сдвигаем на три бита влево,
rlf TEMP,f
rlf TEMP,f
rlf TEMP,w; помещая результат в W
bcf ADCON0,CHS0; Обнуляем биты выбора канала
bcf ADCON0,CHS1
bcf ADCON0,CHS2
addwf ADCONO,f; Заносим номер канала в ADCON0 [5:3]
call DELAY_17US; Ждем 17 мкс для установления
bcf INTCON,GIE; Запрещаем все прерывания
bcf PIR1,ADIF; Предварительно сбрасываем флаг ADIF
bsf ADCON0,GO; Запускаем преобразование
sleep; Немного поспим
bsf INTCON,GIE; Разрешаем прерывания (если необходимо)
movf ADRESH,w; Считываем результат после пробуждения
return
В качестве заключительного примера давайте напишем на Си программу для микроконтроллера PIC16F874 (20 МГц), который должен работать как компаратор, наподобие устройства из Примера 11.2 (стр. 354). В данном случае мы будем сравнивать 8-битное слово N, подаваемое в параллельном виде на порт В, с цифровым представлением аналогового сигнала 1-го канала АЦП. Результат сравнения будет выставляться на выходы RC[2:0] в виде 3-битного кода: Ь’001’ — при аналоговом сигнале, меньшем N, Ь’О10’ — в случае равенства и Ь’100’ — при аналоговом сигнале, большем N. Компаратор должен иметь гистерезис величиной ±1 бит, названный в программе delta. Таким образом, если при предыдущем сравнении аналоговый сигнал оказался меньше N, то новый уровень будет равен N + 1. В обратном случае уровень переключения становится равным N — 1.
Функция compare () из Программы 14.3 предполагает, что микроконтроллер уже инициализирован следующим образом:
#include <16f874.h>
#byte P0RT_B = 0x06
#byte PORT_C = 0x07
#device ADC=8 /* Результат преобразования — 8-битное число */
/* Объявляем функцию, в которую в качестве параметра передается гистерезис (+1 или -1) и которая возвращает новое значение гистерезиса */
unsigned int compare(unsigned int delta);
void main(void)
{
unsigned int hysteresis = 0;
set_tris_c(0xF8);
setup_adc(ADC_CLOCK_DIV_32);
setup_adc_ports(RA0_RA1_RA3_ANALOG);
set_adc_channel(1);
Ниже приведены основные функции компилятора CCS для работы с модулем АЦП.
∙ setup_adc(ADC_CLOCK_DIV_32)
Эта функция загружает требуемое значение в биты ADCS1[1:0], определяющие источник тактового сигнала модуля; в данном случае используется деленный на 32 сигнал от тактового генератора процессора. Для выбора внутреннего RС-генератора следует использовать константу ADC_CLOCK_INTERNAL.
∙ setup_adc_ports(RA0_RA1_RA3_ANALOG)
Эта функция конфигурирует биты PCFG[3:0] регистра ADCON1, определяющие, какие из выводов порта будут аналоговыми, какие — цифровыми и будет ли использовано внешнее опорное напряжение. Константа RA0_RA1_RA3_ANALOG соответствует такой конфигурации, при которой в качестве аналоговых входов используются линии порта RA3 и RA[1:0] (с внутренним источником опорного напряжения), тогда как остальные линии порта остаются цифровыми — PCFG[3:0] = b’0100’ (см. Рис. 14.11). Если же мы хотим использовать вывод RA3 для подключения внешнего ИОН Vref+, то в качестве параметра функции следует указать константу RA0_RA1_ANALOG_RA3_REF. Эти константы, применимые для каждого конкретного устройства, определены в соответствующих заголовочных файлах, в нашем случае — в файле 16f874.h. Для всех устройств, имеющих в своем составе модули АЦП, определены, по меньшей мере, две константы: ALL_ANALOG И NO_ANALOGS.
∙ set_adc_channel(n);
Эта функция используется для загрузки номера текущего канала в биты CHS[2:0] регистра ADCON0.
∙ read_adc();
Эта функция устанавливает флаг регистра ADCON0 и возвращает содержимое регистров ADRESH: L после сброса данного бита.
∙ #device ADC=8
Этой директивой задается выравнивание 10-битного результата преобразования по левой границе (см. Рис. 14.13). В таком случае функция read_adc () возвращает 8-битное целое число, считываемое из регистра ADRESH. При наличии в тексте программы директивы #device ADC=10 эта же функция возвращает 2-байтное значение типа long int.
В функцию compare () из Программы 14.3 в качестве параметра передается значение гистерезиса, названного delta, который может быть равен +1 или -1 (h’FF’). Результат преобразования сохраняется в локальной переменной analog, которая затем сравнивается с содержимым порта В плюс delta. По результату сравнения на линии RC[2:0] порта С выдается соответствующий код.
Программа 14.3. Цифро-аналоговый компаратор с гистерезисом
unsigned int compare(unsigned int delta)
{
unsigned int analog;
analog = read_adc();
if(analog > PQRT_B + delta)
{PORT_C = 0x04; delta = 0xff;}
else
if(analog == PORT_B)
{PORT_C = 0x02;}
else
{PORT_C = 0x01; delta = 1;}
return delta;
}
В соответствии с результатом сравнения также обновляется значение переменной delta, т. е. delta = +1, если analog < (PORTJB + delta), и delta = -1, если analog > (PORT_B + delta). Новое значение delta возвращается функцией в вызывающую программу, что позволяет той обновить значение своей локальной переменной (назовем ее hysteresis). Таким образом, для одновременного формирования выходного сигнала компаратора и обновления значения переменной hysteresis в вызывающей программе должно присутствовать следующее выражение:
hysteresis = compare(hysteresis);
В качестве альтернативы можно было бы объявить переменную hysteresis вне функции main (). Тогда эта переменная стала бы глобальной, т. е. ее значение было бы доступно всем функциям программы и его не потребовалось бы передавать между функциями.
* * *
Преобразование цифровой величины в эквивалентное аналоговое напряжение является более простой операцией, нежели рассмотренное нами аналого-цифровое преобразование, да и требуется не так часто. Наверное, именно по этим причинам цифро-аналоговые преобразователи (ЦАП) достаточно редко встречаются в составе большинства микроконтроллеров.
Мы с вами уже знаем, что одним из методов цифро-аналогового преобразования является управление коэффициентом заполнения импульсной последовательности, имеющей фиксированную частоту, как показано на Рис. 13.9 (стр. 476). Чем меньше в данном случае исходное значение, тем меньше длительность импульсов и тем меньше напряжение на выходе ФНЧ, который выполняет усреднение или, иначе, выделяет постоянную составляющую. И, наоборот, большому значению соответствует большой коэффициент заполнения, который в свою очередь приводит к появлению высокого напряжения.
Цифро-аналоговое преобразование с помощью ШИМ может иметь очень высокую точность и быть простым в реализации. Однако для удаления из выходного сигнала гармоник, кратных частоте импульсов, требуется очень хорошая фильтрация, что приводит к увеличению времени отклика на изменение цифрового значения. Обычно ШИМ используется для управления мощными нагрузками, такими как электродвигатели или нагревательные элементы, в которых сглаживание осуществляется за счет инерционности самих исполнительных устройств. Более того, импульсный характер сигнала как нельзя лучше подходит для управления мощностью с помощью тиристорных схем.
Другой способ формирования аналогового сигнала заключается в коммутации отводов многозвенного резисторного делителя, каждая ступень которого изменяет выходное напряжение на величину, соответствующую младшему биту. Этот принцип использовался в модуле опорного напряжения компаратора, показанном на Рис. 14.7. Однако для осуществления цифро-аналогового преобразования требуется намного больше резисторов. Так, для 10-битного ЦАП требуется цепочка из 1024 резисторов.
В продаже имеется очень много микросхем ЦАП, управляемых извне. Две такие микросхемы были показаны на Рис. 12.3 и Рис. 12.5 (стр. 374 и 379 соответственно). Передача цифрового значения в эти микросхемы осуществлялась последовательно. Теперь же для полноты картины давайте познакомимся с микросхемой, имеющей параллельный интерфейс для ввода цифровых данных.
Подавляющее большинство микросхем ЦАП основаны на многозвенной резистивной цепи типа R-2R, подобной изображенной на Рис. 14.15, а. Напряжение, прикладываемое к каждому отводу при замыкании соответствующего ключа, передается на выходной узел после ослабления (деления). Как мы увидим чуть позже, каждая последующая ступень ослабляет это напряжение Ьi в 2 раза, формируя для N-битного значения следующую весовую функцию:
Сопротивление в точке А схемы, показанной на Рис. 14.15,б, равно R (2R||2R), в результате чего напряжение ослабляется в 2 раза. По мере продвижения к правому краю цепочки этот процесс повторяется, деля каждое из напряжений на два. Так, в точке В напряжение Ь0/2 уменьшается в 2 раза, в результате чего мы получаем = Ь0/4. Поскольку схема симметрична, сопротивление каждого узла с левой стороны также равно 2R. Это означает, что со стороны любого цифрового ключа общее сопротивление равно 2R + 2R||2R = 3R. Это очень важно, поскольку характеристики транзисторного ключа, такие как его сопротивление, зависят от тока, и поддержание их на одном уровне уменьшает ошибку преобразования.
Рис. 14.15. Цифро-аналоговое преобразование с помощью многозвенной резистивной цепи типа R-2R
Для простоты мы ограничились рассмотрением только для трех битов. Однако данный пример можно расширить простым переносом левого оконечного резистора и вставкой требуемого количества секций. Это не влияет на сопротивление узла с правой стороны и, соответственно, не изменяет режимов работы расположенных правее секций. Если мы еще раз взглянем на наши рассуждения, то увидим, что нигде в вычислениях не фигурирует абсолютное значение сопротивления. На самом деле точность преобразования зависит только от соотношения R:2R. Дело в том, что резисторы с точным соотношением сопротивлений изготовить на кремниевой подложке относительно легко, в отличие от резисторов с точными абсолютными значениями сопротивлений. По этой причине в большинстве интегральных микросхем ЦАП используются многозвенные цепи R-2R.
В качестве примера возьмем широко распространенную микросхему МАХ506 компании Maxim, изображенную на Рис. 14.16. Это устройство в 20-выводном корпусе содержит четыре независимых ЦАП, использующих одно внешнее опорное напряжение VKf. Цифровые данные подаются на выводы D[7:0], а один из четырех регистров-защелок выбирается с помощью адресных входов А[1:0]. После защелкивания байт данных перегружается в выбранный регистр и появляется на соответствующем выходе VOUTn.
Рис. 14.16. Счетверенный 8-битный ЦАП МАХ506 компании Maxim
Это выходное напряжение будет находиться в диапазоне от нуля (аналоговая земля — AGND) — для входного кода h’00’ и до Vref — для входного кода h’FF’. Когда вывод VSS подключен к общему проводу, напряжение Vref может иметь любое значение от 0 В до VDD (+5 В). Однако напряжение на выводе VSS может достигать значения -5 В, и в этом случае Vref может лежать в диапазоне ±5 В. Если Vref отрицательно (в случае двухполярного источника питания), то выходное напряжение также будет отрицательным. В любом случае выходное напряжение определяется выражением D х Vref, где D — входной цифровой код, соответствующий долям из диапазона 0…1 (h’00’…h’FF’).
Микросхема МАХ505 представляет собой 24-выводную модификацию предыдущей микросхемы, которая позволяет использовать с каждым из четырех ЦАП отдельный источник опорного напряжения. Кроме того, в этой микросхеме защелки ЦАП отделены от резистивной цепи преобразования дополнительным уровнем защелок, управляемых одним и тем же сигналом . Такая двойная буферизация позволяет программисту обновлять выходное значение всех четырех ЦАП одновременно после загрузки регистров каждого канала.
Для примера предположим, что выводы адреса МАХ506 подключены к выводам RA[1:0] микроконтроллера, а вывод RA2 микроконтроллера управляет входом для защелкивания адресованного байта данных, формируемого на выводах порта В. Тогда для формирования на выходе DACD пилообразного сигнала, показанного на Рис. 14.17, можно написать следующую процедуру:
movlw b’0111’; DACD — 3-й канал (b’11’), WR = 1
movwf PORTA; Выдаем на выводы WR и A1:0 МАХ506
LOOP movwf PORTB; Данные передаем на выводы D7:0 МАХ506
bcf PORTA,2;WR = 0; Защелкиваем данные,
bsf PORTA, 2;WR = 1; формируя импульс на входе WR
addlw 1; Инкрементируем счетчик
goto LOOP; и так без конца
Предполагается, что все линии порта В и линии RA[2:0] порта А уже сконфигурированы как выходы.
Пилообразный выходной сигнал ЦАП, изображенный на Рис. 14.17, формируется при использовании микроконтроллера с 12-МГц резонатором. При длительности каждой итерации цикла, равной шести машинным циклам, период пилообразного сигнала получится равным (256 х 6)/3 ~= 0.5 мс.
Рис. 14.17. Формирование пилообразного сигнала с использованием ЦАП МАХ506
Примеры
Пример 14.1
Диапазон входного напряжения аналоговых каналов в большинстве модулей АЦП[185] ограничен положительным диапазоном 0…Vref+, где в качестве Vref+ может выступать либо напряжение питания VDD, либо внешнее напряжение, подаваемое на вход RA3 и лежащее в диапазоне 3 B…VDD. Однако во многих случаях возникает необходимость оцифровки биполярных аналоговых сигналов. Сконструируйте простую резистивную цепочку для сдвига биполярного напряжения из диапазона ±10 В в однополярный диапазон 0…5 В, полагая, что Vref+ равно +5 В. Доработайте конструкцию, добавив фильтр, устраняющий эффект наложения спектров, и полагая, что выборка осуществляется с частотой 5000 отсчетов/с.
Решение
Один из возможных вариантов решения этой задачи представлен на Рис. 14.18. Сопротивления трех резисторов должны быть такими, чтобы при входном напряжении О В на входе AN формировалось бы напряжение, равное половине шкалы (Vref+/2 = 2.5 В). Кроме того, входное напряжение должно быть ослаблено в четыре раза. В общем виде это соотношение можно выразить следующим образом: Vin = ±G x Vref+.
Рис. 14.18. Резистивная цепочка для сдвига уровня напряжения
Сопротивления резисторов определяются из следующих соображений:
1. Когда Vin = 0, напряжение на суммирующем узле равно половине диапазона, что соответствует выходному значению Ь’10000000’. Для этого сопротивление параллельно соединенных резисторов R1 и R2 должно быть равно сопротивлению R3, т. е.
R3 = R1||R2.
2. Ослабление сигнала осуществляется делителем напряжения, составленным из резисторов R1 и R2||R3. Соответственно значение G определяется из выражения
2G = (R1 + (R2||R3)/(R2||R3);
в нашем случае G = 2.
После ряда преобразований получим
R1 = (G — 1) x R2
R2 = G x R3
Понятно, что у нас имеется три неизвестных и всего два уравнения, поэтому для начала мы должны выбрать значение для одного из параметров. Задав сопротивление R3 равным 5 кОм, получим R2 = 2 х 5 = 10 кОм и R1 = 10 кОм.
Со стороны входа микроконтроллера все три резистора оказываются соединенными параллельно, поэтому выходное сопротивление нашей схемы равно 2.4 кОм. Это значение удовлетворяет требованию, предъявляемому модулем АЦП, по сохранению ошибки, вызванной токами утечки, в пределах младшего значащего бита для 10-битного преобразования. При 8-битном преобразовании значения резисторов следует увеличить в 4 раза.
С помощью конденсатора небольшой емкости, подключенного к суммирующему узлу, можно реализовать простейший ФНЧ первого порядка для ослабления высокочастотных составляющих, наводимых внешними источниками, такими как тактовый генератор микроконтроллера. Этот же ФНЧ выполняет роль фильтра, устраняющего эффект наложения спектров, как было показано на Рис. 14.4. При частоте выборок, равной 5000 отсчетам в секунду, частота среза фильтра не должна превышать 2.5 кГц — половины частоты выборок. Поскольку ослабление в таком фильтре составляет всего 6 дБ/октаву, то лучше выбрать частоту среза 1/2πCR, равную 1 кГц. Таким образом, получаем
1/2πCR = 1000
C = 10-6/4.8xπ
C ~= 66 нФ
Чтобы еще больше снизить шумы, конденсатор фильтра должен иметь хорошие высокочастотные параметры (на высоких частотах конденсаторы становятся индуктивностями) и вместе с резистором должен быть размещен как можно ближе к входу, а рядом с ним не должно проходить никаких цифровых линий. Хорошей практикой является развязывание опорного напряжения и напряжения питания с помощью танталовых электролитических конденсаторов малой емкости и/или керамических конденсаторов емкостью 0.1 мкФ для уменьшения помех, вызванных работой микроконтроллера и других устройств, питающихся от того же источника. Используя отдельные линии питания и земли для подключения микроконтроллера к источнику питания, можно еще больше снизить уровень помех от этого источника.
Пример 14.2
Одной из задач интеллектуального биомедицинского монитора является периодическое измерение пикового напряжения сигнала ЭКГ. Значение, соответствующее данной точке R (см. Рис. 7.1 на стр. 208), должно выводиться через порт В, и при обновлении этого значения на выводе RA5 должен формироваться положительный импульс. Предполагая, что для реализации указанного устройства используется микроконтроллер PIC16F87X, а сигнал ЭКГ поступает на вход RA1, разработайте возможную методику решения указанной задачи. Для прерывания процессора 2000 раз в секунду мы будем использовать Таймер 0 (см. Программу 13.2 на стр. 461). Напишите процедуру обработки прерывания, соответствующую разработанному алгоритму.
Решение
Как и любой биомедицинский параметр, сигнал ЭКГ отличается от такта к такту амплитудой, формой и периодом. Даже если бы это было и не так, несовершенство элементов системы сбора данных, в особенности кожных электродов, может привести к медленному дрейфу базовой линии (постоянной составляющей сигнала). Поэтому величину порогового напряжения, начиная с которого мы будем отслеживать появление пикового (точка R) значения сигнала, необходимо во время каждого периода принимать равной некоторой части амплитуды предыдущего пика.
Один из возможных вариантов реализации этого метода приведен на Рис. 14.19. В данном случае после каждого импульса порог слегка уменьшается, чтобы исключить пропуск последующего пика с меньшей амплитудой. Примем минимальную частоту ЭКГ равной 40 ударам в минуту (период 1.5 с). Тогда если при каждой выборке мы будем уменьшать пороговое значение на 1/64 бита, то при частоте 2000 выборок/с максимальное уменьшение составит ~= 47. Для этого пороговое значение THRESHOLD в Программе 14.4 хранится как двухбайтное значение в формате целое: дробное, и после каждой выборки, в которой пиковое значение MAXIMUM не обновляется, из порогового значения вычитается 1/64 целого (т. е. дробное, равное Ь’00000100’). Изменяя вычитаемое, можно управлять скоростью изменения порогового значения.
Рис. 14.19. Стратегия определения пикового значения сигнала ЭКГ
Данная программа работает по следующему алгоритму:
1. ВЫПОЛНИТЬ преобразование для получения значения ANALOG.
2. ЕСЛИ (ANALOG > THRESHOLD)
• MAXIMUM = ANALOG
• THRESHOLD = ANALOG
• PORTB = ANALOG
• RA5 = 1
3. ИНАЧЕ
• THRESHOLD = THRESHOLD — 1/64
• RA5 = 0
При изменении порогового значения THRESHOLD (в случае, если ANALOG > THRESHOLD) в регистр, содержащий целую часть числа, заносится новое значение MAXIMUM, а регистр с дробной частью обнуляется. Если интерпретировать эту пару байтов как 16-битное слово, то пороговое значение можно вычислить как MAXIMUM х 256 или, иначе, THRESHOLD = MAXIMUM << 8. Предполагается, что значение THRESHOLD было обнулено фоновой программой на этапе инициализации и что мы используем 8-битное аналого-цифровое преобразование.
Если оцифрованное значение меньше порогового, то из младшего байта, расположенного в регистре THRESHOLD+1, вычитается h’04’ = Ь’00000100’, и, если при этом возникает заем, декрементируется старший байт THRESHOLD. При равенстве порогового значения нулю эта операция вычитания пропускается — таким образом, предотвращается потеря значимости.
В Программе 14.4 используется подпрограмма GET_ANALOG из Программы 14.1, а также необходимая для ее работы подпрограмма формирования 17-мкс задержки. Однако, поскольку в данном случае интервал между вызовами подпрограммы достаточно велик, длительность задержки при необходимости можно уменьшить до 10 мкс.
Программа 14.4. Определение пикового значения ЭКГ
; ************************************
; * ФУНКЦИЯ: Обработчик для обновления параметров ЭКГ *
; * ВХОД: По прерыванию от Таймера 0 *
; * ВЫХОД: Обновляет MAXIMUM и THRESHOLD: THRESHOLD+1 *
; * РЕСУРСЫ: П/п GET_ANALOG, возвращающая 8-битное значение *
**************************************
; Сначала сохраняем контекст
EKG_ISR movwf _work; Сохраняем W
swapf STATUS,w; и регистр STATUS
movwf _status
; ===========================
btf ss INTCON,T0IF; Это было прерывание от Таймера 0?
goto EKG_EXIT; ЕСЛИ нет, ТО выходим
bcf INTCON,T0IF; Сбрасываем флаг
movlw 1; Запускаем преобразование
call GET_ANALOG; по 1-му каналу
movwf TEMP; Сохраняем оцифрованное значение
subwf THRESHOLD,w; THRESHOLD — ANALOG
btf sc STATUS,С; ЕСЛИ нет заема, ТО
goto BELOW; не обновляем MAXIMUM
movf TEMP,w; ИНАЧЕ берем оцифрованное значение
movwf MAXIMUM; которое становится новым MAXIMUM
movwf PORTB; Выдаем наружу
bsf PORTA,5; Сообщаем об этом
movwf THRESHOLD; Теперь обновляем 2-байтный
clrf THRESHOLD+1; порог
goto EKG_EXIT; и выходим
; Сюда попадаем, если входной сигнал ниже порога
BELOW bcf PORTA,5; Сообщаем об отсутствии обновления
; Теперь уменьшаем порог на 1/64 до нуля
movf THRESHOLD,f; Целая часть порога равна нулю?
btfsc STATUS,Z; ЕСЛИ нет, ТО пропускаем
goto EKG_EXIT; ЕСЛИ да, ТО выходим
movlw h’04’; 1/64 = b’000001000’
subwf THRESHOLD+1,f; Вычитаем из байта дробной части
btfss STATUS,С; Пропускаем, если нет заема
decf THRESHOLD,f; ИНАЧЕ декрементируем целую часть
; ==========================
EKG_EXIT swapf _status,w; Восстанавливаем STATUS
movwf STATUS
swapf _work,f; Восстанавливаем W,
swapf _work,w; не затрагивая регистр STATUS,
retfie; и выходим из прерывания
В Программе 14.5 приведена программа на языке Си, реализующая тот же самый алгоритм. Директива #int_rtcc указывает компилятору интерпретировать описанную после нее функцию как процедуру обработки прерывания от часов реального времени (Таймера 0). Переменные threshold и maximum в функции ecg_isr () объявлены как статические (static). Это означает, что их значения будут сохранены после выхода из функции и доступны при последующем входе в функцию. По умолчанию локальные переменные функций сохраняют свое значение только на время выполнения функции. В качестве альтернативного варианта можно было бы объявить такие переменные вне всех функций. В этом случае переменные становятся глобальными, и их значения сохраняются на протяжении всего времени работы программы.
Программа 14.5. Определение пикового значения ЭКГ на Си
#byte PORT_B =6 /* Вывод RA5 — 5-й бит порта А
#bit RA5 =5.5 /* Порт В — регистр 06
#int_rtcc
void ecg_isr(void)
{
unsigned int analog;
static unsigned long int threshold = 0;
static unsigned int maximum;
analog = read_adc();
if (analog > threshold»8)
{
maximum = analog; /* Новое максимальное значение */
PORT_B = analog; /* Выдаем наружу */
threshold = maximum << 8; /* Новый 2-байтный порог */
RA5 =1; /* Сообщаем об этом */
}
else
if(threshold >= 0x0004) /* ЕСЛИ порог не менее h’0004’, */
{
threshold = threshold — 0x0004; /* ТО уменьшаем на 1/64 */
RA5 =0; /* Сообщаем об отсутствии обновления */
}
}
Переменная threshold имеет тип long int, поэтому компилятор CCS будет интерпретировать ее как 16-битное число. Обнуление переменной threshold выполняется единожды при запуске программы, поскольку переменная объявлена как static. И опять же, такое поведение отличается от поведения автоматических переменных, создаваемых по умолчанию.
При занесении в переменную threshold нового максимального значения последнее умножается на 256 путем сдвига на восемь разрядов влево. Хороший компилятор автоматически преобразует выражение N*256 к виду N << 8 или же, что еще лучше, просто возьмет в качестве результата операции старший байт пары.
Пример 14.3
Микроконтроллер используется для вычисления энергии разряда двухфазного дефибриллятора, приведенного на Рис. 14.5. Когда микроконтроллер обнаруживает начало разряда, он должен сделать 256 выборок с частотой 20 000 выборок в секунду. При этом энергия определяется как сумма квадратов отклонений сигнала от базового уровня — предполагается, что сопротивление цепи «грудная клетка пациента — электроды» остается постоянным на протяжении всего разряда.
Для получения опорного напряжения используется внешний ИОН с выходным напряжением 4.096 В, что при 8-битном преобразовании даст нам разрешение, равное 16 мВ. После начала разряда на выводе RA4 необходимо сформировать импульс для запуска развертки запоминающего осциллографа, позволяющего сохранить осциллограмму сигнала для архивных целей. А после окончания разряда старший байт значения энергии должен быть выведен в порт В для отображения на дисплее.
Покажите, как можно с помощью микроконтроллера PIC16F87XA с 20-МГц резонатором реализовать указанную измерительную систему. Можете считать, что на ИОН можно подавать смещение наподобие стабилитрона. На практике для достижения более точных результатов может использоваться дополнительный переменный резистор, с помощью которого осуществляется подстройка выходного напряжения ИОН в небольших пределах.
Решение
Подходящая схема показана на Рис. 14.20. Собственно сигнал, изменяющийся в диапазоне +1.8…+3.6 В (см. Рис. 14.5), подается на вход 0-го аналогового канала RA0/AIN0. Резистор сопротивлением 10 кОм защищает аналоговый вход от перегрузки, одновременно выполняя, совместно с конденсатором 3300 пФ, роль фильтра, устраняющего эффект наложения спектров, с частотой среза около 450 кГц. Поскольку реальные дефибрилляторы работают с очень большими напряжениями (порядка 25 кВ), для защиты микроконтроллера от высоковольтных выбросов используется два диода 1N4004, дополняющие внутренние защитные диоды (см. Рис. 14.12).
Рис. 14.20. Измерение энергии разряда дефибриллятора
Внешний ИОН напряжением 4.096 В подключен непосредственно к выводу RA3, который является входом внешнего опорного напряжения (конфигурация АЦП — Ь’0101’). Чтобы снизить уровень помех на линиях VDD и Vref+, к ним подключены развязывающие танталовые конденсаторы емкостью 1 мкФ.
Для определения начального момента разряда используется внутренний аналоговый компаратор, как было показано на Рис. 14.5. При работе компаратора в режиме Ь’1110’ для формирования внутреннего опорного напряжения может использоваться модуль CVREF, как было описано на стр. 501. При сброшенном бите CIS (см. Рис. 14.6) компаратор 1 может использовать 0-й аналоговый канал совместно с модулем АЦП.
И, наконец, вывод RA4 и все выводы порта В должны быть сконфигурированы как выходы. Первый из указанных выводов используется для формирования синхроимпульса, а порт В — для вывода полученного результата.
include "p16f877a.inc"
org 0; Вектор сброса
goto SET_UP; Переход на фоновую программу
org 4; Вектор прерывания
goto ECG_ISR; Обслуживаем прерывание от компаратора
SET_UP
bsf STATUSfRP0; Переключаемся в 1-й банк
movlw b’00000110’; Режим работы компаратора = 110, CIS = 0
movwf CMCON
call DEIAY_17US; Идем 17 мкс для установления напряжений
movf CMCON,f; Читаем СМСОN, чтобы сбросить признак изменения
bsf PIE2,CMIE; Разрешаем прерывания от компаратора
movlw b’10001110’; Модуль CVREF вкл. (1), внутр. ИОН (0)
movwf CVRCON; Верхний диапазон (0), CVR[3:0] = 1110
movlw b’00000101’; RA0/1 — аналоговые входы
movwf ADCON1; RA3 — вход опорного напряжения
movlw b’101111b’; RA4 — выход
movwf TRISA
clrf TRISB; Все выводы порта В — выходы
bcf STATUS,RP0; Возвращаемся в 0-й банк
movlw b’100000011; Включаем модуль АЦП (fosc/32)
movwf ADCONO
bcf PIR2,CMIF; Сбрасываем флаг прерывания от компаратора
bsf INTCON,PEIE; Разрешаем прерывания от периферийных устройств
bsf INTCON,GIE; Разрешаем работу системы прерываний
Выше приведена секция инициализация для нашей программы. В данном случае модули конфигурируются следующим образом:
1. Модуль аналогового компаратора работает в режиме b’110’, при этом CIS = 0. Для выдерживания интервала, требуемого для установления внутренних сигналов модуля, используется подпрограмма DELAY_17US (чтобы не писать отдельный код для формирования 10-мкс задержки). После этого выполняется чтение регистра CMCON для сброса признака изменения состояния компаратора. Затем сбрасывается флаг CMIF и разрешаются прерывания.
2. Модуль CVREF работает в режиме b’1110’ и использует верхний диапазон. Таким образом, он формирует опорное напряжение 3.4375 В.
3. Модуль АЦП работает в режиме Ь’0101’, при котором выводы RA0 и RA1 используются в качестве аналоговых входов, а вывод RA3 — для подачи внешнего опорного напряжения Vref+. Результат преобразования выравнивается по левой границе для упрощения получения 8-битного результата. В качестве тактового сигнала АЦП используется системный сигнал, деленный на 32. При этом в соответствии с Табл. 14.2 частота преобразования получается равной 625 кГц.
4. PORTA[4] конфигурируется как выход. Остальные выводы порта А остаются входами для обеспечения функциональности аналоговых входов AIN0, AIN1 и AIN3. Все выводы порта В конфигурируются как выходы.
Код собственно программы приведен в Программе 14.6. В процедуре MAIN микроконтроллер просто переключается в «спящий» режим до момента изменения состояния аналогового компаратора, по которому генерируется прерывание. После возврата управления в фоновую процедуру старший байт трехбайтной переменной, в которой находится вычисленное значение мощности, копируется в порт В, а затем описанный процесс повторяется.
Программа 14.6. Измерение энергии разряда дефибриллятора
MAIN sleep; Ждем
nop
movf POWER,w; Берем старший байт значения
movwf PORT В; и выводим его в порт В
goto MAIN
; **************************************
* ФУНКЦИЯ: Обработчик прерывания, в котором вычисляется энергия разряда дефибриллятора *
* ВХОД: По прерыванию от модуля компараторов *
* ВЫХОД: Обновляется значение POWER:3 *
* РЕСУРСЫ: П/п GET_ANALOG, возвращающая 8-битное значение, *
* РЕСУРСЫ: п/п SQUARE, выполняющая умножение 8x8 битов *
; ***************************************
Сначала сохраняем контекст
ECG_ISR movwf _work; Сохраняем W
swapf STATUS,w; и регистр STATUS
movwf status
; ==============================
btfss PIR2,CMIF; Это прерывание от компаратора?
goto ECG_EXIT; ЕСЛИ нет, ТО выходим
clrf POWER; Обнуляем регистры результата
clrf POWER+1
clrf POWER+2; Младший байт
clrf COUNT; Обнуляем счетчик (256 итераций)
bcf PORTA,4; Формируем на RA4
bsf PORTA,4; синхроимпульс
bcf PORTA, 4
ACQUIRE clrw; Канал 0 (W = h'00')
call GET_ANALOG; Запускаем преобразование
addlw -BASELINE; Определяем разность с базовым напряжением
bcfsc STATUS,С; ЕСЛИ заем (С==0), ТО обходим,
goto ECG_CONTINUE; так как разность положительна
xorlw b’11111111’; ИНАЧЕ инвертируем и прибавляем
ECG_CONTINUE
call SQR; Возводим в квадрат
movf SQUARE+1,w; Берем младший байт квадрата напряжения
addwf POWER+2,f; Прибавляем к младшему байту результата
btfss STATUS,С; Проверяем перенос
goto NEXT_BYTE; ЕСЛИ нет, ТО складываем след, байты
movlw 1; Инкрементируем средний байт результата
addwf POWER+1,f
btfsc STATUS,С; Был перенос?
incf POWER,f; ЕСЛИ да, ТО инкрементируем старший байт
NEXT BYTE
movf SQUARE,w; Берем старший байт квадрата напряжения
addwf POWER+1,f; Прибавляем к среднему байту результата
btfsc STATUS,С; Проверяем перенос
incf POWER,f; ЕСЛИ нет, ТО инкрементируем старший байт
call DELAY_470US; Ждем перед следующей выборкой
incfsz COUNT,f; Инкрементируем счетчик цикла и повторяем
goto ACQUIRE; операции, если он не равен 0
;========================
EGG_EXIT sf STATUS,RP0; Сначала сбрасываем признак изменения
movf CMCON,f; состояния компаратора,
bcf STATUS,RP0; читая CMCON из 1-го банка,
bcf PIR2,CMIF; и сбрасываем флаг прерывания
swapf _status,w; Восстанавливаем регистр STATUS
movwf STATUS
swapf _work,f; Восстанавливаем W, не затрагивая
swapf _work,w; регистр STATUS,
retfie ; и выходим из прерывания
После сохранения контекста обработчик прерывания сначала проверяет источник прерывания, а затем сбрасывает счетчик итераций цикла и три регистра, используемые для накопления суммы из 256 квадратов отсчетов напряжения. После этого на выводе RA4 формируется короткий импульс, извещая внешние устройства о начале разряда.
Для получения 8-битного оцифрованного значения используется подпрограмма GET_ANALOG из Программы 14.1. Затем вычисляется отклонение от базового уровня, которое принимается равным 2.6 В (см. Рис. 14.5). Если эта величина отрицательна (входное напряжение меньше 2.6 В), что определяется по формированию признака заема при вычитании, то вычисляется дополнительный код байта разности (см. стр. 22) для перевода отрицательного значения в положительное. Полученный модуль напряжения затем возводится в квадрат с использованием подпрограммы SQR, код которой был приведен в Программе 8.3 (стр. 258). Затем содержимое 2-байтной глобальной переменной SUM: SUM+1 прибавляется к общей сумме, хранящейся в регистрах POWER: POWER+1:POWER+2.
Этот процесс повторяется 256 раз, причем перед каждой последующей итерацией цикла формируется задержка длительностью 470 мкс. В итоге считывание сигнала с вывода RA0 осуществляется каждые 500 мкс, что соответствует заданной частоте дискретизации (2 кГц). После завершения серии выборок, на что уходит примерно 128 мс, производится чтение модуля компаратора для сброса признака изменения. Это делается в конце цикла, а не в начале, потому что если входное напряжение перейдет через порог срабатывания компаратора (3.3475 В), то будет зафиксировано новое изменение! Затем флаг CMIF сбрасывается, и восстанавливается контекст программы.
Разумеется, наша программа очень примитивна. Например, базовый уровень может изменяться с течением времени, что влечет за собой необходимость его определения перед запуском преобразования. И, наоборот, при высокой стабильности этого значения его можно запомнить в энергонезависимой памяти, как будет описано в следующей главе. Использование фиксированного числа отсчетов может оказаться ограничивающим фактором. Вместо этого можно выполнять операции считывания до тех пор, пока полученное значение не окажется меньше некоторого порога.
Пример 14.4
Используя язык Си, покажите, как можно в микроконтроллере PIC16F874 считать 10-битный результат оцифровки 3-го аналогового канала при нахождении микроконтроллера в «спящем» режиме.
Решение
В компиляторе CCS имеется функция sleep () для перевода микроконтроллера в «спящий» режим; эта функция просто транслируется в команду sleep. Для преобразования во время «спящего» режима нельзя применять функцию read_adc (), которую мы использовали в Программе 14.3, поскольку в «спящем» режиме процессор остановлен. Вместо этого нам потребуется перед входом в «спящий» режим вручную изменить состояния определенных битов, относящихся к прерываниям, наподобие того, как это было сделано в ассемблерной Программе 14.2. При «пробуждении» можно по отдельности прочитать содержимое регистров ADRESH: L и объединить эти значения для формирования 10-битного результата.
Код для решения этой задачи приведен в Программе 14.7. Биты PEIE, ADIF и определены с помощью директивы #bit. На этот раз функция setup_adc () вызывается с параметром ADC_CLOCK_INTERNAL, соответствующим работе модуля АЦП от собственного RC-генератора, что необходимо для осуществления преобразования в «спящем» режиме.
Программа 14.7. Преобразование в «спящем» режиме на Си
#include <16f874.h>
#device ADC=10 /* Используем 10-битное преобразование */
#use delay(clock=8000000) /* Частота резонатора — 8 МГц */
#bit ADIF = 0х0C.6 /* Флаг прерывания от модуля АЦП в РIR1[6] */
#bit PEIE = 0x0B.6 /* Бит разрешения прерываний от ЛУ */
INTCON[6]
#bit GO = x1F.2 /* Бит GO/NOT_DONE — ADCON0[2] */
void main(void)
{
unsigned long int result; /* 16-битная переменная для хранения результата */
sec_tris_a (0х0Е);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(RA0_RA1_RA3_ANALOG);
set_adc_channel(3);
delay_us(17); /* Ждем для установления напряжений */
disable_interrupts(GLOBAL); /* Запрещаем все прерывания (GIE и PEIE=1) */
ADIF = 0;
enable_interrupts (INT_AD);
PEIE =1; /* Разрешаем прерывания от ПУ */
/* Основной код */
GO = 1;
sleep();
result = ((long)ADRESH << 8) + ADRESL; /* После «пробуждений» считываем оба байта */
}
Встроенная функция disable_interrupts (GLOBAL) сбрасывает оба бита — GIE и PEIE. Обратная по смыслу функция enable_interrupts (GLOBAL) устанавливает оба бита, однако нам необходимо установить только PEIE, a GIE оставить сброшенным. Поэтому мы «напрямую» устанавливаем бит PEIE = 1. Аналогично, для сброса флага ADIF используется выражение ADIF = 0. Перед вызовом функции sleep () мы запускаем преобразование, вручную устанавливая бит . После возврата из функции sleep () сначала считывается регистр ADRESH и преобразуется к типу long int, чтобы компилятор интерпретировал его как 16-битный объект. Затем это значение умножается на 256, поскольку оно является старшим байтом 16-битного объекта. В результате сложения с полученным 16-битным числом регистра ADRESL его содержимое помещается в младший байт результата.
Вопросы для самопроверки
14.1. В Примере 14.2 пороговое значение уменьшалось по линейному закону. Несмотря на то что такой подход достаточно эффективен при априори известном периоде сигнала, который к тому же изменяется в незначительных пределах, в остальных случаях лучшие результаты можно получить, используя экспоненциальное изменение порога. Для получения такой характеристики из результата выборки необходимо вычитать не константу, а некоторую фиксированную долю полученного значения. Покажите, как можно модифицировать Программы 14.4 и 14.5, чтобы при каждой выборке пороговое значение уменьшалось примерно на 0.025 % (-1/4096), и определите постоянную времени в пересчете на количество отсчетов.
14.2. В реальных аналоговых сигналах обязательно присутствуют шумы. На практике это часто приводит к необходимости фильтрации или сглаживания. В любом случае шумы, наводимые извне, не должны иметь составляющих значительной амплитуды, с частотой, которая больше половины частоты дискретизации, поскольку при восстановлении эти составляющие окажутся сдвинутыми в полосу пропускания, как показано на Рис. 14.4. Сигнал необходимо пропускать через фильтр нижних частот перед аналого-цифровым преобразованием, как показано на Рис. 14.20.
Хотя такой внешний фильтр, устраняющий эффект наложения спектров, должен быть, по определению, реализован аппаратно (например, на RС-цепочке), помехи, попадающие в полосу пропускания системы, можно сгладить, используя программную фильтрацию. Один из простейших вариантов цифровой фильтрации заключается в считывании нескольких выборок с последующей выдачей усредненного результата. Например, при суммировании 16 отсчетов и последующем четырехкратном сдвиге результата вправо (16) случайный шум уменьшится в √16 = 4 раза.
Другим методом, хорошо известным тем, кто занимается статистикой, является метод скользящего среднего, который часто используется, например, для вычисления среднего курса акций в течение месяца. Достаточно эффективный алгоритм такого рода получается при усреднении по трем точкам:
где Sn — n-й отсчет, полученный аналоговым модулем.
Покажите, как можно модифицировать подпрограмму GET_ANALOG, чтобы она запоминала значение двух последних отсчетов и возвращала усредненное значение.
14.3. Предположим, что ЦАП МАХ506 используется для реализации автоматической регулировки усиления (АРУ) сигнала, подаваемого на аналоговый вход микроконтроллера в ЭКГ-мониторе из Примера 14.2. Задача АРУ заключается в том, чтобы максимальное значение сигнала на аналоговом входе лежало в диапазоне 3/4…7/8 полной шкалы. Как бы вы реализовали такую подсистему? Подсказка: вспомните, что выходной сигнал каждого канала ЦАП МАХ506 определяется собственным аналоговым входом и общим опорным напряжением Vref, которое может лежать в диапазоне 0…VDD.
14.4. Входной синусоидальный сигнал необходимо подвергнуть двухполупериодному выпрямлению, т. е. отрицательные полуволны должны поменять свой знак. Напишите подпрограмму, выполняющую данное действие, полагая, что 8-битное оцифрованное значение находится в регистре ADRESH, а выходное значение должно быть передано через порт В на внешний ЦАП.
14.5. В основе схемы, изображенной на Рис. 14.21, лежит Fig. 10 из документа AN546 «Using the Analog-to-Digital (A/D) Converter». Такая схема используется для формирования внешнего опорного напряжения для экономичных устройств. Можете ли вы объяснить, как она работает, и из каких соображений выбирается номинал токоограничивающего резистора?
Рис. 14.21. Управляемый источник опорного напряжения
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК