Adc описание. Аналого-цифровой преобразователь микроконтроллеров AVR

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

Начнем-с…Вот некоторые характеристики аналого-цифрового преобразователя в STM32f10x:

  • АЦП является 12-ти битным
  • Возможна генерация прерывания по окончанию преобразования, по окончанию преобразования с инжектированного канала, а также возможно прерывание от Analog Watchdog (что это такое расскажу чуть ниже)
  • Возможно одиночное преобразование и преобразование в непрерывном режиме
  • Самокалибровка
  • Запуск преобразования от внешнего события
  • Работа с ПДП (DMA, прямой доступ к памяти)

Вот структурная схема из даташита, полюбуйтесь)

Пока не забыл про Analog Watchdog, опишу его работу.
Он нужен для того, чтобы следить, что напряжение попадает в определенные пределы. Причем он может сканировать как конкретный канал, так и группу каналов. В регистры ADC_HTR и ADC_LTR заносим значения верхнего и нижнего порога соответственно. И в случае, если проверяемое напряжение выходит за эти пределы, генерируется прерывание. Полезнейшая вещица!

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

Как и в микроконтроллерах AVR возможно выравнивание результата по правому или по левому краю. Тут правда результат 12-ти битный. Но суть та же. Вот как все это выглядит в регистрах:

Видим, как меняются данные в регистре данных. Программа работает правильно, так что можем переходить к дальнейшему изучению STM32. Продолжение следует…

В статье приведено описание аналого-цифрового преобразователя 32-разрядных ARM-микроконтроллеров серии STM32 от компании STMicroelectronics. Рассмотрена архитектура и состав его регистров,
а также приведены практические примеры программ.

Введение
Одним из наиболее важных и востребованных блоков для микроконтроллера является его цифровой преобразователь (АЦП), именуемый в технической англоязычной литературе как Analog-to-Digital
Converter (ADC).

Он позволяет преобразовывать аналоговые сигналы в цифровые значения, которые в дальнейшем могут обрабатываться процессором. Суть преобразования сводится к сравнению аналогового сигнала с опорным напряжением и формирование числового значения, соответствующего аналоговому сигналу в диапазоне разрядности АЦП. Например, 12-разрядный АЦП с опорным напряжением 3,3 В преобразует аналоговые сигналы от 0 до 3,3 В в диапазон цифровых значений от 0 до 4095 единиц с определённой периодичностью во времени.

С помощью АЦП микроконтроллер способен решать гораздо больше задач для автоматизации процессов. Кроме того, при наличии встроенного в микроконтроллер АЦП существенно упрощается схема разрабатываемого устройства и значительно уменьшается его стоимость. Как правило, кроме самого АЦП микроконтроллер имеет встроенный аналоговый мультиплексор, позволяющий увеличить количество аналоговых входов путём поочерёдной коммутации нескольких выводов микроконтроллера и последующего преобразования сигналов от этих выводов.

Микроконтроллеры серии STM32 также имеют встроенный 12-разрядный АЦП последовательного приближения с тактовой частотой до 14 МГц. Некоторые модели STM32 имеют даже два или три блока АЦП.

Структурная схема АЦП микроконтроллеров STM32

Архитектура и функционирование АЦП
Рассмотрим подробнее архитектуру и функционирование блока АЦП для STM32. Аналого-цифровое преобразование сигналов данным АЦП может осуществляться в одиночном режиме, непрерывном режиме, режиме сканирования или прерывистом режиме. Результат преобразования сохраняется в 16-разрядных регистрах АЦП с выравниванием данных по левому или по правому краю.
Встроенный АЦП микроконтроллеров серии STM32 обладает расширенными функциями. Основные характеристики этого АЦП:

  • разрядность – 12 бит;
  • минимальное время преобразования – 1 мкс;
  • количество каналов – 16 внешних и 2 внутренних;
  • количество значений времени преобразования для каждого канала – 8;
  • возможность задания одиночного или непрерывного преобразования;
  • автоматическая калибровка;
  • наличие оконного компаратора;
  • возможность запуска преобразования от внешних источников;
  • работа с блоком прямого доступа к памяти (ПДП).

АЦП питается от источника с напряжением от 2,4 В до 3,6 В. Источник опорного напряжения (ИОН) АЦП соединён либо внутренне с напряжением питания АЦП, либо со специальными внешними выводами в зависимости от модели и количества выводов кристалла. Структурная схема АЦП микроконт­роллеров серии STM32 приведена на рисунке. Как видно из рисунка, АЦП имеет 16 внешних аналоговых каналов
и 2 внутренних, которые коммутируются с помощью мультиплексора входов. Внешние каналы подключены к выводам микроконтроллера. Перед использованием этих выводов в качестве аналоговых необходимо сконфигурировать их как аналоговые входы. Дополнительные два канала задействованы под внутренние сигналы. Один – для контроля внутреннего опорного напряжения, а второй – для датчика
температуры, который расположен на кристалле.
Для данного АЦП введены такие специальные термины, как регулярные и инжектированные каналы. Суть этих понятий заключается в способе опроса каналов. Регулярные каналы опрашиваются и преобразуются с определённой периодичностью, то есть регулярностью. Инжектированные, то есть внедрённые каналы, опрашиваются по специальному запросу от программы между регулярными опросами.
Если необходимо опрашивать периодически несколько каналов, то для АЦП можно сформировать список этих каналов и записать его в специальные регистры. После этого АЦП будет поочерёдно­ преобразовывать сигналы из каналов данного списка последовательно друг за другом. Например, для поочерёдного измерения напряжения в каналах 3, 7, 5 и 1 необходимо записать эту последовательность в специальные регистры и запустить процесс преобразования АЦП. В результате данные каналы будут последовательно опрашиваться и преобразовываться,
а результат этих преобразований записываться в регистры данных. При этом порядок следования каналов не имеет значения. Более того, один и тот же канал может опрашиваться несколько раз за цикл. Количество измерений в группе регулярных каналов может достигать 16. Допускается непрерывное измерение выбранных каналов, то есть по окончании измерения автоматически запускается новый цикл.

Максимальное количество измерений в группе инжектированных каналов равно четырём. Если запустить измерение инжектированных каналов, то измерение регулярных каналов будет приостановлено. Затем будет выполнено измерение заданных инжектированных каналов и вновь восстановлено измерение каналов регулярной группы.
Рассмотрим пример того, как можно применить на практике использование регулярных и инжектированных каналов. Допустим, необходимо постоянно измерять напряжение на пяти выводах в определённой последовательности. Для этого необходимо включить эти каналы в регулярную группу и запустить преобразование. АЦП начнёт последовательно опрашивать их и преобразовывать сигналы в цифровые значения. При необходимости по окончании преобразования будут формироваться прерывания. Таким образом, можно обрабатывать аналоговые сигналы и сохранять данные преобразования АЦП в автоматическом режиме. Если в это время возникает необходимость измерить температуру кристалла или аналоговый сигнал на каком либо другом канале, то для того, чтобы не нарушать измерение в регулярном канале, можно запустить измерение инжектированного канала. При этом обработка регулярных каналов будет автоматически приостановлена на некоторое время, а после окончания
измерения инжектированной группы – автоматически восстановлена.
Сохранение результата преобразования для четырёх инжектированных каналов производится в соответствующих регистрах данных. АЦП имеет для каждого инжектированного канала отдельный регистр, то есть всего четыре регистра данных. Однако для 18 регулярных каналов в АЦП имеется всего один регистр данных. С целью сохранения результатов преобразования для каждого канала можно по окончании измерения в каждом канале формировать прерывание и переписывать данные из этого регистра в блок памяти процессора. Кроме того, можно воспользоваться специальным каналом ПДП, который позволит пересылать результаты каждого преобразования в заранее организованный в памяти буфер данных без участия процессора. Использование данного метода позволяет сократить частоту формирования прерываний до одного по завершении каждого цикла преобразования группы регулярных каналов. Кроме того, можно задействовать двойной буфер. Это позволит после заполнения АЦП первого буфера
сформировать прерывание и приступить к обработке результатов процессором. В это время АЦП начнёт заполнять с помощью­ ПДП второй буфер. Затем очерёдность поменяется и т.д. В нижней части схемы, изображённой на рисунке, приведены источники, которые могут запускать процесс преобразования отдельно для регулярной и инжектированной группы каналов. Это могут быть сигналы от таймеров, внешний сигнал или два специальных разряда управляющих регистров, установив которые, можно программ но запустить преобразование в регулярной или инжектированной группе.
Отличительной особенностью данного АЦП является наличие в нём аналогового сторожевого таймера (AWD, от англ. Analog Watch Dog), представляющего собой оконный компаратор. Он имеет в своём составе два регистра для задания границ сравнения. В регистр нижней границы и регистр верхней границы программно записываются соответствующие значения для контроля уровня измеряемого сигнала. Номер канала, к которому нужно подключить компаратор, записывается в специальный регистр. Если измеряемое напряжение заданного канала выйдет за указанные границы, то в АЦП будет установлен соответствующий флаг и сформируется запрос на прерывание.
Данный оконный компаратор может оказаться очень полезным для автоматического контроля определённого параметра. С его помощью можно, например, следить за температурой контроллера, во избежание его перегрева. Для этого можно регулярно, скажем ежесекундно, измерять уровень сигнала от датчика температуры. Если он превысит заданный порог, будет необходимо предпринять определённые действия. Например, снизить тактовую частоту, сформировать предупреждающий сигнал и тому подобное. Оконный компаратор позволяет выполнять подобную процедуру без отвлечения процессора от выполнения основной программы, экономя при этом ресурсы процессора и памяти программ. Для запуска оконного компаратора необходимо выполнить его инициализацию путём записи уровней границ, включить контролируемый канал в список регулярных каналов и разрешить прерывание от него. Если уровень контролируемого сигнала выйдет за границы заданного диапазона, компаратор сработает и будет вызвана функция обработчика прерывания данного события.
АЦП способен формировать три сигнала прерывания: конец преобразования, конец преобразования инжектированной группы и сигнал от оконного компаратора.

О писание регистров АЦП
Блок АЦП включает в свой состав довольно большое количество регистров. Но это логично, учитывая его насыщенную функциональность и количество каналов для преобразования. Карта регистров АЦП представлена в таблице 1.
Все регистры можно сгруппировать по функциональному назначению. В результате такой организации образуются следующие группы:

●● регистр состояния ADC_SR – содержит биты, указывающие на состояние АЦП;
●● регистры управления ADC_CR1 и ADC_CR2 – определяют режим работы АЦП;
●● регистры ADC_SMPR1 и ADC_SMPR2 – задают время преобразования АЦП;
●● регистры ADC_JOFR1…ADC_JOFR4 – определяют смещение данных в инжектированной группе каналов;
●● регистры ADC_HTR и ADC_LTR – задают верхнюю и нижнюю границы для оконного компаратора;
●● регистры ADC_SQR1…ADC_SQR3 – задают последовательность каналов регулярной группы;
●● регистр ADC_JSQR – задаёт последовательность каналов инжектированной группы;
●● регистры данных ADC_JDR1…ADC_JDR4 – содержат результат преобразования для регистров инжектированной группы каналов;
●● регистр данных DR – содержит результат преобразования для регулярной группы каналов.

Рассмотрим назначение разрядов в каждой из представленных групп регистров АЦП подробнее. Регистр ADC_SR содержит биты, которые устанавливаются аппаратно. Обнуляются они программно или при сбросе. Бит EOC сбрасывается автоматически после чтения регистра ADC_DR. Назначение бит следующее:
●● бит 4 STRT устанавливается при старте преобразования регулярного канала;
●● бит 3 JSTRT устанавливается при старте преобразования инжектированного канала;
●● бит 2 JEOC указывает на окончание преобразования инжектированного канала;
●● бит 1 EOC обозначает окончание преобразования регулярного или инжектированного канала;
●● бит 0 AWD устанавливается при срабатывании оконного компаратора.

Регистр ADC_CR1 содержит следующие биты управления:
●● бит 23 AWDEN управляет оконным компаратором регулярного канала;
●● бит 22 JAWDEN управляет оконным компаратором инжектированного канала;
●● биты 15…13 DISCNUM определяют количество регулярных каналов, преобразование которых будет выполняться в прерывистом режиме, по приходу события внешнего запуска;
●● бит 12 JDISCEN запрещает и разрешает прерывистый режим для инжектированных каналов;
●● бит 11 DISCEN запрещает и разрешает прерывистый режим для регулярных каналов;
●● бит 10 JAUTO запрещает и разрешает режим автоматического преобразования для инжектированных каналов;
●● бит 9 AWDSGL разрешает работу оконного компаратора для всех каналов или для того канала, который определён битами AWDCH;
●● бит 8 SCAN запрещает и разрешает режим сканирования каналов, заданных регистрами ADC_SQRx или ADC_JSQRx;
●● бит 7 JEOCIE запрещает и разрешает прерывания по окончании преобразования инжекционных каналов;
●● бит 6 AWDIE запрещает и разрешает прерывания от оконного компаратора АЦП;
●● бит 5 EOCIE запрещает и разрешает прерывания по окончании преобразования в регулярной или инжектированной группе;
●● биты 4…0 AWDCH определяют номер канала, к которому подключён оконный компаратор.
Регистр ADC_CR2 содержит биты, имеющие следующее назначение:
●● бит 23 TSVREFE подключает канал опорного напряжения и датчика температуры, расположенного на кристалле;
●● бит 22 SWSTART запускает преобразование регулярных каналов;
●● бит 21 JSWSTART запускает преобразование инжектированных каналов;
●● бит 20 EXTTRIG запрещает и разрешает использование внешнего запуска для регулярных каналов;
●● биты 19…17 EXTSEL определяют источник, который будет запускать преобразование в регулярном канале (000 = TIM1_CH1, 001 = TIM1_CH2, 010 = TIM1_CH3, 011 = TIM2_CH2, 100 = TIM3_TRGO, 101 =T IM4_CH4, 110 = EXTI_11, 111 = SWSTART);
●● бит 15 JEXTTRIG запрещает и разрешает использование внешнего запуска для инжектированных каналов;
●● биты 14…12 JEXTSEL определяют источник, который будет запускать преобразование в инжектированном канале (000 = TIM1_TRGO, 001 = TIM1_CH4, 010 = TIM2_TRGO, 011 = TIM2_CH1, 100 = TIM3_СH4, 101 = TIM4_TRGO, 110 = EXTI_15, 111 = JSWSTART);
●● бит 11 ALIGN задаёт выравнивание результата преобразования в регистре данных по правому (0) или левому (1) краям;
●● бит 8 DMA запрещает и разрешает использование блока ПДП (DMA);
●● бит 3 RSTCAL сбрасывает калибровку;
●● бит 2 CAL запускает калибровку АЦП путём записи 1, которая по окончании процесса сбрасывается аппаратно;
●● бит 1 CONT запускает непрерывное преобразование;
●● бит 0 ADON отключает и включает модуль АЦП.

Регистры ADC_SMPR1 и ADC_SMPR2 задают время преобразования в каждом канале. Для каждого канала выделены по три разряда, что позволяет задать 8 значений времени преобразования
в циклах (000 = 1,5 цикла, 001 = 7,5 цикла, 010 = 13,5 цикла, 011 = 28,5 цикла, 100 = 41,5 цикла, 101 = 55,5 цикла, 110 = 71,5 цикла, 111 = 239,5 цикла).
Регистры ADC_JOFR1…ADC_JOFR4 служат для задания смещения каждого канала инжектированной группы (JOFR1, JOFR2, JOFR3, JOFR4). В эти регистры можно записывать 12-битное значение, которое автоматически вычитается из результата преобразования АЦП. Если результирующее значение станет отрицательным, то регистр результата инжектированной группы дополнится битом знака отрицательного значения.

Регистры ADC_LTR и ADC_HTR имеют по 12 разрядов, в которые записываются значения верхней и нижней границ оконного компаратора.
Регистры ADC_SQR1… ADC_SQR3 служат для задания номеров каналов, которые будут опрашиваться в регулярной группе, и общее количество каналов. Разряды SQx этих регистров задают номер канала, где х – это номер позиции для преобразования от 1 до 16. Количество каналов в группе задаётся разрядами L регистра ADC_SQR1.

Например, необходимо регулярно опрашивать 7 каналов в очерёдности 1, 3, 1, 5, 9, 9, 1. Для этого нужно записать
в регистр ADC_SQR3 следующие значения: SQ1 = 1, SQ2 = 3, SQ3 = 1, SQ4 = 5, SQ5 = 9, SQ6 = 9. В регистр ADC_SQR2 требуется записать номер последнего седьмого опрашиваемого канала: SQ7 = 1. После этого следует задать количество опрашиваемых каналов регулярной группы для регистра ADC_SQR1: L = 7. Из приведённой информации видно, что каналы можно опрашивать в любой последовательности. Кроме того, любой канал можно опрашивать несколько раз.
Регистр ADC_JSQR, подобно регистрам ADC_SQRx, задаёт последовательность опрашиваемых каналов и их количество для инжектированной группы каналов. Как видно из структуры регистра, максимальное количество преобразований в инжектированной группе равно четырём. Количество каналов задаётся в разрядах JL.

Регистры ADC_JDR1…ADC_JDR4 хранят данные каналов инжектированной группы. Максимальное количество каналов в инжектированной группе равно четырём, соответственно имеется четыре регистра данных. В эти регистры помещается результат преобразований в каждом выбранном канале. Поскольку регистры 16-разрядные, а АЦП 12-разрядный, предусмотрена возможность выравнивания результата измерения по левому или по правому краю этих регистров.

Регистр ADC_DR содержит результат преобразования АЦП в регулярной группе. В отличие от инжектированной группы, в которой четыре регистра данных, он – один на всю группу. Его структура подобна регистрам JDRx, за исключением старших разрядов 16…31. Эти разряды используются при работе АЦП в сдвоенном режиме, совместно со вторым АЦП, именуемым ADC2.

Режимы работы АЦП
АЦП позволяет использовать нес­колько режимов работы. Рассмотрим их поочерёдно, начиная с режима одиночного преобразования. В этом режиме АЦП выполняет всего одно преобразование. Оно запускается после установки разряда ADON в регистре ADC_CR2 для регулярных каналов, или от внешнего сигнала для регулярного и инжектированного каналов. При этом разряд CONT регистра ADC_CR2 должен быть равен нулю. После окончания преобразования в выбранном регулярном канале результат преобразования сохраняется в регистре ADC_DR и устанавливается флаг EOC. Если установлен разряд EOCIE, генерируется прерывание. Для инжектированного канала результат преобразования сохраняется в регистре ADC_DRJ1 и устанавливается флаг JEOC. Если установлен разряд JEOCIE, генерируется прерывание. После этого работа АЦП останавливается.
В режиме непрерывного преобразования АЦП начинает очередное преобразование после завершения текущего. Этот режим запускается от внешнего источника или путём установки разряда ADON регистра ADC_CR2. При этом разряд CONT регистра ADC_CR2 должен быть равен единице. После каждого преобразования выполняется результат преобразования и сохраняется аналогично режиму одиночного преобразования.
В режиме сканирования АЦП выполняет поочерёдное преобразование группы каналов. Этот режим выбирается установкой разряда SCAN регистра ADC_CR1. Если этот разряд установлен, АЦП сканирует все каналы, выбранные в регистрах ADC_SQRx для регулярных каналов или в регистре ADC_JSQR для инжектированных каналов. Если разряд CONT установлен, то преобразование не останавливается на последнем канале, а вновь запускается с первого канала. Если установлен разряд DMA, контроллер прямого доступа к памяти используется для передачи результата в память по окончании каждого преобразования после установки разряда EOC. Если в регулярной группе используется более одного канала, то для сохранения результата рекомендуется использовать DMA. Это позволяет избежать потерь данных, которые уже хранятся в регистре ADC_DR. В конце преобразования регулярная группа формирует запрос DMA для сохранения результата из регистра ADC_DR в место, заданное пользователем. Режимы работы АЦП с инжектированными каналами также разно­ образны. Чтобы использовать запуск инжекционного канала, надо чтобы бит JAUTO был обнулён, а бит SCAN в регистре ADC_CR1 – установлен. Запуск преобразования сигналов для группы регулярных каналов производится либо внешним сигналом, либо установкой бита ADON в регистре ADC_CR2. Если внешний запуск инжектированных каналов происходит во время преобразования сигналов группы регулярных каналов, то текущее преобразование приостанавливается и запускается преобразование последовательности инжекционных каналов в режиме однократного сканирования.

Затем возобновляется преобразование группы регулярных каналов, начиная с того канала, который был прер­ван. Если во время инжекционного преобразования происходит событие запуска регулярных каналов, то оно не прерывает это преобразование, но запуск регулярной последовательности выполняется сразу после окончания обработки инжекционной последовательности. При использовании запуска инжектированных каналов внешним событием необходимо убедиться, что интервал между событиями запуска дольше, чем время преобразования инжекционных каналов. Например, если длительность последовательности преобразований составляет 28 циклов тактового АЦП, то минимальный интервал между событиями запуска должен быть 29 циклов.

Если установлен бит JAUTO, то после завершения преобразования группы регулярных каналов автоматически запускается преобразование группы инжекционных каналов. Это можно использовать, чтобы преобразовать последовательность из 17–20 каналов, заданных в регистрах ADC_JSQR и ADC_SQRx. В этом режиме механизм запуска внешним событием должен быть отключён. Если в дополнение к биту JAUTO установлен бит CONT, то сразу после преобразования группы инжекционных каналов вновь запускается преобразование группы регулярных каналов. Использовать одно-временно оба режима, автоматический запуск и запуск внешним событием, невозможно.

Калибровка АЦП
АЦП имеет встроенный механизм автоматической калибровки. Калибровка значительно уменьшает погрешность оцифровки, которая вызывается неоднородностью внутренних конденсаторов выборки и хранения сигналов. Во время калибровки вычисляется цифровое значение АЦП для каждого конденсатора в виде корректирующего кода. Во время всех последующих преобразований этот код используется для компенсации ошибки преобразования сигналов.
Перед началом калибровки АЦП должен находиться в отключённом состоянии, то есть бит ADON должен быть равен нулю, по крайней мере в течение двух циклов тактового АЦП.
Запуск калибровки производится установкой бита CAL в регистре ADC_CR2. Как только калибровка закончена, бит CAL сбрасывается аппаратно, после чего может быть выполнено нормальное преобразование. Рекомендуется калибровать АЦП один раз при подаче питания. Коды калибровки сохраняются в ADC_ DR при завершении фазы калибровки.

Время преобразования АЦП
АЦП поддерживает возможность раздельного программирования времени преобразования в каждом из каналов. Предусмотрена возможность выбора 8 дискретных значений из диапазона 1,5…239,5 циклов. Для каждого канала время задаётся индивидуально с помощью разрядов SMPx регистров ADC_SMPR1 и ADC_SMPR2.
Полное время преобразования Tconv вычисляется по формуле: Tconv = Tsmt + 12,5 циклов, где Tsmt – это программно заданное время выборки. Например, частота ADCCLK задана равной 14 МГц,
а время выборки – 1,5 цикла. Тогда Tconv = =1,5 + 12,5 = 14 циклов = 1мкс.

Датчик температуры АЦП
Встроенный в кристалл микроконтроллера датчик температуры позволяет измерять температуру самого кристалла. Датчик подключён к 16-му входу АЦП. Рекомендуемое время выборки
при опросе датчика составляет 17,1 мкс.
Когда датчик не используется, его можно отключить. Напряжение на выходе датчика изменяется линейно с температурой. В разных кристаллах эта линия смещается до 45 градусов, что связано
с технологией изготовления. Внутренний датчик больше подходит не для измерения абсолютного значения температуры, а для контроля её изменения. Для чтения температуры необходимо
выбрать канал 16, задать время выборки не менее 17,1 мкс и установить раз-ряд TSVREFE в регистре ADC_CR2 для включения датчика. После этого можно запустить преобразование АЦП установкой разряда ADON или внешним событием и прочитать результат преобразования.
Вычисляется значение температуры по формуле: Т[C] = (V25 – Vsense) / Avg_ Slope + 25, где V25 – значение измерения при 25 градусах, имеющее типовое значение 1,41В, Vsense – текущее измеренное значение, а Avg_Slope – коэффициент из таблицы на кристалл, имеющий типовое значение 4,3 мВ/C.

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

Флаг AWD устанавливается, если цифровое значение канального сигнала, измеренного с помощью АЦП, больше или меньше заданного уровня. Этот уровень задаётся регистрами ADC_HTR и ADC_LTR. Прерывание может быть разрешено разрядом AWDIE регистра ADC_CR1. Каналы АЦП, контролируемые оконным компаратором, задаются согласно таблице 2.
Разряд AWDSGL задаёт количество контролируемых каналов. Если он равен 0, то контролируются все каналы, а если 1 – то один канал. Номер канала при этом задаётся с помощью раз-рядов AWDCH.
Разряд AWDEN разрешает конт­роль каналов регулярной группы, а JAWDEN – контроль каналов инжектированной группы.

Таблица 2. Каналы АЦП контролируемые оконным компаратором

Примеры программ

Рассмотрим примеры программ для работы с АЦП. Начнём с простейшего варианта: измерение уровня сигнала на одном канале с программным запуском. Для этого используем вывод порта PORTA.6 микроконтроллера. Пример программы приведён в листинге 1.

Листинг 1 //========================= // Функция инициализации АЦП //========================= void Init_ADC(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Разрешить тактирование порта PORTA // Сконфигурировать PORTA.6 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE6; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF6; // Очистить биты CNF RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Включить тактирование АЦП RCC->CFGR &= ~RCC_CFGR_ADCPRE; // Задать значение делителя тактовой частоты ADC1->CR1 = 0; // Обнулить регистр управления ADC1->SQR1 = 0; // Обнулить регистр SQR1 ADC1->CR2 |= ADC_CR2_CAL; // Пуск калибровки while (!(ADC1->CR2 & ADC_CR2_CAL)){}; // Ждать окончания калибровки ADC1->CR2 = ADC_CR2_EXTSEL; // Выбрать источником запуска разряд SWSTART ADC1->CR2 |= ADC_CR2_EXTTRIG; // Разрешить внешний запуск регулярного канала ADC1->CR2 |= ADC_CR2_ADON; // Включить АЦП } //====================================================== // Функция запуска преобразования АЦП и чтение выбранного канала // Вход - номер канала для преобразования // Выход - результат преобразования //====================================================== uint16_t RD_ADC(uint8_t nk) { ADC1->SQR3 = nk; // Задать номер канала ADC1->CR2 |= ADC_CR2_SWSTART; // Пуск преобразования while(!(ADC1->SR & ADC_SR_EOC)){}; // Ждать окончания преобразования return ADC1->DR; // Считать результат преобразования } //========================= // Главный модуль программы //========================= void main(void) { unsigned int ai; // Инициализация переменных // Другие команды … while(1) // Бесконечный цикл { Init_ADC(); // Выполнить инициализацию и пуск АЦП ai = RD_ADC(6); // Считать данные АЦП для канала 6 // Другие команды … } }

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

Листинг 2 //========================= // Функция инициализации АЦП //========================= void Init_ADC(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Разрешить тактирование порта PORTA // Сконфигурировать PORTA.6 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE6; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF6; // Очистить биты CNF RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Включить тактирование АЦП RCC->CFGR &= ~RCC_CFGR_ADCPRE; // Задать значение делителя тактовой частоты ADC1->CR1 = 0; // Обнулить регистр управления ADC1->SQR1 = 0; // Обнулить регистр SQR1 ADC1->CR2 |= ADC_CR2_CAL; // Пуск калибровки while (!(ADC1->CR2 & ADC_CR2_CAL)){}; // Ждать окончания калибровки ADC1->CR2 = ADC_CR2_EXTSEL; // Выбрать источником запуска разряд SWSTART ADC1->CR2 |= ADC_CR2_EXTTRIG; // Разрешить внешний запуск регулярного канала ADC1->CR2 |= ADC_CR2_CONT; // Включить режим непрерывного преобразования ADC1->CR2 |= ADC_CR2_ADON; // Включить АЦП ADC1->CR2 |= ADC_CR2_SWSTART; // // Пуск преобразования } //========================= // Главный модуль программы //========================= void main(void) { unsigned int ai; // Инициализация переменных Init_ADC(); // Выполнить инициализацию и пуск АЦП // Другие команды … while(1) // Бесконечный цикл { ai=ADC1->DR; // Считать результат преобразования // Другие команды … } }

Данная программа запускает режим непрерывного преобразования заданного канала, и АЦП постоянно опрашивает выбранный канал, помещая результат в регистр данных. Поэтому
в основной программе не требуется регулярно запускать АЦП. При таком способе в регистре ADC_DR информация об уровне сигнала на входе канала будет постоянно обновляться. Обновление будет происходить с периодичностью, которую можно изменять.
В рассмотренных примерах можно запустить непрерывное преобразование для одного канала. Если нужно сделать это для нескольких каналов, то без использования прерываний или блока ПДП не обойтись, так как для регулярной группы предусмотрен всего один регистр данных. Однако если количество каналов не превышает четырёх, то подобным образом можно использовать и преобразование инжектированных каналов.
Максимальное количество каналов для инжектированной группы равно четырём. Для каждого такого канала предусмотрен свой регистр для хранения результата преобразования.
Допустим, необходимо опрашивать четыре канала с номерами: 3, 4, 5 и 6. Для этого можно запустить непрерывное измерение группы из четырёх инжектированных каналов. При этом АЦП будет автоматически сканировать четыре заданных канала, и помещать результат в регистры данных ADC_ JDR1, ADC_JDR2, ADC_JDR3 и ADC_JDR4. При этом можно будет считывать данные из нужного канала в любое время. Пример такой программы приведён в листинге 3.

Листинг 3 //========================= // Функция инициализации АЦП //========================= void Init_ADC(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Разрешить тактирование порта PORTA //Сконфигурировать PORTA.3 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE3; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF3; // Очистить биты CNF //Сконфигурировать PORTA.4 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE4; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF4; // Очистить биты CNF //Сконфигурировать PORTA.5 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE5; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF5; // Очистить биты CNF //Сконфигурировать PORTA.6 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE6; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF6; // Очистить биты CNF RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Включить тактирование АЦП RCC->CFGR &= ~RCC_CFGR_ADCPRE; // Задать значение делителя тактовой частоты ADC1->CR1 = 0; // Обнулить регистр управления ADC1->CR2 |= ADC_CR2_CAL; // Пуск калибровки while (!(ADC1->CR2 & ADC_CR2_CAL)){}; // Ждать окончания калибровки ADC1->CR2 = ADC_CR2_JEXTSEL; // Выбрать источником запуска разряд JSWSTART ADC1->CR2 |= ADC_CR2_JEXTTRIG; // Разрешить внешний запуск инжектированной группы ADC1->CR2 |= ADC_CR2_CONT; // Включить режим непрерывного преобразования ADC1->CR1 |= ADC_CR1_SCAN; // Включить режим сканирования нескольких каналов ADC1->CR1 |= ADC_CR1_JAUTO; // Автоматический запуск инжектированной группы ADC1->JSQR = (uint32_t)(4-1)<<20; // Задать количество каналов в инжектированной группе=4 ADC1->JSQR |= (uint32_t)3<<(5*0); // Номер первого канала для преобразования=3 ADC1->JSQR |= (uint32_t)4<<(5*1); // Номер второго канала для преобразования=4 ADC1->JSQR |= (uint32_t)5<<(5*2); // Номер третьего канала для преобразования=5 ADC1->JSQR |= (uint32_t)6<<(5*3); // Номер четвертого канала для преобразования=6 ADC1->CR2 |= ADC_CR2_ADON; // Включить АЦП ADC1->CR2 |= ADC_CR2_JSWSTART; // Пуск преобразования } //========================= // Главный модуль программы //========================= void main(void) { unsigned int ai; // Инициализация переменных Init_ADC(); // Выполнить инициализацию и пуск АЦП // Другие команды … while(1) // Бесконечный цикл { //Считать результат преобразования ai=ADC1->JDR1; // Канал 3 ai=ADC1->JDR2; // Канал 4 ai=ADC1->JDR3; // Канал 5 ai=ADC1->JDR4; // Канал 6 //Другие команды … } }

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


Описание работы Аналого-цифрового преобразователя.
Прерывания от АЦП

ATMega16 содержит в себе 10-битовый АЦП, вход которого может быть соединён с одним из восьми выводов Port A. АЦП Mega16, как и любому другому АЦП, нужно опорное напряжение для целей сравнения со входным (если измеряемое равно опорному, то получаем максимальный код в двоичном виде). Опорное напряжение подаётся на вывод ADRef или может использоваться внутренний генератор с фиксированным напряжением 2,65 В. Полученный результат можно представить в таком виде:

АЦП включается установкой бита ADEN в регистре ADCSRA. После преобразования, 10-битный результат оказывается в 8-битных регистрах ADCL и ADCH. По умолчанию, младший бит результата находится справа (то есть в bit 0 регистра ADCL, так называемое правое ориентирование). Но порядок следования битов на левое ориентирование можно сменить установив бит ADLAR в регистре ADMUX. Это удобно, если требуется получить 8-битовый результат. В таком случае требуется прочитать только регистр ADCH. В противном случае, Вы должны сначала прочитать регистр ADCL первым, а ADCH вторым, чтобы быть уверенным в том, что чтение этих двух регистров относится к результату одного преобразования.

Одиночное преобразование может быть вызвано записью бита ADSC в регистр ADCSRA. Этот бит остаётся установленным всё время, занимаемое преобразованием. Когда преобразование закончено, бит автоматически устанавливается в 0. Можно также начинать преобразования по событиям из разных источников. Модуль АЦП также может работать в режиме "свободного полёта". В таком случае АЦП постоянно производит преобразование и обновляет регистры ADCH и ADCL новыми значениями.

Для выполнения преобразования модулю АЦП необходима тактовая частота. Чем выше эта частота, тем быстрее будет происходить преобразование (оно, обычно, занимает 13 тактов, первое преобразование занимает 25 тактов). Но чем выше частота (и выше скорость преобразования), тем менее точным получается результат. Для получения максимально точного результата, модуль АЦП должен тактироваться частотой в пределах от 50 до 200 КГц. Если необходим результат с точностью менее 10 бит, то можно использовать частоту больше 200 КГц. Модуль АЦП содержит делитель частоты, чтобы получать нужную тактовую частоту для преобразования из частоты процессора.

Регистр ADMUX задаёт входной контакт порта A для подключения АЦП, ориентирование результата и выбор опорной частоты. Если установлен бит ADLAR, то результат лево-ориентирован. Опорная частота от внутреннего генератора задаётся выставленными в 1 битами REFS1 и REFS0. Если оба бита сброшены, то опорная частота берётся от контакта AREF. В случае, если REFS1=0 а REFS0=1, опорная частота берётся от AVCC с внешним конденсатором, подключенным к AREF. Выбор контакта ввода выполняется следующим образом:

Регистр контроля и статуса АЦП ADCSRA :

Бит ADEN=1 включает модуль АЦП.
Запись единицы в ADSC запускает цикл преобразования. В режиме "свободного полёта" запись единицы запускает первое преобразование, последующие запускаются автоматически.
ADIF - флаг прерывания АЦП. Этот бит устанавливается в 1 когда АЦП завершено преобразование и в регистрах ADCL и ADCH находятся актуальные данные. Этот флаг устанавливается даже в том случае, если прерывания запрещены. Это необходимо для случая программного опроса АЦП. Если используются прерывания, то флаг сбрасывается автоматически. Если используется программный опрос, то флаг может быть сброшен записью лог.1 в этот бит.
ADIE - Если в этом бите установлена единица, и прерывания разрешены глобально, то при окончании преобразования будет выполнен переход по вектору прерывания от АЦП.
Биты ADPS2..0 задают коэффициенты предделителя частоты:


Аналого-цифровые преобразователи (АЦП) являются устройствами, которые принимают входные аналоговые сигналы и генерируют соответствующие им цифровые сигналы, пригодные для обработки микропроцессорами и другими цифровыми устройствами. АЦП входит во многие современные модели МК AVR , он многоканальный. Обычно число каналов равно 8, но в разных моделях оно может варьировать от 4 каналов в младших моделях семейства Tiny, 6 в ATmega8, до 16 каналов в ATmega2560.

Многоканальность означает, что на входе единственного модуля АЦП установлен аналоговый мультиплексор, который может подключать этот вход к различным выводам МК для осуществления измерений нескольких независимых аналоговых величин с разнесением по времени. Входы мультиплексора могут работать по отдельности (в несимметричном режиме для измерения напряжения относительно "земли") или (в некоторых моделях) объединяться в пары для измерения дифференциальных сигналов. Иногда АЦП дополнительно снабжается усилителем напряжения с фиксированными значениями коэффициента усиления 10 и 200.

Сам АЦП представляет собой преобразователь последовательного приближения с устройством выборки-хранения и фиксированным числом тактов преобразования, равным 13 (или 14 для дифференциального входа; первое преобразование после включения потребует 25 тактов для инициализации АЦП ). Тактовая частота формируется аналогично тому, как это делается для таймеров- с помощью специального предделителя тактовой частоты МК, который может иметь коэффициенты деления от 1 до 128. Но в отличие от таймеров, выбор тактовой частоты АЦП не совсем произволен, т. к. быстродействие аналоговых компонентов ограничено. Поэтому коэффициент деления следует выбирать таким, чтобы при заданном "кварце" тактовая частота АЦП укладывалась в рекомендованный диапазон 50-200 кГц (т. е. максимум около 15 тыс. измерений в секунду). Увеличение частоты выборки допустимо, если не требуется достижение наивысшей точности преобразования.

Разрешающая способность АЦП в МК AVR - 10 двоичных разрядов, чего для большинства типовых применений достаточно. Абсолютная погрешность преобразования зависит от ряда факторов и в идеальном случае не превышает ±2 младших разрядов, что соответствует общей точности измерения примерно 8 двоичных разрядов. Для достижения этого результата необходимо принимать специальные меры: не только "вгонять" тактовую частоту в рекомендованный диапазон, но и снижать по максимуму интенсивность цифровых шумов. Для этого рекомендуется, как минимум, не использовать оставшиеся выводы того же порта, к которому подключен АЦП, для обработки цифровых сигналов, правильно разводить платы, а как максимум - дополнительно к тому еще и включать специальный режим ADC Noise Reduction .

Регистры управления АЦП

ADCSR

Режим непрерывных измерений активизируется установкой бита ADFR (бит 5) этого же регистра. В ряде моделей Mega этот бит носит наименование ADATE , и управление режимом работы производится сложнее: там добавляются несколько режимов запуска через различные прерывания (в т. ч. прерывание от компаратора, при наступлении различных событий от таймера и т. п.), и выбирать их следует, задавая биты ADTS регистра SFIOR , а установка бита ADATE разрешает запуск АЦП по этим событиям.

Разряд Название Описание
5 ADFR(ADATE) Выбор режима работы АЦП

Так как нулевые значения всех битов ADTS (по умолчанию) означают режим непрерывного преобразования, то в случае, когда вы их значения не трогали, функции битов ADATE и ADFR в других моделях будут совпадать.

ADTS2 ADTS1 ADTS0 Источник стартового сигнала
0 0 0 Режим непрерывного преобразования
0 0 1 Прерывание от аналогового компаратора
0 1 0 Внешнее прерывание INT0
0 1 1 Прерывание по событию "Совпадение" таймера/счетчика Т0
1 0 0 Прерывание по переполнению таймера/счетчика Т0
1 0 1 Прерывание по событию "Совпадение" таймера/счетчика Т1
1 1 0 Прерывание по переполнению таймера/счетчика Т1
1 1 1 Прерывание по событию "Захват" таймера/счетчика Т1

Если выбран режим запуска не от внешнего источника, то преобразование запускается установкой бита ADSС (бит 6). При непрерывном режиме установка этого бита запустит первое преобразование, затем они будут автоматически повторяться. В режиме однократного преобразования, а также независимо от установленного режима при запуске через прерывания (в тех моделях, где это возможно) установка бита ADSС просто запускает одно преобразование. При наступлении прерывания, запускающего преобразование, бит ADSС устанавливается аппаратно. Отметим, что преобразование начинается по-фронту первого тактового импульса (тактового сигнала АЦП, а не самого контроллера!) после установки ADSС . По окончании любого преобразования (и в одиночном, и в непрерывном режиме) устанавливается бит ADIF (бит 4. флаг прерывания). Разрешение прерывания АЦП осуществляется установкой бита ADIE (бит 3) все того же регистра ADCSR/ADCSRA .

Для работы с АЦП необходимо еще установить его тактовую частоту. Это делается тремя младшими битами регистра ADCSR/ADCSRA под названием ADPS0..2. Коэффициент деления частоты тактового генератора МК устанавливается по степеням двойки, все нули в этих трех битах соответствуют коэффициенту 2, все единицы - 128. Оптимальная частота преобразования лежит в диапазоне 50-200 кГц, так что, например, для тактовой частоты МК, равной 4 МГц, коэффициент может иметь значение только 32 (состояние битов ADPS0..2 = 101, частота 125 кГц) или 64 (состояние битов ADPS0..2 = 110, частота 62,5 кГц). При тактовой частоте 16 МГц в допустимый диапазон укладывается только коэффициент 128.

ADPS2 ADPS1 ADPS0 Коэффициент деления
0 0 0 2
0 0 1 2
0 1 0 4
0 1 1 8
1 0 0 16
1 0 1 32
1 1 0 64
1 1 1 128

Ниже приведена таблица с описанием регистра ADMUX.



Выборка источника опорного напряжения производится битами REFS1..0 регистра ADMUX (старшие биты 7 и 6), причем их нулевое значение (по умолчанию) соответствует внешнему источнику. Напряжение этого внешнего источника может лежать в пределах от 2 В до напряжения питания аналоговой части AVcc (а оно, в свою очередь, не должно отличаться от питания цифровой части более чем на 0,3 В в большую или меньшую сторону). Можно выбрать в качестве опорного и питание самой аналоговой части, причем двояким способом: либо просто соединить выводы AREF и AVcc микросхемы, либо установить биты REFS1..0 в состояние 01 (тогда соединение осуществляется внутренними схемами, но заметим, что внешний опорный источник при этом должен быть отключен). Предусмотрен и встроенный источник (задается REFS1..0 в состоянии 11, при этом к выводу AREF рекомендуется подключать фильтрующий конденсатор), имеющий номинальное напряжение 2,56В с большим разбросом от 2,4 до 2,7 В.

REFS1 REFS0 Источник опорного напряжения
0 0 Внешний ИОН, подключенный к выводу AREF, внутренний ИОН отключен
0 1 Напряжение питания AVcc*
1 0 Зарезервировано
1 1 Внутренний ИОН напряжением 2,56V, подключенный к ввыводу AREF*
*Если к выводу AREF подключен источник напряжения, данные варианты использоваться не могут

Результат преобразования АЦП оказывается в регистрах ADCH:ADCL . Поскольку результат 10-разрядный, то по умолчанию старшие 6 битов в регистре ADCH оказываются равными нулю. Чтение этих регистров производится, начиная с младшего ADCL , после чего регистр ADCH блокируется, пока не будет прочитан. Следовательно, даже если момент между чтением регистров попал на фронт 14 (15) такта АЦП, когда данные в них должны меняться, значения прочитанной пары будут соответствовать друг другу, пусть и результат этого преобразования пропадет. В противоположном порядке читать эти регистры не рекомендуется. Но бит ADLAR (бит 5 регистра ADMUX ) предоставляет интересную возможность: если его установить в 1, то результат преобразования в регистрах ADCH:ADCL выравнивается влево: бит 9 результата окажется в старшем бите ADCH , а незначащими будут младшие 6 битов регистра ADCL . В этом случае, если хватает 8-разрядного разрешения результата, можно прочесть только значение ADCH .

class="eliadunit">

Выбор каналов и режимов их взаимодействия в АЦП производится битами MUX0..3 в регистре ADMUX . Их значения выбирают нужный канал в обычном (недифференциальном) режиме, когда измеряемое напряжение отсчитывается от "земли". Последние два значения этих битов для семейства Mega (11110 и 11111 в большинстве моделей или 1110 и 1111 для ATmega8) выбирают режимы, когда вход АЦП подсоединяется к опорному источнику компаратора (1,22 В) или к "земле" соответственно, что может использоваться для автокалибровки устройства.

Управление входным мультиплексором в моделях Atmega8x

MUX3-MUX0 Несимметричный вход
0000 ADC0
0001 ADC1
0010 ADC2
0011 ADC3
0100 ADC4*
0101 ADC5*
0110 ADC6**
0111 ADC7**
1000-1101 Зарезервировано
1110 1,22V
1111 0V(GND)

*8-ми разрядное преобразование

**Имеются только в корпусах TQFP-32 и MLF-32.

Остальные комбинации разрядов MUX предназначены для установки различных дифференциальных режимов - в тех моделях, где они присутствуют, в других случаях эти биты зарезервированы (как в моделях Atmega8, ATmega163 и др.). В дифференциальном режиме АЦП измеряет напряжение между двумя выбранными выводами (например, между ADC0 и ADC1 ), причем не все выводы могут быть в таком режиме задействованы. В том числе дифференциальные входы АЦП можно подключать к одному и тому же входу для коррекции нуля. Дело в том, что в ряде моделей на входе АЦП имеется встроенный усилитель, с коэффициентом 1х, 10х и 200х (коэффициент выбирается теми же битами MUX0..4 ), и такой режим используется для его калибровки - в дальнейшем значение выхода при соединенных входах можно просто вычесть.

После завершения преобразования (при установке в «1» флага ADIF регистра ADCSR ) его результат сохраняется в регистре данных АЦП . Поскольку АЦП имеет 10 разрядов, этот регистр физически размещен в двух регистрах ввода/вывода ADCH:ADCL , доступных только для чтения. По умолчанию результат преобразования выравнивается вправо (старшие 6 разрядов регистра ADCH - незначащие). Однако он может выравниваться и влево (младшие 6 разрядов регистра ADCL - незначащие). Для управления выравниванием результата преобразования служит разряд ADLAR регистра ADMUX . Если этот разряд установлен в «1», результат преобразования выравнивается по левой границе 16-разрядного слова, если сброшен в «0» - по правой границе.

Обращение к регистрам ADCH и ADCL для получения результата преобразования должно выполняться в определенной последовательности: сначала необходимо прочитать регистр ADCL , а затем ADCH . Это требование связано с тем, что после обращения к регистру ADCL процессор блокирует доступ к регистрам данных со стороны АЦП до тех пор, пока не будет прочитан регистр ADCH. Благодаря этому можно быть уверенным, что при чтении регистров в них будут находиться составляющие одного и того же результата. Соответственно, если очередное преобразование завершится до обращения к регистру ADCH , результат преобразования будет потерян. С другой стороны, если результат преобразования выравнивается влево и достаточно точности 8-разрядного значения, для получения результата можно прочитать только содержимое регистра ADCH .

Для недифференциального режима АЦП, когда напряжение отсчитывается от "земли", результат преобразования определяется формулой:

Ка = 1024Uвх/Uref

Где Ка - значение выходного кода АЦП, Uвх и Uref - входное и опорное напряжения.

Дифференциальному измерению соответствует такая формула:

Ка = 512(Upos - Uneg)/Uref

Где Upos и Uneg - напряжения на положительном и отрицательном входах соответственно. Если напряжение на отрицательном входе больше, чем на положительном, то результат в дифференциальном режиме становится отрицательным и выражается в дополнительном коде от $200 (-512) до $3FF (-1). Реальная точность преобразования в дифференциальном режиме равна 8 разрядам.

Делаем светодиодный индикатор напряжения

Для практического изучения АЦП напишем программу светодиодного индикатора напряжения. Как и в прошлых примерах будем использовать микроконтроллер Atmega8. Восемь индикаторов подключаем к порту D контроллера, это будет линейная шкала уровня сигнала от 0 до 5V. Входом АЦП у нас будет вывод PC0(ADC0), к которому через переменный резистор сопротивлением 10кОм подается напряжение. Схема устройства представлена ниже:

К точности АЦП в этом устройстве предъявляются наименьшие требования. Источником опорного напряжения служит напряжение питания микроконтроллера - 5 Вольт, для этого вывод AREF соединяем с выводом Vcc микроконтроллера, также поступаем с выводами питания аналоговой части AVcc и AGND , подключаем их к плюсу и минусу соответственно, в программе битами REFS1 и REFS0 задаем источник ИОН .

Режим индикации работает следующим образом: после окончания преобразования, которое работает в непрерывном режиме, считываем биты ADCH и ADCL . Это значение потом сравниваем с предварительно расчитанными константами. Если значение ADC больше константы загорается один светодиод, если значение ADC больше второй константы загораются уже два светодиода и т.д.

Константы высчитываются так: так как АЦП 10-ти битный, число 1024 раскладываем на 8 равных частей, а по формуле уже вычисляем эти значения в Вольтах.

1020...5V(приблизительно)

Полный код программы показан ниже. Частота тактового генератора контроллера 8MHz.

/*** Использование АЦП. Светодиодная шкала ***/ #include #include int main (void) { DDRD = 0xFF; PORTD = 0x00; /*** Настройка АЦП ***/ ADCSRA |= (1 << ADEN) // Включение АЦП |(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8 ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН |(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // вход PC0 while(1) { unsigned int u; ADCSRA |= (1 << ADSC); // Начинаем преобразование while ((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования u = (ADCL|ADCH << 8); // Считываем ADC if (u > 128) // 0.625V PORTD = 0b00000001; else PORTD = 0b00000000; if (u > 256) // 1.25V PORTD = 0b00000011; if (u > 384) // 1.875V PORTD = 0b00000111; if (u > 512) // 2.5V PORTD = 0b00001111; if (u > 640) // 3.125V PORTD = 0b00011111; if (u > 768) // 3.75V PORTD = 0b00111111; if (u > 896) // 4.375V PORTD = 0b01111111; if (u > 1020) // 5V PORTD = 0b11111111; _delay_ms(30); } }

В следующем примере мы разберем принципы создания вольтметра 0-30V на микроконтроллере Atmega8.

Аналого-цифровые преобразователи (АЦП) являются устройствами, которые принимают входные аналоговые сигналы и генерируют соответствующие им цифровые сигналы, пригодные для обработки микропроцессорами и другими цифровыми устройствами.

АЦП входит во многие современные модели МК AVR, он многоканальный. Обычно число каналов равно 8, но в разных моделях оно может варьировать от 4 каналов в младших моделях семейства Tiny, 6 в ATmega8, до 16 каналов в ATmega2560. Многоканальность означает, что на входе единственного модуля АЦП установлен аналоговый мультиплексор, который может подключать этот вход к различным выводам МК для осуществления измерений нескольких независимых аналоговых величин с разнесением по времени. Входы мультиплексора могут работать по отдельности (в несимметричном режиме для измерения напряжения относительно "земли") или (в некоторых моделях) объединяться в пары для измерения дифференциальных сигналов. Иногда АЦП дополнительно снабжается усилителем напряжения с фиксированными значениями коэффициента усиления 10 и 200.

Сам АЦП представляет собой преобразователь последовательного приближения с устройством выборки-хранения и фиксированным числом тактов преобразования, равным 13 (или 14 для дифференциального входа; первое преобразование после включения потребует 25 тактов для инициализации АЦП). Тактовая частота формируется аналогично тому, как это делается для таймеров- с помощью специального предделителя тактовой частоты МК, который может иметь коэффициенты деления от 1 до 128. Но в отличие от таймеров, выбор тактовой частоты АЦП не совсем произволен, т. к. быстродействие аналоговых компонентов ограничено. Поэтому коэффициент деления следует выбирать таким, чтобы при заданном "кварце" тактовая частота АЦП укладывалась в рекомендованный диапазон 50-200 кГц (т. е. максимум около 15 тыс. измерений в секунду). Увеличение частоты выборки допустимо, если не требуется достижение наивысшей точности преобразования.

Разрешающая способность АЦП в МК AVR - 10 двоичных разрядов, чего для большинства типовых применений достаточно. Абсолютная погрешность преобразования зависит от ряда факторов и в идеальном случае не превышает ±2 младших разрядов, что соответствует общей точности измерения примерно 8 двоичных разрядов. Для достижения этого результата необходимо принимать специальные меры: не только "вгонять" тактовую частоту в рекомендованный диапазон, но и снижать по максимуму интенсивность цифровых шумов. Для этого рекомендуется, как минимум, не использовать оставшиеся выводы того же порта, к которому подключен АЦП, для обработки цифровых сигналов, правильно разводить платы, а как максимум - дополнительно к тому еще и включать специальный режим ADC Noise Reduction.

Отметим также, что АЦП может работать в двух режимах: одиночного и непрерывного преобразования. Второй режим целесообразен лишь при максимальной частоте выборок. В остальных случаях его следует избегать, т. к. обойти в этом случае необходимость параллельной обработки цифровых сигналов, как правило, невозможно, а это означает снижение точности преобразования.

Регистры управления АЦП

Для разрешения работы АЦП необходимо записать лог. 1 в разряд ADEN регистра ADCSR, а для выключения - лог. 0. Если АЦП будет выключено во время цикла преобразования, то преобразование завершено не будет (в регистре данных АЦП останется результат предыдущего преобразования).

Режим непрерывных измерений активизируется установкой бита ADFR (бит 5) этого же регистра. В ряде моделей Mega этот бит носит наименование ADATE, и управление режимом работы производится сложнее: там добавляются несколько режимов запуска через различные прерывания (в т. ч. прерывание от компаратора, при наступлении различных событий от таймера и т. п.), и выбирать их следует, задавая биты ADTS регистра SFIOR, а установка бита ADATE разрешает запуск АЦП по этим событиям. Так как нулевые значения всех битов ADTS (по умолчанию) означают режим непрерывного преобразования, то в случае, когда вы их значения не трогали, функции битов ADATE и ADFR в других моделях будут совпадать.

Если выбран режим запуска не от внешнего источника, то преобразование запускается установкой бита ADTS (бит 6 того же регистра ADCSR/ADCSRA). При непрерывном режиме установка этого бита запустит первое преобразование, затем они будут автоматически повторяться. В режиме однократного преобразования, а также независимо от установленного режима при запуске через прерывания (в тех моделях, где это возможно) установка бита ADCS просто запускает одно преобразование. При наступлении прерывания, запускающего преобразование, бит ADCS устанавливается аппаратно. Отметим, что преобразование начинается по-фронту первого тактового импульса (тактового сигнала АЦП, а не самого контроллера!) после установки ADCS. По окончании любого преобразования (и в одиночном, и в непрерывном режиме) устанавливается бит ADIF (бит 4. флаг прерывания). Разрешение прерывания АЦП осуществляется установкой бита ADIE (бит 3) все того же регистра ADCSR/ADCSRA.

Для работы с АЦП необходимо еще установить его тактовую частоту. Это делается тремя младшими битами регистра ADCSR/ADCSRA под названием ADPS0..2. Коэффициент деления частоты тактового генератора МК устанавливается по степеням двойки, все нули в этих трех битах соответствуют коэффициенту 2, все единицы - 128. Оптимальная частота преобразования лежит в диапазоне 50-200 кГц, так что, например, для тактовой частоты МК, равной 4 МГц, коэффициент может иметь значение только 32 (состояние битов ADPS0..2 = 101, частота 125 кГц) или 64 (состояние битов ADPS0..2 = 110, частота 62,5 кГц). При тактовой частоте 16 МГц в допустимый диапазон укладывается только коэффициент 128.

Выборка источника опорного напряжения производится битами REFS1..0 регистра ADMUX (старшие биты 7 и 6), причем их нулевое значение (по умолчанию) соответствует внешнему источнику. Напряжение этого внешнего источника может лежать в пределах от 2 В до напряжения питания аналоговой части AVcc (а оно, в свою очередь, не должно отличаться от питания цифровой части более чем на 0,3 В в большую или меньшую сторону). Можно выбрать в качестве опорного и питание самой аналоговой части, причем двояким способом: либо просто соединить выводы AREF и AVcc микросхемы, либо установить биты REFS1..0 в состояние 01 (тогда соединение осуществляется внутренними схемами, но заметим, что внешний опорный источник при этом должен быть отключен). Предусмотрен и встроенный источник (задается REFS1..0 в состоянии 11, при этом к выводу AREF рекомендуется подключать фильтрующий конденсатор), имеющий номинальное напряжение 2,56В с большим разбросом от 2,4 до 2,7 В.

*****REFS*******

Результат преобразования АЦП оказывается в регистрах ADCH:ADCL. Поскольку результат 10-разрядный, то по умолчанию старшие 6 битов в регистре ADCH оказываются равными нулю. Чтение этих регистров производится, начиная с младшего ADCL, после чего регистр ADCH блокируется, пока не будет прочитан. Следовательно, даже если момент между чтением регистров попал на фронт 14 (15) такта АЦП, когда данные в них должны меняться, значения прочитанной пары будут соответствовать друг другу, пусть и результат этого преобразования пропадет. В противоположном порядке читать эти регистры не рекомендуется. Но бит ADLAR (бит 5 регистра ADMUX) предоставляет интересную возможность: если его установить в 1, то результат преобразования в регистрах ADCH:ADCL выравнивается влево: бит 9 результата окажется в старшем бите ADCH, а незначащими будут младшие 6 битов регистра ADCL. В этом случае, если хватает 8-разрядного разрешения результата, можно прочесть только значение ADCH.

Выбор каналов и режимов их взаимодействия в АЦП производится битами MUX0..3 в регистре ADMUX. Их значения выбирают нужный канал в обычном (недифференциальном) режиме, когда измеряемое напряжение отсчитывается от "земли". Последние два значения этих битов для семейства Mega (11110 и 11111 в большинстве моделей или 1110 и 1111 для ATmega8) выбирают режимы, когда вход АЦП подсоединяется к опорному источнику компаратора (1,22 В) или к "земле" соответственно, что может использоваться для автокалибровки устройства.

Остальные комбинации разрядов MUX предназначены для установки различных дифференциальных режимов - в тех моделях, где они присутствуют, в других случаях эти биты зарезервированы (как в моделях Atmega8, ATmegal63 и др.). В дифференциальном режиме АЦП измеряет напряжение между двумя выбранными выводами (например, между ADC0 и ADC1), причем не все выводы могут быть в таком режиме задействованы. В том числе дифференциальные входы АЦП можно подключать к одному и тому же входу для коррекции нуля. Дело в том, что в ряде моделей на входе АЦП имеется встроенный усилитель, с коэффициентом 1х, 10х и 200х (коэффициент выбирается теми же битами MUX0..4), и такой режим используется для его калибровки - в дальнейшем значение выхода при соединенных входах можно просто вычесть.

Для недифференциального режима АЦП, когда напряжение отсчитывается от "земли", результат преобразования определяется формулой: Ка = 1024Uвх/Uref, где Ка - значение выходного кода АЦП, Uвх и Uref - входное и опорное напряжения. Дифференциальному измерению соответствует такая формула: Ка = 512(Upos - Uneg)/Uref, где Upos и Uneg - напряжения на положительном и отрицательном входах соответственно. Если напряжение на отрицательном входе больше, чем на положительном, то результат в дифференциальном режиме становится отрицательным и выражается в дополнительном коде от $200 (-512) до $3FF (-1). Реальная точность преобразования в дифференциальном режиме равна 8 разрядам.

ADC - это текстовый протокол для клиент-серверных сетей, наподобие Neo-Modus" Direct Connect (NMDC) . Целью является создание простого протокола, который не нагружает ни клиент, ни сервер, и который можно расширять. В нём исправлены некоторые неудачные решения протокола NMDC, но не все.

Рассматриваются те-же самые взаимодействия: клиент-клиент и клиент-сервер. Данная документация разделена на две части; первая часть описывает структуру протокола, вторая - специфичность системы протокола для использования этой структуры. Advanced Direct Connect - это первая версия, которая будет постепенно улучшаться.

Большинство идей для протокола пришли из проекта DCTNG (Jan Vidar Krey"s). Основные участники разработки: Dustin Brody, Walter Doekes, Timmo Stange, Fredrik Ullner, Fredrik Stenberg и другие. Jon Hess посодействовал как создатель протокола NMDC.

Преимущества протокола

  • SID, а также названия команд протокола, состоят из четырёх латинских символов в верхнем регистре. Протокол достаточно хорошо подходит для реализации на языке СИ. По стандарту языка СИ sizeof(char) == 1, то есть 4 символа будут занимать 4 байта, или могут быть представлены в виде четырёхбайтового целого числа. Преобразование строки в число и обратно значительно упрощает и оптимизирует работу с командами и даёт возможность хранить команду в виде объединения.

Недостатки протокола

  • Разделителями протокола являются очень распространённые символы (пробел и перенос), которые нужно заменять на \s и \n. Так как эти символы очень распространены в сообщениях чата, то число замен всегда будет большим, чего не было в протоколе NMDC.
  • По сравнению с протоколом NMDC, в протоколе ADC есть возможность в UserCommand удалить определённое меню. Однако, по-прежнему отсутствует возможность удаления определённого меню в определённом контексте .

История версий

Последующие версии этого документа, а также промежуточные и более старые версии могут быть получены по адресу: . Эта версия представляется к ревизии:

Версия 1.0.1, 2008-05-02

  • Расширения выделены в отдельный документ.
  • Спецификации выделены в отдельный проект на SourceForge.

Версия 1.0, 2007-12-01

  • Первый релиз

Структура протокола

  • Все команды протокола начинаются с четырёх букв. Первая буква определяет то, как команда должна быть послана, следующие три показывают что должно быть выполнено.
  • Параметры разделяются пробелами, а каждая команда заканчивается символом переноса строки (код 0x0a). Экранируются элементы: "\s" - пробел, "\n" - новая строка и "\\" - обратный слеш. Данная версия протокола резервирует все остальные экранированные символы для возможного дальнейшего использования; любые команды, содержащие неизвестные экранированные символы, должны игнорироваться.
  • Все отсылаемые команды должны отправляться в кодировке UTF-8 - закодированный Юникод в С нормализации.
  • Клиенты должны игнорировать неизвестные/неправильные команды. Хабы должны игнорировать неправильные команды, и должны отсылать неизвестные команды, согласно их типу (префиксу).
  • Адреса клиентов должны быть определены в виде десятичных чисел, разделённых точками ("x.x.x.x") для IPv4 или в формате RFC (1884) для IPv6. Адреса хабов должны быть определены ссылкой с добавкой "adc" спереди, которая показывает специфику данного протокола ("adc://server:port/").
  • Числа отсылаются как строки в соответствии со стандартом плавающей точки, в качестве разделителя между целой дробной частью используется точка "." . Целыми являются числа без дробной части и без экспоненциальной добавки. Приложения должны иметь возможность оперировать с 64-битными положительными числами и с 64-битными числами с плавающей точкой. Префиксом отрицания является знак "-".

D (Direct message) Хаб должен отправить эту команду для пользователя с указанным SID .

E (Echo message) Хаб должен отправить команду для пользователей с sid и my_sid.

F (Feature broadcast) Хаб должен отослать эту команду всем клиентам, которые поддерживают(+)/не поддерживают(-) данную характеристику. Поддержка клиентом той или иной характеристики определяется из поля SU, которое содержится в команде INF , отсылаемой клиентом.

H (Hub message) Клиенты должны использовать данный тип для отсылки команды, которая предназначена только хабу.

I (Info message) Хабы должны использовать данный тип для отсылки команды, которая не была отослана другим клиентом.

U (UDP message) Клиенты должны использовать эту команду только для прямого соединения по протоколу UDP .

Хеш-функции

Некоторые команды используются для определяния хеш-функций. При установке каждого нового соединения по команде SUP происходит обмен хеш-функциями. При коннекте клиент передаёт серверу несколько хеш-функций посредствам параметров команды SUP . Сервер вбирает одну из них и передаёт её клиенту, поставив её до любой другой хеш-функции в команде SUP , которая отправится с сервера. Клиент и хаб должны иметь по крайней мере одну одинаковую хеш-функцию, которая будет использоваться в протоколе и в файловой идентификации.

Идентификация клиента

Каждый клиент идентифицируется по трём различным идентификаторам: идентификатор сессии - Session ID (SID), личный идентификатор - Private ID (PID) и идентификатор клиента - Client ID (CID).

Файлы

Имена файлов отсчитываются от относительного (вымышленного) корня в шаре пользователя. "/" - разделитель директорий; каждый файл или имя директории должно быть уникальным в регистро-независимом контексте. Все печатные символы, включая пробел, допустимы в имени файла, символы "/" и "\" экранируются символом "\". Клиенты должны использовать фильтры для имён под свои файловые системы, имена файлов, полученные от других клиентов, должны также подчиняться этим правилам. Специальные имена "." и ".." не могут содержаться в директории или имени файла; любой полученный файл-лист, содержащий эти имена должен быть проигнорирован. Все имена директорий должны оканчиваться на "/".

Расшаренные файлы идентифицируются относительно безымянного корня "/" ("/dir/subdir/filename.ext"), тогда как дополнения могут добавить имя корня. Например, "TTH/…" для TIGR дополнения используют имя корня "TTH" для идентификации файлов по их "Tiger Tree Hash". Это недопустимо для имён из безымянного корня, которые попали в шару с идентификатором по контрольной сумме.

Без корневое имя файла "files.xml" определяет полный файл-лист, в формате XML в кодировке UTF-8 . Клиентам рекомендуется использовать дополнения чтобы сжимать данный файл-лист.

Дополнения могут добавлять к имени файла свои расширения, обычно это делается для того, чтобы избежать повторения имён.

Специальный тип "list" используется для просмотра списков файлов. Частичный файловый список имеет ту же структуру, что и нормальный список, но директории могут быть теговыми с атрибутом Incomplete="1", который показывает на частичность. Только директории без корневых файлов могут начинаться с символа "/". Содержимое такой директории в последствии будет послано просящему клиенту на глубину, выбранную им (это нужно для отправки только того уровня, который требуется пользователю). Атрибут "Base" для поля "FileListing" определяет к какой конкретной директории принадлежит данный файл.