Atmega8 adc работаем с ацп
Урок 22
Сегодня мы начнем изучать очень интересную технологию, а для микроконтроллера — периферию — это аналго-цифровой преобразователь или как его называют АЦП. В английской аббревиатуре, гораздо чаще встречающейся в технической документации — ADC (Analog-to-Digital Converter). Это такая штука, которая преобразует величину электрического сигнала в цифровой код. Затем данный код мы уже используем для обработки или для отображения тем или иным образом данной электрической величины. Это очень распространённая периферия или технология. АЦП активно используется в звукозаписи, измерительной технике, видеозаписи и во многих других случаях. Поэтому нас обойти данную вещь стороной никак не получится, тем более АЦП поддерживается аппаратно в контроллерах AVR.
В контроллере Atmega8 АЦП имеет следующие характеристики
- Разрешение 10 бит,
- Поддержка запуска по прерываниям,
Есть ещё масса различных характеристик, с которыми мы, возможно, познакомимся в дальнейшем.
Как вообще работает цифровое преобразование?
Берётся опорное напряжение и сравнивается с измеряемым. Соответственно, опорное напряжение всегда должно быть больше измеряемого. Если это не так, то нужно будет применять делители напряжения.
Изобразим схематично процесс измерения
Отрезок — это диапазон измерений. Он находится между нулём и опорным напряжением. А стрелка — это измеряемое напряжение.
Данный отрезок делится пополам, и АЦП оценивает, в какой половине находится приложенное напряжение
Если оно находится в стороне нуля, то в самый старший бит результата записывается 0, а если в стороне максимального напряжения, то единица. У нас будет единица. Затем та половина отрезка, на которой находится измеряемое напряжение делится ещё пополам, и АЦП опять измеряет, в какой половинке уже данного отрезка у нас находится измеряемое напряжение
Оценка идёт по тому же принципу — в какой стороне отрезок. В нашем случае будет 0.
Затем та четвертинка опять делится пополам и АЦП опять оценивает,где находится отрезок
И АЦП так и продолжает такой процесс до тех пор, пока не кончатся ячейки для битов. То есть если мы используем 10-битный режим, то. соответственно, и будет 10 подобных измерений и заполнятся 10 бит величины. Чем больше бит, тем точнее результат, но уже потребуется на это больше времени и более серьёзный и точный АЦП. Имея данный результат, нам несложно будет посчитать величину измеренного напряжения. Мы знаем. что если у нас АЦП 10-битный, то данный результат у нас лежит в промежутке от 0 до 1024, получаемтся всего у нас 1023 отрезка. И мы затем наш результат делим на 1023 и умножаем на величину опорного напряжения.
Посмотрим блок-схему АЦП в контроллере Atmega8
Мы видим, что у нас есть мультиплексор, имеющий 8 каналов, вход для опрного напряжения AREF. Также существует 8-разрядная шина данных, значения с которых записываются в определённый регистр. Есть регистр данных, регистр управления и состояния, а также регистр управления мультиплексором.
Мы будем использовать самый первый вход ADC0 и в качестве источника измеряемого напряжения будем использовать центральную ножку переменного резистора, подлключенного к контактам питания
Работать будем сначала в протеусе. Также мы видим, что у нас подключен дисплей самым обычным образом.
Также мы всё подключим и на живом контроллере
Существует несколько вариантов опорных напряжений, которые мы можем использовать.в нашем АЦП. Мы будем использовать внутреннее опорное напряжение на 2,56 вольт, оно проще, не нужно ничего подключать. Возможно, при таком варианте не очень сильная точность, но перед нами не стоит задача создать точный измерительный прибор. У нас есть задача — изучить возможность использования АЦП в контроллере AVR.
А вот и таблица вариантов опроных напряжений для АЦП
Перечислим данные варианты сверху вних по таблице.
Также в АЦП есть делитель частоты на величину от 2 до 128. Делитель этот для того, чтобы мы добивались частоты работы АЦП не больше 200 кГц, иначе точность измерений будет очень малой и мы просто растеряем самые младшие биты. Если у нас возникнет требование имено к скорости измерений и нам уже точность будет на так важна, то мы сможем использовать и более высокие частоты измерений.
Теперь немного поближе познакомимся с регистрами АЦП.
Регистр ADCSRA — управляющий и статусный регистр
ADEN — данный бит включает АЦП.
ADSC — при установке в 1 заставляет АЦП начинать преобразование.
ADFR — используется в режиме с использованием прерываний. При установке в 1 включает круговой режим, при котором измерения автоматически следуют одно за другим.
ADIF — бит, также используемый только в режиме прерываний. Это флаг прерываний, который устанавливается в определённых условиях.
ADPS2-ADPS0 — биты, от комбинации которых зависит величина делителя
Регистр ADMUX — это регистр для управления каналами мультиплексора АЦП
Но, помимо непосредственно битов управления каналами у данного регистра есть ещё некоторые управляющие биты
REFS1-REFS0 — биты, включающие определённый режим использования опорного напряжения. Таблица была размещена на данной странице выше.
ADLAR — это бит организации расположения измеренных 10 битов в двух байтах регистровой пары данных. Поближе мы с этим расположением познакомимся чуть позже.
MUX3-MUX0 — биты, включающие определённый канал мультиплексора
Отсюда видно, что мы можем пользоваться несколькими каналами сразу только по очереди, попеременно включая различные комбинации данных битов. Также внизу есть две комбинации для калибровки нашего АЦП.
Ну и, наконец, регистровая пара ADCH и ADCL, состоящая из старшего и младшего байта в которую и заносится измеряемый результат. А как именно он туда укладывается, этот результат, зависит от состояния бита ADLAR, рассмотренного выше в регистре ADMUX
То есть, если бит ADLAR не выставлен, то младшие 8 бит результата находятся в младшем байте регистровой пары, а 2 старших бита — в младших битах старшего байта. Если же бит ADLAR у нас выставлен, то 8 самых старших бит результата находятся в сатршем байте, а 2 младших в 2 старших битах младшего байта регистровой пары. Второй вариант нам интересен при исользовании 8-битного режима. В данном случае мы читаем только старший байт.
Проект был создан полностью из проекта урока по изучению 4-битного режима подключения LCD Test09 и был назван MyADCLCD.
Также для выноса кода для реализации периферии АЦП были созданы стандартным образом два файла adc.h
В файл MyADCLCD.c код был также полностью скопирован из главного файла проекта Test09, всё лишнее было удалено. Код в данном файле после данной операции принял следующий вид
Урок 8.
Аналого-Цифровой преобразователь — устройство, преобразующее входной аналоговый сигнал в цифровой код. Под аналоговой величиной подразумевается ток, напряжение, сопротивление, емкость, частота, и так далее. На выходе АЦП мы получаем цифровое представление входной величины. Именно благодаря АЦП микроконтроллер может оперировать аналоговыми сигналами.
Однако АЦП микроконтроллера может измерять только напряжение. Поэтому любую другую величину, например ток, перед измерением необходимо преобразовать в напряжение.
Преобразование входного сигнала в численное представление происходит относительно опорного напряжения. Опорное напряжение( Vref ) — эталонное напряжение, относительно которого происходит преобразование входной величины. При использовании АЦП микроконтроллера AtMega 8, опорное напряжение необходимо подавать на соответствующую ножку контроллера.
Измерение напряжения производится в диапазоне от 0 до Vref .Весь этот диапазон делится в соответствии с разрядностью. То есть если разрядность АЦП — 10 Бит, то диапазон делится на 1023, если 8 бит, то на 255 и так далее. Предполагая, что Vref = 5 Вольтам, при разрядности 10 Бит мы получим шаг измерения 5/1023 = 0.0049 Вольт, а при разрядности 8 бит, шаг измерения станет 5/255 = 0.02 Вольт. То есть, чем меньше разрядность — тем ниже точность преобразования.
Предположим, что мы подаем на вход 10 битного АЦП, c Vref =5 Вольтам, напряжение 3 вольта. На выходе АЦП мы получим численное представление входного напряжения. Легко подсчитать, что шаг измерения равен 0.0049 Вольт, значит, на выходе АЦП мы получим . То есть, для получения значения входного напряжения, необходимо шаг измерения умножить на выходное значение АЦП.
Давайте рассмотрим регистры, отвечающие за конфигурацию АЦП микроконтроллера AtMega 8. АЦП в AtMega 8 всего один, однако, имеет 8 входных каналов. За выбор входного канала, а так же настройку опорного напряжения отвечает регистр ADMUX .
- Биты REFS 0- REFS 1 отвечают за выбор опорного напряжения.
- Биты MUX 0- MUX 3 отвечают за выбор входного канала.
- Бит ADLAR. Определяет порядок записи результатов преобразования в регистры ADCL и ADCH.
АЦП микроконтроллера AtMega 8, может работать как в режиме однократного преобразования, так и в режиме непрерывного преобразования (Следующее преобразование начинается сразу после предыдущего). За настройку режима преобразования, прерываний, а так же тактирования АЦП, отвечает регистр ADCSRA .
- Бит ADEN включает и выключает АЦП микроконтроллера.
ADEN = 1 — АЦП включен.
ADEN = 0 — АЦП выключен.
- При записи 1 в бит ADSC , в режиме однократного преобразования запускается преобразование.
- Бит ADFR , отвечает за выбор режима преобразования.
ADFR = 1 — Непрерывное преобразование.
ADFR = 0 — Однократное преобразование.
- Бит ADIF , флаг окончания преобразования, становится равен 1 при окончании преобразования
- Бит ADIE , разрешает прерывание АЦП.
ADIE = 1 — Прерывание разрешено.
ADIE = 0 — Прерывание запрещено.
- Биты ADPS 0- ADPS 2 отвечают за выбор предделителя между частотой тактирования микроконтроллера и АЦП.
Результат преобразования помещается в пару регистров ADCH и ADCL, в виде заданным значением бита ADLAR.
В качестве примера соберем простой вольтметр с применением LCD WH 1602, и встроенного АЦП микроконтроллера AtMega 8.
Форум по AVR
АЦП – аналогово-цифровой преобразователь (ADC- Analog-to-Digital Converter). Преобразует некий аналоговый сигнал в цифровой. Битность АЦП определяет точность преобразования сигнала. Время преобразования – соответственно скорость работы АЦП.N, где N – битность АЦП. Условимся, что этот регистр, как у ATmega8, 10-ти битный. Преобразование в нашем случае проходит в 10 стадий. Старший бит Z9 выставляется в единицу.
Далее генерируется напряжение (Опорное напряжение*Z/1024), это напряжение, с помощью аналогового компаратора сравнивается с входным, если оно больше входного, бит Z9 становиться равным нулю, а если меньше – остается единицей. Далее переходим к биту Z8 и вышеописанным способом получаем его значения. После того, как вычисление регистра Z окончено, выставляется некий флаг, который сигнализирует, что преобразование закончено и можно считывать полученное значение. На точность преобразования могут очень сильно влиять наводки и помехи, а также скорость преобразования. Чем медленнее происходит преобразования – тем оно точней. С наводками и помехами следует бороться с помощью индуктивности и емкости, как советует производитель в даташите:
В микроконтроллерах AVR как источник опорного напряжения может использоваться вывод AREF, или внутренние источники 2,56В или 1,23В. Также источником опорного напряжения может быть напряжение питания. В некоторых корпусах и моделях микроконтроллеров есть отдельные выводы для питания АЦП: AVCC и AGND. Выводы ADCn – каналы АЦП.
С какого канала будет оцифровываться сигнал можно выбрать с помощью мультиплексора.
Теперь продемонстрируем примером сказанное выше. Соорудим макет, который будет работать как вольтметр с цифровой шкалой. Условимся, что максимальное измеряемое напряжение будет 10В. Также пусть наш макет выводит на ЖКИ содержимое регистра ADC.
Схема подключения:
Обвязка микроконтроллера и ЖКИ Wh2602A стандартна. X1 – кварцевый резонатор на 4 Мгц, конденсаторы С1,С2 – 18-20 пФ. R1-C7 цепочка на выводе reset по 10 кОм и 0,1 мкФ соответственно. Сигнальный светодиод D1 и ограничивающий резистор R2 200 Ом и R3 – 20 Ом. Регулировка контраста ЖКИ – VR1 на 10 кОм. Источник опорного напряжения мы будем использовать встроенный на 2,56В. С помощью делителя R4-R5 мы добьемся максимального напряжения 2,5В на входе PC0, при напряжении на щупе 10В. R4 – 3 кОм, R5 – 1 кОм, в их номиналу нужно отнестись тщательно, но если не возможности подобрать точно такие, можно сделать любой резистивный делитель 1:4 и программно подкорректировать показания, если это потребуется. Дроссель на 10мкГн и конденсатор на 0,1 мкФ для устранения шумов и наводок на АЦП на схеме не показан. Их наличие подразумевается само собой, если используется АЦП. Теперь дело за программой:
Программа на языке Си:
Так-же есть хитрость, чтобы не работать с дробными числами. Когда производиться вычисления входного напряжения в вольтах. Мы просто будем хранить наше напряжения в милливольтах. Например, значение переменной voltage 4234 означает, что мы имеем 4,234 вольта. Вообще операции с дробными числами кушают очень много памяти микроконтроллера (наша прошивка вольтметра весит чуть больше 4 килобайт, это половина памяти программ ATmega8!), их рекомендуется использовать только при особой необходимости. Вычисления входного напряжения в милливольтах просто: voltage=R_division*2.56*u*1.024;
Здесь R_division – коэффициент резистивного делителя R4-R5. Так, как реальный коэффициент делителя может отличаться от расчетного, то наш вольтметр будет врать. Но подкорректировать это просто. С помощью тестера меряем некое напряжение, получаем X вольт, а наш вольтметр пускай показывает Y вольт. Тогда R_division = 4*X/Y, если Y больше X и 4*Y/X если X больше Y. На этом настройка вольтметра завершена, и им можно пользоваться.
Видео работы устройства:
Также можно доработать свой блок питания.N, где N – битность АЦП.
AVR. Учебный курс. Использование АЦП
Многие AVR имеют на борту АЦП последовательного приближения.
АЦП это десятиразрядное, но при точности +/- 2 минимально значащих разрядов его можно смело считать восьмиразрядным 🙂 Так как в младших двух разрядах всегда мусор какой то, не похожий на полезный сигнал. Тем не менее это неплохой инструмент для контроля напряжения, в восьмиразрядном режиме имеющий 256 отсчетов и выдающее частоту дискретизации до 15кГц (15 тысяч выборок в секунду).
Конфигурация источника
Сигнал в АЦП подается через мультиплексор, с одного из восьми (в лучшем случае, часто бывает меньше) входов. Выбор входа осуществляется регистром ADMUX, а точнее его битами MUX3…MUX0. Записанное туда число определяет выбраный вход. Например, если MUX3..0 = 0100, то подключен вывод ADC4.
Кроме того, существует несколько служебных комбинаций битов MUX, использующихся для калибровки.
Например, 1110 подключает к АЦП внутренний источник опорного напряжения на 1.22 вольта. А если записать в MUX3..0 все единицы, то АЦП будет изнутри посажено на землю. Это полезно для выявления разных шумов и помех.
У старших AVR семейства Mega (8535, 16, 32, 128) есть возможность включить АЦП в режиме дифференциального входа. Это когда на два входа приходят разные напряжения. Одно вычитается из другого, да еще может умножаться на коэффициент усиления. Зачем это нужно? А, например, когда надо замерить перекос напряжения измерительного моста. У какого-нибудь тензомоста при входном напряжении в пять вольт выходные сигналы будут различаться между собой всего лишь 30мВ, вот и поймай его. А так подал на диф вход, подогнал нужный коэффициент усиления и красота!
Таблицу значений MUX3..0 для диф включения я не буду тут приводить, она находится легко в даташите, зовется она «Input Channel and Gain Selections«. Я поясню лишь один тонкий момент. В режиме выбора диф входа встречаются такие комбинации как: первый вход ADC0 и второй вход тоже ADC0 ну и коэффициент усиления еще. Как так? Ведь для диф входа нужно два разных входа! Вначале подумал опечатка, поднял даташит на другую АВРку — та же ботва. Потом повтыкал в текст ниже и понял — это для калибровки нуля. Т.е. перед началом съема диф данных нам нужно закоротить входы, чтобы понять, что же у нас ноль. Так вот, комбинация когда два входа подключены к одной ноге это и есть та самая калибровочная закоротка входов. Делаешь первое преобразование на такой фигне, получаешь смещение нуля. А потом вычитаешь его из всех полученных значений, что резко повышает точность.
Мультиплексирование каналов осуществляется только после того, как завершится преобразование, поэтому можно смело запускать АЦП на обсчет входных значений, записывать в MUX3..0 параметры другого входа, и готовится снимать данные уже оттуда.
Выбор опорного сигнала
Это максимальное напряжение, которое будет взято за максимум при измерениях. Опорное напряжение должно быть как можно стабильней, без помех и колебаний — от этого кардинальным образом зависит точность работы АЦП. Задается он в битах REFS1..0 регистра ADMUX.
- По дефолту там стоит REFS1..0 = 00 — внешний ИОН, подключенный к входу AREF. Это может быть напряжение со специальной микросхемы опорного напряжения, или же со стабилитрона какого, если нужно замерять небольшое напряжение, заметно меньшее чем напряжение питания, скажем от 0 до 1 вольт, то чтобы было точнее, и чтобы оно не затерялось на фоне пятивольтового питания, то на AREF мы заводим опорное напряжение в 1 вольт.
- REFS1..0 = 01 — тут просто берется напряжение питания. У всех почти Мег с АЦП есть вход AVCC — вот это напряжение питания для AЦП и порта на который это АЦП повешено. Подавать туда плюс питания желательно через LC фильтр, чтобы не было искажений.
- REFS1..0 = 11 — внутренний источник опорного напряжения на 2.56 вольт. Честно говоря, качество этого источника мне сильно не понравилось. С ним показания АЦП плавают как говно в проруби. Но если невозможно обеспечить гладкую и стабильную подачу напряжения на AREF или AVCC то прокатит. Кстати, внутренний ИОН подключен к выводу AREF так что можно повесить туда кондер и попробовать его чуть чуть сгладить. Немного, но помогает.
В регистре SFIOR под АЦП отведено аж три бита. ADTS2..0 которые управляют режимами запуска АЦП.
- По дефолту ADTS2..0 = 000 и это значит, что преобразование идет в непрерывном режиме. Ну или по ручному запуску.
- ADTS2..0 = 001 — запуск АЦП от аналогового компаратора. Удобно блин. Например, чтобы не замерять постоянно входную величину, а запрограммировать компаратор на то, что как только у него вылезет что-либо выше порога, так тут же захватывать это дело на АЦП.
- ADTS2..0 = 010 — запуск от внешнего прерывания INT0
- ADTS2..0 = 011 — по совпадению таймера T0
- ADTS2..0 = 100 — по переполнению таймера Т0
- ADTS2..0 = 101 — по совпадению с таймера Т1
- ADTS2..0 = 110 — По переполнению таймера Т1
- ADTS2..0 = 111 — По событию «захват» таймера Т1
Частота выборки АЦП задается в битах предделителя ADPS2…0 регистра ADCSR. Саму таблицу можно поглядеть в даташите на соответствующий МК, скажу лишь то, что самая оптимальная точность работы модуля АЦП находится в пределах 50…200кГц, поэтому предделитель стоит настраивать исходя из этих соображений. С повышением частоты точность падает.
Прерывания.
Естественно у АЦП есть прерывания. В данном случае это прерывание по окончанию преобразования. Его можно разрешить битом ADIE, а внаглую вручную палится оно по флагу ADIF (регистр ADCSRA). Флаг ADIF автоматом снимается при уходе на вектор прерывания по АЦП.
Данные с АЦП сваливаются в регистровую пару ADCH:ADCL откуда их можно забрать. Причем тут есть один прикольный момент. Регистровая пара то у нас ведь 16ти разрядная, а АЦП имеет разрядность 10бит. В итоге, лишь один регистр занят полностью, а второй занимает лишь оставшиеся два бита. Так вот, выравнивание может быть как по правому краю — старшие два бита в ADCH, а младшие в ADCL, либо по левому — старшие биты в ADCH, а два младших бита в ADCL.
[x][x][x][x][x][x][9][8]:[7][6][5][4][3][2][1][0] или [9][8][7][6][5][4][3][2]:[1][0][x][x][x][x][x][x]
Зачем это сделано? А это выборка разрядности так оригинально организована. Как я уже говорил, в младших разрядах все равно мусор и шумы (по крайней мере я от них так и не смог избавиться, как ни старался) . Так вот. Делаем выравнивание по левому краю. И загребаем старшие разряды только из регистра ADCH, а на младший забиваем. Итого, у нас число отсчетов становится 256. За выравнивание отвечает бит ADLAR в регистре ADMUX 0 — выравнивание по правой границе, 1 — по левой.
Запуск преобразования в ручном или непрерывном режиме.
Для запуска преобразования нужно вначале разрешить работу ADC, установкой бита ADEN в регистре ADCSR и в том же регистре ткнуть в бит ADSC. Для запуска непрерывного преобразование (одно за другим) нужно также выставить бит ADFR (ADATE в некоторых AVR).
Повышение точности уходом в спячку.
Для повышения точности, чтобы внутренние цепи АЦП не гадили своими шумами, можно запустить АЦП в спящем режиме. Т.е. проц останавливается, все замирает. Работает только WatchDog и блок АЦП. Как только данные сосчитаются, генерируется прерывание которое будит процессор, он уходит на обработчик прерывания от АЦП и дальше все своим чередом.
А теперь приведу парочку примеров простой инициализации и работы с АЦП. Микроконтроллер ATMega16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ; Мой любимый макрос для записи в порты :)))) .MACRO outi LDI R16,@1 OUT @0,R16 .ENDM ; ADC Init - Инициализурем АЦП. Это можно сунуть куда - нибудь в начало кода OUTI ADCSRA,(1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(1<<ADATE)|(3<<ADPS0) ; Итак что тут у нас: ; ADEN = 1 - разрешаем АЦП ; ADIE = 1Разрешаем прерывания. ; ADSC = 1 Запускаем преобразование (первое, дальше автоматом) ; ADATE = 1 Непрерывные последовательные преобразования, одно за другим. ; ADPS2..0 = 3 Делитель частоты на 8 - так у меня получается оптимальная частота. OUTI ADMUX,0b01000101 ;А тут выбираем откуда брать будем сигнал ;REFS -- 0b[01]000101 первые два бита - напряжение с входа AVCC ;ADLAR --0b01[0]00101следующий бит выравнивание по правому краю ;MUX -- 0b010[00000]</B>Сигнал на вход идет с нулевого канала АЦП. |
; Мой любимый макрос для записи в порты :)))) .MACRO outi LDI R16,@1 OUT @0,R16 .ENDM ; ADC Init — Инициализурем АЦП. Это можно сунуть куда — нибудь в начало кода OUTI ADCSRA,(1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(1<<ADATE)|(3<<ADPS0) ; Итак что тут у нас: ; ADEN = 1 — разрешаем АЦП ; ADIE = 1Разрешаем прерывания. ; ADSC = 1 Запускаем преобразование (первое, дальше автоматом) ; ADATE = 1 Непрерывные последовательные преобразования, одно за другим. ; ADPS2..0 = 3 Делитель частоты на 8 — так у меня получается оптимальная частота. OUTI ADMUX,0b01000101 ;А тут выбираем откуда брать будем сигнал ;REFS — 0b[01]000101 первые два бита — напряжение с входа AVCC ;ADLAR —0b01[0]00101следующий бит выравнивание по правому краю ;MUX — 0b010[00000]</B>Сигнал на вход идет с нулевого канала АЦП.
А что дальше делать? А ничего! Сидеть и ждать прерывания!
Когда оно придет процессор кинет на вектор и дальше уже можно либо переписать данные из ADCH:ADCL в другое место, либо какую простенькую обработку тут же, не отходя от кассы, замутить. Вроде усреднения.
Вариант два, с уходом в спячку. В принципе, все то же самое, только нужно выключить автоматический перезапуск конвертирования. Далее в регистре MCUCR в битах SM2..0 выбрать режим ADC Noise Reduction SM2..0 = 001, а после, сразу же после запуска послать процессор в спячку командой SLEEP. Как только он уснет заработает АЦП, сделает преобразование и проснется на прерывании.
Выглядит это так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ; ADC Init - Инициализурем АЦП. Это можно сунуть куда - нибудь в начало кода OUTI ADMUX,0b01000101 ;А тут выбираем откуда брать будем сигнал ;REFS -- 0b[01]000101 первые два бита - напряжение с входа AVCC ;ADLAR --0b01[0]00101следующий бит выравнивание по правому краю ;MUX -- 0b010[00101]</B>Сигнал на вход идет с 5й ноги. OUTI MCUCR,0b10010000 ; Выставил биты спящего режима в Noise Reduction ; А это уже тело главной программы Main Prog: OUTI ADCSRA,(1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(0<<ADATE)|(3<<ADPS0) ; Подготовили АЦП SLEEP ; Свалились в спячку, как только Хрюша со Степашей скажут нам ; Баю-бай так врубится молотилка АЦП, затем придет Фреди Крюг... ; в смысле запрос на прерывание и проц резко проснется |
; ADC Init — Инициализурем АЦП. Это можно сунуть куда — нибудь в начало кода OUTI ADMUX,0b01000101 ;А тут выбираем откуда брать будем сигнал ;REFS — 0b[01]000101 первые два бита — напряжение с входа AVCC ;ADLAR —0b01[0]00101следующий бит выравнивание по правому краю ;MUX — 0b010[00101]</B>Сигнал на вход идет с 5й ноги. OUTI MCUCR,0b10010000 ; Выставил биты спящего режима в Noise Reduction ; А это уже тело главной программы Main Prog: OUTI ADCSRA,(1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(0<<ADATE)|(3<<ADPS0) ; Подготовили АЦП SLEEP ; Свалились в спячку, как только Хрюша со Степашей скажут нам ; Баю-бай так врубится молотилка АЦП, затем придет Фреди Крюг… ; в смысле запрос на прерывание и проц резко проснется
Ну и, для повышения точности, следует соблюдать ряд правил по подключению питания к АЦП модулю, например подавать напряжение на вход AVCC через дроссель, ставить конденсаторы и земли побольше вокруг. Об этом все есть в даташите. Я же скоро выложу пример рабочей программы — примера для АЦП и UART.
Проекты на микроконтроллерах AVR — Аналогово-Цифровой Преобразователь (АЦП) и Bascom-AVR
Аналогово-Цифровой Преобразователь (АЦП)
Микроконтроллер — цифровой прибор, который понимает и работает только с цифровыми сигналами (нулями и единицами). Но вокруг нас все сигналы представлены в аналоговой форме — освещение, температура и давление, влажность, звуки — все это непрерывно меняющиеся физические величины.
Для того чтобы обрабатывать аналоговые сигналы, в большинство микроконтроллеров AVR встроен АЦП (ADC–analog digital converter) – аналого-цифровой преобразователь.
Аналогово-Цифровой Преобразователь служит для преобразования аналогового сигнала на входе в цифровую форму, понятную для МК. Практически во всех современных микроконтроллерах от AVR имеется 10 битный АЦП, позволяющий оцифровывать аналоговый сигнал с дискретностью 1024 значений. Этого достаточно чтобы, например, делать замеры напряжений (в разумных пределах), снимать показания с различных датчиков, таких как фотодиод и термопара, делать анализаторы спектра и многое другое.
Примерная работа преобразования приведена на рисунке ниже; через равные промежутки времени (ось X) происходит считывание значения напряжения на входе АЦП (ось Y). Так как АЦП имеет ограниченную разрешающую способность, появляется дискретность (дробление) значений.
Величина по оХ называется частотой дискретизации, чем больше частота тем точнее может быть полученная информация о сигнале. АЦП в мк AVR может работать на частотах дискретизации от 50 до 200 кГц, это значит что микроконтроллер может до 200-х раз в секунду считывать уровень напряжения на входе АЦП.
Для того чтобы начать работать с преобразователем его сперва необходимо сконфигурировать. В Bascom-AVR настройка АЦП сводится всего к одной строчке:
Config Adc = SINGLE , Prescaler = 128 , Reference = Avcc
здесь Adc — режим считывания значения: Single — единичное считывание, также может быть Free (режим постоянной работы преобразователя)
Prescaler = 128 — выбираем частоту дискретизации путем деления частоты кварца на определенное число (также может быть 2,4,8,16,32,64 или Auto). Если выбрать Auto, то компилятор сам выберет подходящую частоту работы АЦП
Reference – выбор источника опорного напряжения (ИОН), у этого параметра может быть несколько значений:
Aref – внешний источник, Avcc – напряжение питания схемы, Internal – внутренний стабилизатор на 2,56 вольт (или в некоторых микроконтроллерах, таких как ATmega48P — 1,1 вольт)
Для того чтобы посмотреть работу АЦП можно собрать вот такую простую схему на микроконтроллере ATmega8 (или на любом другом камне имеющем на борту цифро-аналоговый преобразователь).
В качестве опорного напряжения для АЦП будет использоваться встроенный стабилизатор, у Atmega8 этот стабилизатор выдает 2,56 вольт. А для того чтобы этот стабилизатор заработал нужно подать напряжение на ножку AVCC. Чтобы уменьшить шумы по питанию и увеличить качество работы стабилизатора, принято подавать питание на эту ножку через дроссель (L1) номиналом 10÷100 мкГн, а так же соединять с землей через керамический конденсатор 100 нанофарад (С1). Но для простого тестирования, конечно можно убрать эти элементы и соединить ножку AVCC напрямую с VCC.
Вход АЦП (ADC0) соединим с переменным резистором (потенциометр), таким образом получится делитель напряжения, который позволит менять напряжение на этой ножке.
тестовый исходник работы с АЦП в Bascom-AVR
$regfile = «m8def.dat» ‘микроконтроллер ATmega8
$crystal = 1000000 ‘частота работы 1МГц
$baud = 1200 ‘скорость передачи 1200 бод
‘конфигурируем АЦП
Config Adc = Single , Prescaler = 128 , Reference = Internal
Dim R As Word ‘переменная R в которую будем записывать показания с АЦП
Start Adc ‘запускаем пребразователь
‘этой командой на преобразователь поступает питание
‘работу преобразователя также можно остановить в любой момент
‘для этого пишем команду:
‘Stop Adc
Do ‘бесконечный цикл
R = Getadc(0) ‘считываем нулевой канал АЦП и записываем в переменную
Print R ‘печатаем значение в терминал
Waitms 500 ‘ждем полсекунды и повторяем
Loop
End
Изменяя напряжение на ножке ADC0 с помощью переменного резистора, мы увидим как меняется значение считанное с АЦП. На рисунке ниже показан скрин терминала с данными, которые получил с АЦП
При вращении ручки потенциометра можно заметить одну странность: если плавно увеличивать напряжение на входе АЦП, то в определенный момент показания перестанут расти, а значение переменной остановится на значении 1023. На самом деле это означает, что АЦП достиг максимального предела измерения. Если в этот момент измерить напряжение на входе АЦП то мы получим значение примерно 2,56 вольт, что равняется выбранному значению опорного напряжения. Отсюда можно сделать вывод, что АЦП измеряет напряжение на входе только в пределах от нуля до значения ИОН.
Так как изменение значения с АЦП меняются пропорционально напряжению на входе, для удобства можно пользоваться вот таким рисунком.
К примеру, получив значение c АЦП 599 можно примерно прикинуть сколько соответствует этому вольт на входе. А чтобы увеличить диапазон измеряемого напряжения, нужно использовать резисторный делитель.
ATmega16 (32): аналого-цифровой преобразователь (ADC) | avr
Перевод даташита Atmel на микроконтроллер ATmega16, ATmega32, касающийся ADC.
[Отличительные особенности]
- 10-разрядное разрешение
- Интегральная нелинейность 0.5 мл. разр.
- Абсолютная погрешность ±2 мл. разр.
- Время преобразования 13 — 260 мкс.
- Частота преобразования до 15 тыс. преобр. в сек. при максимальном разрешении
- 8 мультиплексированных однополярных каналов (входов)
- 7 дифференциальных каналов (входов)
2 дифференциальных канала (входа) с подключаемым усилением на 10 и 200 - Представление результата с левосторонним или правосторонним выравниванием в 16-разр. слове
- Диапазон входного напряжения ADC 0…VCC
- Выборочный внутренний ИОН (Reference Voltage) на 2.56 В
- Режимы одиночного преобразования и автоматического перезапуска
- Прерывание по завершении преобразования ADC
- Механизм подавления шумов в режиме сна
Замечание: дифференциальные каналы не тестировались для микроконтроллеров в корпусе PDIP40. Работа в таком режиме гарантируется только для микроконтроллеров в корпусах TQFP и QFN/MLF.
ATmega16 содержит 10-разр. ADC последовательного приближения. ADC связан с 8-канальным аналоговым мультиплексором, 8 однополярных (недифференциальных) входов которого связаны с ножками порта A. Недифференциальные входы измеряют потенциал напряжения относительно провода 0 В (т. е. связанного с GND).
ADC также поддерживает 16 вариантов конфигурации для дифференциальных входов. Два дифференциальных входа (ADC1, ADC0 и ADC3, ADC2) содержат каскад со ступенчатым программируемым усилением: 0 дБ (1x), 20 дБ (10x), или 46 дБ (200x) – непосредственно перед аналого-цифровым преобразованием. Семь дифференциальных аналоговых каналов используют общий инвертирующий вход (ADC1), а все остальные входы ADC выполняют функцию неинвертирующих входов. Если выбрано усиление 1x или 10x, то можно ожидать 8-разрядное разрешение, а если 200x, то 7-разрядное.
ADC содержит УВХ (Sample and Hold circuit, устройство выборки-хранения), которое поддерживает на постоянном уровне напряжение на входе ADC во время преобразования. Функциональная схема ADC показана на рисунке 98.
ADC имеет отдельный вывод питания AVCC (аналоговое питание). AVCC не должен отличаться более чем на ±0.3В от VCC. См. параграф “Подавитель шумов ADC (ADC Noise Canceler)”, где приведены рекомендации по подключению этого вывода.
В качестве внутреннего опорного напряжения может выступать напряжение от внутреннего ИОН (Reference Voltage, Источник Опорного Напряжения) на 2.56В или напряжение AVCC. Для уменьшения шума к выводу AREF может быть подключен внешний блокировочный конденсатор.
Рисунок 98. Блоковая схема ADC.
[Принцип действия]
ADC преобразовывает входное аналоговое напряжение в 10-разр. код методом последовательных приближений. Минимальное значение соответствует уровню GND, а максимальное уровню AREF минус 1 мл. разр. К выводу AREF по выбору может быть подключено напряжение AVCC или внутренний ИОН на 2.56В путем записи соответствующих значений в биты REFSn регистра ADMUX. Несмотря на то, что ИОН на 2.56В находится внутри микроконтроллера, к его выходу может быть подключен блокировочный конденсатор для снижения чувствительности к шумам, т.к. он связан с выводом AREF.
Канал аналогового ввода и каскад дифференциального усиления выбираются путем записи бит MUX в регистр ADMUX. В качестве однополярного аналогового входа ADC может быть выбран один из входов ADC0…ADC7, а также GND и выход фиксированного источника напряжения (fixed bandgap voltage reference). В режиме дифференциального ввода предусмотрена возможность выбора инвертирующих и неинвертирующих входов к дифференциального усилителя.
Если выбран дифференциальный режим аналогового ввода, то дифференциальный усилитель будет усиливать разность напряжений между выбранной парой входов на заданный коэффициент усиления. Усиленное таким образом значение поступает на аналоговый вход ADC. Если выбирается однополярный режим аналогового ввода, то каскад усиления пропускается.
Работа ADC разрешается путем установки бита ADEN в регистре ADCSRA. Выбор опорного источника и канала преобразования не производят эффекта до установки ADEN. Если ADEN = 0, то ADC не потребляет ток, поэтому, при переводе в экономичные режимы сна рекомендуется предварительно отключить ADC.
ADC генерирует 10-разрядный результат, который помещается в пару регистров данных ADC ADCH и ADCL. По умолчанию результат преобразования размещается в младших 10-ти разрядах 16-разр. слова (выравнивание справа), но может быть опционально размещен в старших 10-ти разрядах (выравнивание слева) путем установки бита ADLAR в регистре ADMUX.
Практическая полезность представления результата с выравниванием слева существует, когда достаточно 8-разрядное разрешение, т.к. в этом случае необходимо считать только регистр ADCH. В другом же случае необходимо первым считать содержимое регистра ADCL, а затем ADCH, чем гарантируется, что оба байта являются результатом одного и того же преобразования. Как только выполнено чтение ADCL, блокируется доступ к регистрам данных со стороны ADC. Это означает, что если считан ADCL и преобразование завершается перед чтением регистра ADCH, то ни один из регистров не может модифицироваться и результат преобразования теряется. После чтения ADCH доступ к регистрам ADCH и ADCL со стороны ADC снова разрешается.
ADC генерирует собственный запрос на прерывание по завершении преобразования. Если между чтением регистров ADCH и ADCL запрещен доступ к данным для ADC, то прерывание возникнет, даже если результат преобразования будет потерян.
[Запуск преобразования]
Одиночное преобразование запускается путем записи лог. 1 в бит запуска преобразования ADC ADSC (регистр ADCSRA). Данный бит остается в высоком состоянии в процессе преобразования и сбрасывается по завершении преобразования. Если в процессе преобразования переключается канал аналогового ввода, то ADC автоматически завершит текущее преобразование прежде, чем переключит канал.
Другой вариант запуска преобразования – автоматический запуск по сигналу из различных источников. В режиме автоматического перезапуска ADC непрерывно оцифровывает аналоговый сигнал и обновляет регистр данных ADC. Данный режим задается путем записи лог. 1 в бит ADATE регистра ADCSRA. Можно также выбрать источник перезапуска битами ADTS регистра SFIOR (см. описание битов ADTS для списка источников запуска). Когда происходит положительный перепад выбранного сигнала перезапуска, сбрасывается прескалер ADC и запускается преобразование. Это предоставляет метод запуска преобразования в фиксированные интервалы времени. Если сигнал запуска все еще установлен, когда преобразование завершено, новое преобразование не запускается. Если происходит положительный перепад выбранного сигнала перезапуска происходит во время преобразования, этот перепад будет игнорирован. Внимание – флаг прерывания ADIF будет все равно установлен, даже если соответствующее прерывание запрещено или бит глобального разрешения прерываний регистра SREG сброшен, при этом преобразование запустится без генерации прерывания. Однако флаг прерывания ADIF должен быть очищен, чтобы запустилось новое преобразование при следующем событии прерывания.
Рисунок 99. Логика автоматического запуска ADC.
Использование флага прерывания ADC (ADIF) как источника запуска преобразования запускает новое преобразование, как только текущее преобразование завершается. Таким образом, ADC работает в режиме автозапуска — непрерывно оцифровывает аналоговый сигнал и обновляет регистр данных ADC. Первое преобразование инициируется путем записи лог. 1 в бит ADSC регистра ADCSRA. В данном режиме ADC выполняет последовательные преобразования, независимо от того — сброшен флаг прерывания ADC ADIF или нет.
Если разрешен автозапуск (установлен бит ADATE регистра ADCSRA), одиночные преобразования могут запускаться путем записи лог. 1 в бит ADSC регистра ADCSRA. Бит ADSC может использоваться для определения, происходит или нет в настоящий момент преобразование. Бит ADSC будет читаться как 1 во время выполнения преобразования, независимо от того, как оно было запущено.
[Предделитель (прескалер) и временная диаграмма преобразования]
Рисунок 100. Прескалер ADC.
Если требуется максимальная разрешающая способность (10 разрядов), то тактовая частота для ADC последовательного приближения должна быть в диапазоне 50…200 кГц. Если достаточно разрешение менее 10 разрядов, то для получения более высокой частоты преобразования тактовая частота ADC может быть установлена свыше 200 кГц.
Модуль ADC содержит предделитель, который формирует частоты тактов ADC из любых частот ядра микроконтроллера свыше 100 кГц. Коэффициент деления устанавливается с помощью бит ADPS в регистре ADCSRA. Предделитель начинает счет с момента включения ADC установкой бита ADEN в регистре ADCSRA. Предделитель работает, пока бит ADEN = 1, и постоянно сброшен, когда ADEN=0.
Если инициируется преобразование не в дифференциальном режиме установкой бита ADSC в регистре ADCSRA, то преобразование начинается со следующего нарастающего фронта тактового сигнала ADC. Особенности временной диаграммы в режиме дифференциального преобразования представлены в разделе “Каналы дифференциального усиления”.
Нормальное преобразование требует 13 тактов синхронизации ADC. Первое преобразование после включения ADC (установка ADEN в ADCSRA) требует 25 тактов синхронизации ADC за счет необходимости инициализации аналоговой схемы.
После начала нормального преобразования на выборку-хранение затрачивается 1.5 такта синхронизации ADC, а после начала первого преобразования – 13,5 тактов. По завершении преобразования результат помещается в регистры данных ADC и устанавливается флаг ADIF. В режиме одиночного преобразования одновременно сбрасывается бит ADSC. Программно бит ADSC может быть снова установлен и новое преобразование будет инициировано первым нарастающим фронтом тактового сигнала ADC.
В режиме автоматического перезапуска прескалер (предделитель) сбрасывается при каждом событии запуска. В этом режиме схема выборки-хранения требует 2 такта ADC после нарастающего фронта сигнала запуска. 3 дополнительных цикла ядра микроконтроллера используется для логики синхронизации. В дифференциальном режиме, если используется автозапуск от любого источника, кроме «завершение преобразования ADC», каждое преобразование требует 25 тактов ADC. Это происходит из-за того, что ADC должен быть запрещен и снова разрешен для каждого преобразования.
В режиме постоянного преобразования (Free Running) новое преобразование начинается сразу по завершении предыдущего, пока бит ADSC остается в высоком состоянии. Времена преобразования для различных режимов преобразования представлены в таблице 81.
Рисунок 101. ВременнАя диаграмма ADC, первое преобразование (режим одиночного преобразования).
Рисунок 102. ВременнАя диаграмма ADC, одиночное преобразование.
Рисунок 103. ВременнАя диаграмма ADC, преобразование с автозапуском.
Рисунок 104. ВременнАя диаграмма ADC, непрерывное преобразование (Free Running conversion).
Таблица 81. Время преобразования ADC.
Условие |
выборка и хранение (в циклах ADC относительно начала преобразования) |
время преобразования в циклах ADC |
Первое преобразование | 13.5 | 25 |
Недифференциальное обычное преобразование | 1.5 | 13 |
Преобразование с автозапуском | 2 | 13.5 |
Дифференциальное обычное преобразование | 1.5/2.5 | 13/14 |
[Каналы дифференциального усиления]
Если используются каналы дифференциального усиления, то необходимо принять во внимание некоторые особенности.
Дифференциальные преобразования синхронизированы внутренней тактовой частотой CKADC2, частого которого равна половине частоты синхронизации ADC. Данная синхронизация выполняется автоматически интерфейсом ADC таким образом, чтобы выборка-хранение инициировалась определенным фазой CKADC2. Если преобразование (все одиночные преобразования и первое преобразование в режиме автоматического перезапуска) инициировалось пользователем, когда CKADC2 находился в низком лог. состоянии, то его длительность будет эквивалента недифференциальному преобразованию (13 тактов синхронизации ADC относительно следующего такта). Если преобразование инициируется пользователем, когда CKADC2 равен лог. 1 , оно будет длиться 14 тактов синхронизации ADC вследствие работы механизма синхронизации. В режиме автоматического перезапуска (Free Running mode) новое преобразование инициируется сразу по завершении предыдущего, а т.к. в этот момент CKADC2 равен лог. 1, то все преобразования, которые были автоматически перезапущены (т. е. все, кроме первого), будут длиться 14 тактов синхронизации ADC.
Усилительный каскад оптимизирован под частотный диапазон до 4 кГц для любых коэффициентов усиления. Усиление сигналов более высоких частот будет нелинейным. Поэтому, если входной сигнал содержит частотные составляющие выше частотного диапазона усилительного каскада, то необходимо установить внешний фильтр низких частот. Обратите внимание, что частота синхронизации ADC не связана с ограничением по частотному диапазону усилительного каскада. Например, период синхронизации ADC может быть 6 мкс, при котором частота преобразования канала равна 12 тыс. преобр. в секунду, независимо от частотного диапазона этого канала.
Если используются каналы дифференциального усиления и преобразование запущено автоматическим запуском, то ADC должен быть выключен между преобразованиями. При использовании автоматического запуска прескалер ADC сброшен перед запуском преобразования. Поскольку каскад усиления зависит от стабильной тактовой частоты ADC перед преобразованием, то это преобразование будет недействительным. Путем запрещения и разрешения ADC между каждыми преобразованиями (с помощью записи 0 и 1 соответственно в бит ADEN регистра ADCSRA) выполняются только расширенные преобразования. Результат расширенного преобразования будет действительным. См. подробнее раздел «Предделитель (прескалер) и временная диаграмма преобразования».
[Изменение канала или выбор источника опорного напряжения]
Биты MUXn и REFS1:0 в регистре ADMUX поддерживают одноступенчатую буферизацию через временный регистр. Этим гарантируется, что новые настройки канала преобразования и опорного источника вступят в силу в безопасный момент для преобразования. Любые изменения канала и опорного источника постоянно вступают в силу в момент начала преобразования. Как только начинается процесс преобразования доступ к изменению канала и опорного источника блокируется, чем гарантируется достаточность времени на преобразование для ADC. Непрерывность модификации восстанавливается на последнем такте ADC перед завершением преобразования (при установке флага ADIF в регистре ADCSRA). Обратите внимание, что преобразование начинается следующим нарастающим фронтом тактового сигнала ADC после записи ADSC. Таким образом, пользователю не рекомендуется записывать новое значение канала или опорного источника в ADMUX до завершения 1-го такта синхронизации ADC после записи ADSC.
Если используется автозапуск преобразования, то нельзя определить точное время события запуска. Необходимо внимательно обновлять регистр ADMUX, чтобы определить, какое преобразование будет соответствовать новым установкам.
Если оба бита ADATE и ADEN установлены в лог. 1, событие прерывания может произойти в любой момент. Если регистр ADMUX был изменен в этот период, то пользователь не может сказать, произошло это преобразование на основе старых или новых установок. В этом случае ADMUX должен модифицироваться следующими способами:
- Когда очищены бит ADATE или ADEN.
- Во время преобразования, минимум один цикл ADC после события срабатывания преобразования.
- После преобразования, перед тем как флаг прерывания ADIF очищен для использования как источник события запуска.
Когда регистр ADMUX обновляется с соблюдением этих условий, то новые установки начнут работать во время следующего преобразования ADC.
Особые меры необходимо предпринять при изменении дифференциальных каналов. Как только осуществлен выбор дифференциального канала, усилительному каскаду требуется 125 мкс для стабилизации нового значения. Следовательно, после переключения дифференциального канала в течение первых 125 мкс не должно стартовать преобразование. Если же в этот период преобразования все-таки выполнялись, то их результат необходимо игнорировать.
Такую же задержку на установление необходимо ввести при первом дифференциальном преобразовании после изменения источника опорного напряжения для ADC (путем изменения бит REFS1:0 в ADMUX).
[Входные каналы ADC]
При переключении входного канала необходимо учесть некоторые рекомендации, которые исключат некорректность переключения.
В режиме одиночного преобразования переключение канала необходимо выполнять перед началом преобразования. Переключение канала может произойти только в течение одного такта синхронизации ADC после записи лог. 1 в ADSC. Однако самым простым методом является ожидание завершения преобразования перед выбором нового канала.
В режиме автоматического перезапуска (Free Running mode) канал необходимо выбирать перед началом первого преобразования. Переключение канала происходит аналогично — в течение одного такта синхронизации ADC после записи лог. 1 в ADSC. Но самым простым методом является ожидание завершения первого преобразования, а затем переключение канала. Поскольку следующее преобразование уже запущено автоматически, то следующий результат будет соответствовать предыдущему каналу. Последующие преобразования отражают результат для нового выбранного канала.
При переключении на дифференциальный канал первое преобразование будет характеризоваться плохой точностью из-за переходного процесса в схеме автоматической регулировки смещения. Следовательно, первый результат такого преобразования рекомендуется игнорировать.
[Источник опорного напряжения ADC]
Источник опорного напряжения (ИОН) для ADC (VREF) определяет диапазон преобразования ADC. Если в недифференциальном режиме уровень сигнала свыше VREF, то результатом преобразования будет 0x3FF. В качестве VREF могут выступать AVCC, внутренний ИОН 2,56В или внешний ИОН, подключенный к выв. AREF.
AVCC подключается к ADC через пассивный ключ. Внутреннее опорное напряжение 2,56В генерируется внутренним эталонным источником (Bandgap Reference) VBG, буферизованного внутренним усилителем. В любом случае внешний вывод AREF связан непосредственно с ADC, и поэтому можно снизить влияние шумов на опорный источник за счет подключения конденсатора между выводом AREF и общим проводом (GND). Напряжение VREF также может быть измерено на выводе AREF высокоомным вольтметром. Обратите внимание, что VREF является высокоомным источником, и поэтому внешне к нему может быть подключена только емкостная нагрузка.
Если пользователь использует внешний опорный источник, подключенный к выв. AREF, то не допускается использование другой опции опорного источника, т. к. это приведет к шунтированию внешнего опорного напряжения. Если к выв. AREF не приложено напряжение, то пользователь может выбрать AVCC и 2.56В качестве опорного источника. Результат первого преобразования после переключения опорного источника может характеризоваться плохой точностью и пользователю рекомендуется его игнорировать.
Если используются дифференциальные каналы, то выбранный опорный источник должен быть меньше уровня AVCC, что показано в табл. 122.
Часть таблицы 122. Уровень опорного напряжения ADC.
Символ | Параметр | Режим | Min | Номинал | Max | Единицы |
VREF |
Опорное напряжение | Недифференциальный | 2.0 | AVCC | В | |
Дифференциальный | 2.0 | AVCC — 0.2 | В |
[Подавитель шумов ADC (ADC Noise Canceler)]
ADC имеет встроенный подавитель шумов, который позволяет производить преобразование в режиме сна (sleep mode), что уменьшает влияние шумов, вызванных работой ядра ЦПУ и периферийных устройств ввода-вывода. Подавитель шумов может быть использован совместно с режимами снижения шумов ADC (ADC Noise Reduction) и в режиме холостого хода (Idle mode). При использовании данной функции необходимо придерживаться следующей процедуры:
- Убедитесь, что работа ADC разрешена и он не выполняет преобразования. Должен быть выбран режим одиночного преобразования и разрешено прерывание по завершении преобразования.
- Запустите режим уменьшения шумов ADC (ADC Noise Reduction mode) или режим холостого хода (Idle mode). ADC запустит преобразование, как только остановится ЦПУ.
- Если до завершения преобразования не возникает других прерываний, то по завершении преобразования прерывание ADC разбудит ЦПУ и программа перейдет на вектор обработки прерывания (прерывание завершения преобразования, ADC Conversion Complete). Если до завершения преобразования другое прерывание пробуждает микроконтроллер, то это прерывание обрабатывается, а по завершении преобразования генерируется соответствующий запрос на прерывание. ADC остается в активном режиме пока не будет выполнена очередная команда sleep.
Обратите внимание, что ADC не отключается автоматически при переводе во все другие режимы сна, кроме режима холостого хода (Idle mode) и режима снижения шумов ADC (ADC Noise Reduction mode). Поэтому пользователь должен предусмотреть запись лог. 0 в бит ADEN перед переводом в такие режимы сна, во избежание чрезмерного энергопотребления. Если работа ADC была разрешена в таких режимах сна и пользователь желает выполнить дифференциальное преобразование, то после пробуждения ADC нужно выключить, а затем включить для инициации расширенного преобразования, чем будет гарантировано получение действительного результата.
[Схема аналогового входа]
Схема аналогового входа для недифференциальных каналов представлена на рисунке 105. Независимо от того, какой канал подключен к ADC, аналоговый сигнал, подключенный к выв. ADCn, нагружается емкостью вывода и входным сопротивлением утечки. После подключения канала к ADC входной аналоговый сигнал будет связан с конденсатором выборки-хранения через последовательный резистор, сопротивление которого эквивалентно всей входной цепи.
ADC оптимизирован под аналоговые сигналы с выходным сопротивлением 10 кОм или меньше. Если используется такой источник сигнала, то время выборки незначительно. Если же используется источник с более высоким входным сопротивлением, то время выборки будет определяться временем, которое требуется для зарядки конденсатора выборки-хранения от источника аналогового сигнала. Рекомендуется использовать источники только с малым выходным сопротивлением и медленно изменяющимися сигналами, т.к. в этом случае будет достаточно быстрым заряд конденсатора выборки-хранения.
С каналами с дифференциальным усилением рекомендуется использовать сигналы с внутренним сопротивлением до нескольких сотен кОм.
Следует предусмотреть, чтобы в предварительных каскадах формирования аналогового сигнала ко входу ADC не вносились частоты выше fADC/2, в противном случае результат преобразования может быть некорректным (связано с условием Найквиста/Котельникова). Если вероятность проникновения высоких частот существует, то рекомендуется перед ADC установить фильтр низких частот.
Рисунок 105. Схема аналогового входа
[Рекомендации по снижению влияния шумов на результат преобразования]
Работа цифровых узлов внутри и снаружи микроконтроллера связана с генерацией электромагнитных излучений и шумов, которые могут негативно сказаться на точность измерения аналогового сигнала. Если точность преобразования является критическим параметром, то уровень шумов можно снизить, придерживаясь следующих рекомендаций:
- Выполняйте путь аналоговых сигналов как можно более коротким. Следите, чтобы аналоговые сигналы проходили над плоскостью (слоем) с аналоговой землей (экраном) и далеко от проводников, передающих высокоскоростные цифровые сигналы.
- Вывод AVCC необходимо связать с цифровым питанием VCC через LC-цепь в соответствии с рис. 106.
- Используйте функцию подавления шумов ADC (ADC noise canceler) для уменьшения шумов, внесенных работой ядра ЦПУ.
- Если какой-либо из выводов ADC используется как цифровой выход, то чрезвычайно важно не допустить переключение состояния этого выхода в процессе преобразования.
Рисунок 106. Подключение питания к ADC
[Схемы компенсации смещения]
Усилительный каскад имеет встроенную схему компенсации смещения (offset cancellation circuit), которая стремится максимально приблизить к нулю смещение дифференциального измерения. Оставшееся смещение можно измерить, если в качестве дифференциальных входов ADC выбрать один и тот же вывод микроконтроллера. Измеренное таким образом остаточное смещение можно программно вычесть из результата преобразования. Использование программного алгоритма коррекции смещения позволяет уменьшить смещение ниже одного мл. разр.
[Определения погрешности (точности) аналого-цифрового преобразования]
n-разрядный однополярный ADC преобразовывает напряжение линейно между GND и VREF с количеством шагов 2n (мл. разрядов). Минимальный код = 0, максимальный = 2n-1. Основные погрешности преобразования являются отклонением реальной функции преобразования от идеальной. К ним относятся:
Смещение – отклонение первого перехода (от кода 0x000 на код 0x001) по сравнению с идеальным переходом (т. е. при 0.5 мл. разр.). Идеальное значение: 0 мл. разр.
Рисунок 107. Погрешность смещения.
Погрешность усиления. После корректировки смещения погрешность усиления представляет собой отклонение последнего перехода (с 0x3FE на 0x3FF) от идеального перехода (т. е. отклонение при максимальном значении минус 1.5 мл. разр.). Идеальное значение: 0 мл. разр.
Рисунок 108. Погрешность усиления
Интегральная нелинейность (Integral Non-linearity, INL). После корректировки смещения и погрешности усиления INL представляет собой максимальное отклонение реальной функции преобразования от идеальной для любого кода. Идеальное значение ИНЛ = 0 мл. разр.
Рисунок 109. Интегральная нелинейность (ИНЛ)
Дифференциальная нелинейность (DNL). Максимальное отклонение между шириной фактического кода (интервал между двумя смежными переходами) от ширины идеального кода (1 мл. разр.). Идеальное значение: 0 мл. разр.
Рисунок 110. Дифференциальная нелинейность (DNL)
Погрешность квантования. Возникает из-за преобразования входного напряжения в конечное число кодов. Погрешность квантования — интервал входного напряжения протяженностью 1 мл. разр. (шаг квантования по напряжению), который характеризуется одним и тем же кодом. Всегда равен ±0.5 мл. разр.
Абсолютная погрешность. Максимальное отклонение реальной (без подстройки) функции преобразования от реальной при любом коде. Является результатом действия нескольких эффектов: смещение, погрешность усиления, дифференциальная погрешность, нелинейность и погрешность квантования. Идеальное значение: ±0.5 мл. разр.
[Результат преобразования ADC]
По завершении преобразования (ADIF = 1) результат может быть считан из пары регистров результата преобразования ADC (ADCL, ADCH). Для недифференциального преобразования:
где VIN – уровень напряжения на подключенном к ADC входе, VREF – напряжение выбранного источника опорного напряжения (см. табл. 83 и табл. 84). Код 0x000 соответствует уровню аналоговой земли, а 0x3FF — уровню напряжения ИОН минус 1 шаг квантования по напряжению.
При использовании дифференциального канала
Здесь VPOS напряжение на «плюсовом» дифференциальном входе, а VNEG – на «минусовом», GAIN – выбранный коэффициент усиления, VREF – напряжение выбранного источника опорного напряжения. Результат представляется в коде двоичного дополнения, начиная с 0x200 (-512d) до 0x1FF (+511d). Обратите внимание, что при необходимости быстро определить полярность результата достаточно опросить старший бит результата преобразования (ADC9 в ADCH). Если данный бит равен лог. 1, то результат отрицательный, если же лог. 0, то положительный. На рисунке 111 представлена функция преобразования ADC в дифференциальном режиме.
В таблице 82 представлены результирующие выходные коды для дифференциальной пары каналов (ADCn — ADCm) с коэффициентом усиления GAIN (Ку) и опорным напряжением VREF (VИОН).
Рисунок 111. Функция преобразования ADC при измерении дифференциального сигнала
Таблица 82. Связь между входным напряжением и выходными кодами
VADC, разница напряжений входов (VADCn — VADCm) |
считываемый код | соответствующее десятичное значение |
+ VREF / GAIN | 0x1FF | 511 |
+ (511/512) VREF / GAIN | 0x1FF | 511 |
+ (510/512) VREF / GAIN | 0x1FE | 510 |
… | … | … |
+ (1/512) VREF / GAIN | 0x001 | 1 |
0 | 0x000 | 0 |
— (1/512) VREF / GAIN | 0x3FF | -1 |
… | … | … |
— (511/512) VREF / GAIN | 0x201 | -511 |
– VREF / GAIN | 0x200 | -512 |
Пример: ADMUX = 0xED (дифференциальная пара входов ADC3 — ADC2, GAIN = 10, VREF =2.56В, результат с левосторонним выравниванием), напряжение на входе ADC3 = 300 мВ, а на входе ADC2 = 500 мВ, тогда:
ADCR = 512 * 10 * (300 — 500) / 2560 = -400 = 0x270
С учетом выбранного формата размещения результата (левосторонний) ADCL = 0x00, а ADCH = 0x9C. Если же выбран правосторонний формат (ADLAR=0), то ADCL = 0x70, ADCH = 0x02.
[Регистры ADC]
Интерфейс работы с ADC микроконтроллеров ATmega16 (ATmega32) чрезвычайно прост — нужно знать только 5 регистров — ADMUX, ADCSRA, ADCL, ADCH, SFIOR.
Разряд | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
REFS1 | REFS0 | ADLAR | MUX4 | MUX3 | MUX2 | MUX1 | MUX0 | ADMUX | |
Чтение/запись | R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W | |
Исх. значение | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Разряд 7:6 – REFS1:0: Биты выбора источника опорного напряжения
Данные биты определяют какое напряжение будет использоваться в качестве опорного для ADC (см. табл. 83). Если изменить значения данных бит в процессе преобразования, то новые установки вступят в силу только по завершении текущего преобразования (т. е. когда установится бит ADIF в регистре ADCSRA). Внутренний ИОН можно не использовать, если к выводу AREF подключен внешний опорный источник.
Таблица 83. Выбор опорного источника ADC
REFS1 | REFS0 | Источник опорного напряжения ADC |
0 | 0 | Внешний источник, подключенный к AREF, внутренний VREF отключен |
0 | 1 | AVCC с внешним конденсатором на выводе AREF |
1 | 0 | Зарезервировано |
1 | 1 | Внутренний источник опорного напряжения 2.56В с внешним конденсатором на выводе AREF |
Разряд 5 – ADLAR: Бит управления представлением результата преобразования
Бит ADLAR влияет на представление результата преобразования в паре регистров результата преобразования ADC. Если ADLAR = 1, то результат преобразования будет иметь левосторонний формат, в противном случае — правосторонний. Действие бита ADLAR вступает в силу сразу после изменения, независимо от выполняющегося параллельно преобразования. Полное описание действия данного бита представлено во врезке «Регистры данных ADC: ADCL и ADCH».
Разряды 4:0 – MUX4:0: Биты выбора аналогового канала и коэффициента усиления
Данные биты определяют какие из имеющихся аналоговых входов подключаются к ADC. Кроме того, с их помощью можно выбрать коэффициент усиления для дифференциальных каналов (см. табл. 84). Если значения бит изменить в процессе преобразования, то новые установки вступят в силу только после завершения текущего преобразования (после установки бита ADIF в регистре ADCSRA).
Таблица 84. Выбор входного канала и коэффициента усиления
MUX4..0 | Недифференциальный вход | Неинвертирующий дифференциальный вход | Инвертирующий дифференциальный вход | Коэффициент усиления, GAIN (Ку) |
00000 | ADC0 | Дифференциальных входов и усиления нет | ||
00001 | ADC1 | |||
00010 | ADC2 | |||
00011 | ADC3 | |||
00100 | ADC4 | |||
00101 | ADC5 | |||
00110 | ADC6 | |||
00111 | ADC7 | |||
01000 | Недифференциальных входов нет | ADC0 | ADC0 | 10x |
01001 | ADC1 | ADC0 | 10x | |
01010(1) | ADC0 | ADC0 | 200x | |
01011(1) | ADC1 | ADC0 | 200x | |
01100 | ADC2 | ADC2 | 10x | |
01101 | ADC3 | ADC2 | 10x | |
01110(1) | ADC2 | ADC2 | 200x | |
01111(1) | ADC3 | ADC2 | 200x | |
10000 | ADC0 | ADC1 | 1x | |
10001 | ADC1 | ADC1 | 1x | |
10010 | ADC2 | ADC1 | 1x | |
10011 | ADC3 | ADC1 | 1x | |
10100 | ADC4 | ADC1 | 1x | |
10101 | ADC5 | ADC1 | 1x | |
10110 | ADC6 | ADC1 | 1x | |
10111 | ADC7 | ADC1 | 1x | |
11000 | ADC0 | ADC2 | 1x | |
11001 | ADC1 | ADC2 | 1x | |
11010 | ADC2 | ADC2 | 1x | |
11011 | ADC3 | ADC2 | 1x | |
11100 | ADC4 | ADC2 | 1x | |
11101 | ADC5 | ADC2 | 1x | |
11110 | 1.22 В (VBG) | Дифференциальных входов и усиления нет | ||
11111 | 0 В (GND) |
Примечание: 1. Дифференциальные каналы не тестировались для микроконтроллеров в корпусе PDIP40. Работа в таком режиме гарантируется только для микроконтроллеров в корпусах TQFP и QFN/MLF.
Разряд | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
ADEN | ADSC | ADFR | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 | ADCSRA | |
Чтение/запись | R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W | |
Исх. значение | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Разряд 7 – ADEN: Разрешение работы ADC
Запись в данный бит лог. 1 разрешает работу ADC. Если в данный бит записать лог. 0, то ADC отключается, даже если он находился в процессе преобразования.
Разряд 6 – ADSC: Запуск преобразования ADC
В режиме одиночного преобразования установка данного бита инициирует старт каждого преобразования. В режиме автоматического перезапуска установкой этого бита инициируется только первое преобразование, а все остальные выполняются автоматически. Первое преобразование после разрешения работы ADC, инициированное битом ADSC (или если в ADSC записали 1 одновременно с разрешением работы ADC), выполняется за 25 тактов синхронизации ADC, вместо обычных 13 тактов. Это связано с необходимостью инициализации ADC при первом преобразовании.
В процессе преобразования при опросе бита ADSC возвращается лог. 1, а по завершении преобразования – лог. 0. Запись лог. 0 в данный бит возможно, но не оказывает никакого действия.
Разряд 5 – ADATE: Включение режима автоматического запуска ADC
Если в данный бит записать лог. 1, то ADC перейдет в режим автоматического перезапуска. В этом режиме ADC автоматически запускает преобразование по положительному фронту выбранного запускающего сигнала. Выбор источника запуска происходит битами ADTS регистра SFIOR.
Разряд 4 – ADIF: Флаг прерывания ADC
Данный флаг устанавливается после завершения преобразования ADC и обновления регистров выходных данных (ADCH:ADCL). Если установлены биты ADIE и I (регистр SREG), то происходит вызов обработчика прерывания по завершении преобразования. Флаг ADIF сбрасывается аппаратно при переходе на соответствующий вектор прерывания. Альтернативно флаг ADIF сбрасывается путем записи лог. 1 в него. Обратите внимание, что при выполнении команды «чтение-модификация-запись» с регистром ADCSRA ожидаемое прерывание может быть запрещено. Сказанное также действительно, если используются инструкции SBI и CBI.
Разряд 3 – ADIE: Разрешение прерывания ADC
Когда этот бит установлен в лог. 1, и установлен бит I в регистре SREG, разрешается прерывание по завершении преобразования ADC.
Разряды 2:0 – ADPS2:0: Биты управления предделителем ADC
Данные биты определяют на какое значение тактовая частота ЦПУ будет отличаться от частоты входной синхронизации ADC.
Таблица 85. Управление предделителем (прескалером) ADC
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 |
ADLAR = 0:
Разряд | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | |
— | — | — | — | — | — | ADC9 | ADC8 | ADCH | |
ADC7 | ADC6 | ADC5 | ADC4 | ADC3 | ADC2 | ADC1 | ADC0 | ADCL | |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
Чтение/запись | R | R | R | R | R | R | R | R | |
R | R | R | R | R | R | R | R | ||
Исх. значение | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
ADLAR = 1:
Разряд | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | |
ADC9 | ADC8 | ADC7 | ADC6 | ADC5 | ADC4 | ADC3 | ADC2 | ADCH | |
ADC1 | ADC0 | — | — | — | — | — | — | ADCL | |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
Чтение/запись | R | R | R | R | R | R | R | R | |
R | R | R | R | R | R | R | R | ||
Исх. значение | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
По завершении преобразования результат помещается в этих двух регистрах. При использовании дифференциального режима преобразования результат представляется в коде двоичного дополнения.
Если выполнено чтение ADCL, то доступ к этим регистрам для ADC будет заблокирован (т. е. ADC не сможет в дальнейшем модифицировать результат преобразования), пока не будет считан регистр ADCH.
Формат представления результата (левостороннее выравнивание или правостороннее выравнивание) зависит от состояния бита ADLAR и от состояния битов MUXn в регистре ADMUX. Левосторонний формат представления результата удобно использовать, если достаточно 8 разрядов. В этом случае 8-разрядный результат хранится в регистре ADCH и, следовательно, чтение регистра ADCL можно не выполнять. При правостороннем формате необходимо сначала считать ADCL, а затем ADCH.
ADC9:0: Результат преобразования ADC
Данные биты представляют результат преобразования. Подробнее см. раздел «Результат преобразования ADC».
Разряд | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
ADTS2 | ADTS1 | ADTS0 | — | ACME | PUD | PSR2 | PSR10 | SFIOR | |
Чтение/запись | R/W | R/W | R/W | R | R/W | R/W | R/W | R/W | |
Исх. значение | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Разряды 7:5 – ADTS2:0: Биты выбора источника автоматического запуска ADC
Если ADATE в регистре ADCSRA записан в лог. 1, значения бит ADTS определяют, какой будет использоваться источник для запуска преобразования. Если ADATE в регистре ADCSRA записан в лог. 0, значения бит ADTS никакого значения не имеют. Преобразование будет запускаться по положительному фронту (нарастание сигнала) выбранного сигнала. Внимание – событие переключения от очищенного источника запуска к источнику запуска, который установлен, будет генерировать положительный фронт сигнала запуска, и если бит ADEN в регистре ADCSRA установлен, то запустится преобразование. Переключение в режим постоянного преобразования (Free Running mode, ADTS[2:0]=0) не генерирует событие запуска, даже если установлен флаг прерывания ADC (ADC Interrupt Flag).
ADTS2 | ADTS1 | ADTS0 | Источник запуска преобразования ADC |
0 | 0 | 0 | Постоянное преобразование (Free Running mode) |
0 | 0 | 1 | Аналоговый компаратор |
0 | 1 | 0 | Внешний запрос на прерывание 0 |
0 | 1 | 1 | Timer/Counter0 Compare Match |
1 | 0 | 0 | Timer/Counter0 Overflow |
1 | 0 | 1 | Timer/Counter1 Compare Match B |
1 | 1 | 0 | Timer/Counter1 Overflow |
1 | 1 | 1 | Timer/Counter1 Capture Event |
Разряд 4 – Res: Зарезервированный бит
Этот бит зарезервирован для использования в будущем. Для обеспечения совместимости с микроконтроллерами, которые будут разработаны в будущем, при записи в регистр SFIOR этот бит должен быть установлен в лог. 0.
[Устранение проблем, FAQ]
Q001. Мне нужно, чтобы ADC выполнял преобразование максимально быстро. Почему когда я устанавливаю маленькое значение делителя битами ADPS2..0 (ADPS2:ADPS0=000 или ADPS2:ADPS0=001), то ADC у меня не работает?
A001. ADC имеет минимально допустимое время преобразования, поэтому если у Вас рабочая частота ядра CPU слишком большая (16 МГц и выше), то при маленьких коэффициентах деления прескалера тактовая частота для ADC может оказаться слишком высокой. Поэтому просто подберите минимальное значение делителя, при котором ADC начинает работать. Например, у меня с ATmega32A рабочее значение делителя оказалось не меньше 4 (ADPS2:ADPS0=010).
[Ссылки]
1. Содержимое этой статьи в формате doc.
2. Автомат управления освещением ledlight — рабочий проект AVR Studio как пример работы с ADC.
3. AVR-USB-MEGA16: замена GC7137AD (ICL7137) на ATmega32 и OP291.
Наибольшая частота входного сигнала АЦП для atmega8?
Что такое часы АЦП?
Раздел, который вы видите, относится к часам, используемым для АЦП. Эти часы не имеют прямого отношения к максимальной частоте дискретизации. Часы — это то, что на самом деле подается на модуль АЦП, который должен быть быстрее, чем ваша выборка, чтобы он мог справиться с вашей магией .
Как часы Max соотносятся с максимальной частотой дискретизации?
Данные таблицы говорят о том, что для получения 10-битного разрешения ваши тактовые частоты не могут быть выше 200 кГц. Когда ваши часы будут на такой скорости, вы сможете сэмплировать ваш сигнал со скоростью 15 000 сэмплов в секунду.
Если вам не нужны все 10-битные разрешения, вы можете обеспечить АЦП более быстрым тактовым сигналом, и вы получите более высокую частоту дискретизации, но в таблице не ясно, как быстро вы можете идти и при этом получить 8-битное разрешение.
Я бы предположил, что отношение тактовой частоты к частоте дискретизации является фиксированным, поэтому 200K / 15K = 13,33, что означает, что вы можете перейти на тактовую частоту 50 кГц, что приведет к 3,75 кПс.
Почему минимальные часы, чтобы получить 10-битный образец?
Модуль АЦП выполняет выборку и удержание, в котором напряжение по существу удерживается в конденсаторе. Если вы слишком сильно замедляете тактовую частоту, напряжение может начать стравливаться из конденсатора, прежде чем будет выполнена полная выборка. Это изменение напряжения делает его таким, что вы не можете получить все 10 бит точно.
Итак, что же все это значит?
Согласно теореме отсчетов Найквиста-Шеннона ваша частота дискретизации должна быть как минимум вдвое больше максимальной частоты вашего сигнала. Вы можете узнать больше о том, почему, взглянув на этот вопрос: озадачен частотой Найквиста
Таким образом, чтобы получить разрешение 10 бит, максимальный ваш сигнал может быть 7,5 кГц, но если вам нужно сэмплировать сигнал быстрее, вы можете это сделать, но в техническом описании не указано, как высоко вы можете подняться или как много вредит твоему решению.
Сопряжение АЦП с микроконтроллерами AVR
Микроконтроллеры AVR семейств tiny и mega имеют встроенные десятиразрядные аналого-цифровые преобразователи, что в целом очень удобно для создания различных измерительных устройств на основе микроконтроллеров. Но нередко требуется выполнять аналого-цифровое преобразование с более высокой разрядностью, точностью или скоростью. Для этого нужно подключить к микроконтроллеру внешний АЦП с соответствующими параметрами. В статье приведены примеры сопряжения трёх различных АЦП с микроконтроллером ATmega8.
Для экспериментов с различными внешними АЦП был изготовлен по схеме, изображённой на рис. 1, модуль, содержащий микроконтроллер ATmega8L-8PI и буквенно-цифровой ЖКИ MT-10S1, позволяющий отобразить на своём экране строку из десяти символов. К этому модулю подключались для исследования различные микросхемы АЦП, для работы с каждой из которых в программную память микроконтроллера загружалась специально разработанная демонстрационная программа, превращающая устройство в простой цифровой милливольтметр постоянного тока.
Рис. 1. Схема устройства
Схема подключения к микроконтроллерному модулю 12-разрядного АЦП AD7896AN [1] показана на рис. 2. Особенность этого АЦП — использование напряжения питания в качестве образцового. Поэтому здесь он питается от параллельного стабилизатора на микросхеме TL431. При напряжении питания 4,096 В цена младшего разряда выходного кода АЦП равна 1 мВ.
Рис. 2. Схема подключения к микроконтроллерному модулю 12-разрядного АЦП AD7896AN
Точное значение напряжения питания устанавливают подстроечным резистором R1. Результат преобразования поступает в микроконтроллер по последовательному интерфейсу, образованному линиями PB5 (SCK) и PB4 (MISO). Микроконтроллер подаёт АЦП команду запуска преобразования по линии PB0 и принимает сигнал о его завершении по линии PB1.
Демонстрационная программа Vmeter_AD7896 запускает АЦП и выводит полученный результат в виде десятичного числа на ЖКИ HG1 микроконтроллерного модуля. Для исключения миганий индикатора предусмотрена секундная задержка между измерениями. Последовательный интерфейс реализован программно, поскольку обнаружилось, что принятые от АЦП аппаратным модулем SPI микроконтроллера данные некорректны — результат измерения удвоен. Причина этого ещё подлежит выяснению.
Схема подключения к микроконтроллерному модулю 12-разрядного АЦП MCP3201 [2] показана на рис. 3. Он имеет дифференциальный вход преобразуемого напряжения, что не исключает возможности работы в однополярном режиме при соединении входа IN- с общим проводом.
Рис. 3. Схема подключения к микроконтроллерному модулю 12-разрядного АЦП MCP3201
Этому АЦП требуется отдельный источник образцового напряжения, которым в рассматриваемом случае служит микросхема REF3030 с типовым значением выходного напряжения 3 В. Более удобным было бы применить аналогичную микросхему REF3040, дающую образцовое напряжение 4,096 В, как в предыдущем случае, но найти такую микросхему не удалось.
Если перемычка S1 установлена в положение 2-3, входное напряжение поступает на вход АЦП напрямую с Входа 1. Когда она в положении 1 -2, напряжение на вход АЦП проходит с Входа 2 через ФНЧ с частотой среза 10 Гци коэффициентом передачи 1 на ОУ DA1. Устанавливать на входе АЦП фильтр или повторитель напряжения на ОУ рекомендуется, если источник сигнала «шумит» или имеет высокое выходное сопротивление.
Передача информации из АЦП в микроконтроллер организована по последовательному интерфейсу, использующему линии PB5 (SCK), PB4 (MISO) и PB2 (CS). Низкий уровень сигнала CS, устанавливаемый микроконтроллером, разрешает АЦП приём и передачу информации по последовательному интерфейсу.
Демонстрационная программа Vmeter_MCP3201 запускает преобразование, вычисляет значение входного напряжения в вольтах и выводит полученный результат на ЖКИ микроконтроллерного модуля.
Для исключения мелькания изображения предусмотрена секундная задержка между измерениями. Для связи с АЦП программа использует аппаратный модуль SPI микроконтроллера.
В программе учтено, что для получения от АЦП MCP3201 правильного результата преобразования два старших разряда его старшего байта необходимо обнулить, а затем сдвинуть весь двухбайтовый результат на один разряд вправо.
При образцовом напряжении 3 В цена младшего разряда результата преобразования 3/4096 » 0,7324 мВ. Чтобы для получения результата в милливольтах использовать только целочисленные вычисления, программа умножает принятый от АЦП код на в 10000 раз большее число 7324, а затем делит произведение на 10000. Целая часть частного выводится на ЖКИ с незначащими нулями, причём десятичная запятая устанавливается после разряда целых вольт.
Наиболее просто подключить к микроконтроллерному модулю 16-разрядный АЦП ADS1110 [3]. Для этого требуются всего два резистора, два конденсатора и две линии ввода/вывода микроконтроллера. Схема подключения показана на рис. 4. АЦП имеет интерфейс I2C, аппаратный адаптер которого имеется в большинстве микроконтроллеров. Адрес ведомого АЦП ADS1110 на шине I2C зашифрован в нанесённой на корпус микросхемы маркировке. Всего возможны восемь вариантов: ED0 — 1001000, ED1 — 1001001… ED7 — 1001111. Если в разрабатываемом устройстве предполагается использовать несколько таких АЦП, нужно выбирать их с разными адресами ведомого.
Рис. 4. Схема подключения
Интервал допустимого синфазного входного напряжения у этого АЦП — 0…2,048 В, дифференциального входного напряжения — от -2,048 до +2,048 В. При этом потенциал каждого входа должен быть положительным или нулевым относительно общего провода.
В АЦП ADS1110 имеется конфигурационный регистр, в котором значениями двух младших разрядов PGA0 и PGA1 устанавливают коэффициент усиления встроенного усилителя, следующими двумя разрядами DR0 и DR1 задают скорость преобразования и передачи информации. Однако с увеличением скорости преобразования уменьшается его разрядность. В прилагаемой демонстрационной программе Vmeter_ ADS1110 оставлены заводские установки: 16 разрядов, 15 выборок в секунду (DR0=1, DR1 = 1).
Следующий разряд SC позволяет выбрать режим преобразования: 1 — однократное, 0 — непрерывное (по умолчанию). Ещё два разряда не используются, а старший разряд ST/DRDY в программе оставлен без изменения.
В самом начале своей работы программа Vmeter_ADS1110 настраивает АЦП, записывая нужные значения в разряды его конфигурационного регистра. В основном цикле она запускает аналого-цифровое преобразование, вычисляет измеренное напряжение и отображает результат на ЖКИ микроконтроллерного модуля, повторяя эти операции каждую секунду.
Подпрограмма вычисления напряжения аналогична рассмотренной выше для АЦП MCP3201. Но поскольку цена младшего разряда АЦП ADS1110 равна 62,5 мкВ, результат преобразования программа умножает на 625 и делит на 1000. Измеренное значение напряжения выводится на экран со знаком плюс или минус и с точностью до десятых долей милливольта. Но верными можно считать только четыре старшие десятичные цифры результата, поскольку именно с такой точностью задана цена младшего двоичного разряда кода АЦП.
Измерения можно проводить в однополярном режиме, подавая измеряемое положительное напряжение на Вход+ или Вход-, а неиспользуемый вход — соединив с общим проводом. Если напряжение подано на Вход-, результат работы АЦП будет отрицательным числом, представленным дополнительным кодом. Программа распознаёт его по единице в старшем разряде старшего байта и для дальнейших вычислений инвертирует. Аналогично работает программа в дифференциальном режиме измерения. В этом случае результат преобразования получается отрицательным, когда напряжение на Входе- больше, чем на Входе+. Знаки плюс или минус на экране ЖКИ информируют о том, на какой вход подано измеряемое напряжение, или о том, на каком входе оно больше.
Программы микроконтроллера имеются здесь.
Литература
1. AD7896 2.7V to 5.5V, 12-Bit, 8 ms ADC in 8-Pin SO/DIP. — URL: https://lib.chipdip.ru/ 143/DOC000143743.pdf (29.05.17).
2. MCP3201 2.7V 12-Bit A/D Converter with SPI Serial Interface. — URL: https://lib. chipdip.ru/2 51 /DOC000251218.pdf (29.05.17).
3. ADS1110 16-Bit Analog-to-Digital Converter with Onboard Reference. — URL: http:// www.farnell.com/datasheets/1863612.pdf (29.05.17).
Автор: Н. Салимов, г. Ревда Свердловской обл.
Масштабируем сигнал для АЦП — DiMoon Electronics
Аналогово-цифровой преобразователь, или АЦП, служит для преобразования аналогового сигнала в цифровой код, который далее может обрабатываться микроконтроллером, компьютером или другой цифровой вычислительной машиной.10 — 1 = 1023. При опорном напряжении 2.5 вольт, результат преобразования будет следующим:
- на входе 0 вольт -> код на выходе 0
- на входе 1.25 вольт -> код на выходе 511
- на входе 2.5 вольт -> код на выходе 1023
- на входе 2.51 вольт -> код на выходе 1023
- на входе 3.0 вольт -> код на выходе 1023
Вот!!! Обратите внимание на последние 2 строчки: напряжение на входе увеличиваем, а код не меняется. Все, уперлись в рельсу (англ. rail — рейка, перекладина, ограда). Вот это и есть выход за динамический диапазон. А сам динамический диапазон лежит в пределах 0..2.5 вольт.
А что делать, когда надо измерять напряжения, например, от 0 до 3.5 вольт?
Можно увеличить опору АЦП до 4-х вольт, и тогда максимальному значению 1023 будет соответствовать уже 4 вольта, а не 2,5. И у нас остается еще небольшой запас в пределах динамического диапазона.
А если надо мерить до 10-и вольт? Опору в 10 вольт поставить не получится. Согласно datasheet-у на мегу8, напряжение опоры может быть в пределах от 2 вольт и до напряжения питания аналоговой части контроллера AVcc, а AVcc примерно равно напряжению питания цифровой части Vcc.
Рис. 1. Диапазон напряжений опоры и питания аналоговой части микроконтроллера.
Вот и получается, что при питании МК от 5-и вольт, сигнал опорного напряжения может быть в пределах от 2v до 5v.
Выйти из ситуации можно довольно просто: в качестве опоры выбрать всё те же 2.5 вольт, а на аналоговый вход АЦП подавать сигнал через делитель на 4:
Рис. 2. Схема масштабирования сигнала на резисторах.
Результат будет следующий:
- Uin = 0.0v: ADC_DATA = 0
- Uin = 2.5v: ADC_DATA = 255
- Uin = 5.0v: ADC_DATA = 511
- Uin = 7.5v: ADC_DATA = 767
- Uin = 10.0v: ADC_DATA = 1023
Отлично! Теперь мы можем мерить напряжения от 0 до 10 вольт. Изменив нужным образом коэффициент деления резистивного делителя можно скорректировать диапазон измеряемых напряжений.
Бывают случаи, когда нам нужно получить высокое входное сопротивление аналогового входа Uin, порядка нескольких МегаОм. А в нашем случае (рис. 2) входное сопротивление всего 50 ком. Решить проблему крайне просто: перед делителем на R1 и R2 поставить повторитель на операционном усилителе:
Рис. 3. Схема масштабирования с высоким входным сопротивлением.
У современных ОУ сопротивление входа запросто может быть несколько десятков мегаом, а у лучших образцах и того больше — Гигаомы. Тут следует помнить об одной вещи: если мы хотим на Uin измерять напряжения от 0 до 10 вольт, то питание операционного усилителя должно быть соответствующим: для так называемых Rail-to-Rail ОУ напряжение питания должно быть равно 10 вольт, или немного больше.
Если использовать «обычный» операционник, то надо помнить, что ему на вход нельзя подавать напряжение, равное напряжению питания. Для очень популярного LM358 необходимо «отступить» от напряжений питания целых 2 вольта. Т.е. для нашего случая, чтоб ОУ не уходил в насыщение при подачи на Uin 10 вольт (относительно земли), на «плюс» питания ОУ надо подать минимум +12 вольт. То же самое и при Uin=0 вольт: на «минус» питания подаем -2 вольта относительно земли. Если с +12-ю вольтами особых проблем и не возникает, то с -2 вольтами придется повозиться: или использовать трансформатор с двумя вторичными обмотками, или какой-то DC-DC преобразователь ставить, геморрой лишний короче. А в результате у нас получится мега-сложная схема, которая делает мега-простую вещь. Поэтому использование Rail-to-Rail операционников в некоторых схемах очень даже к стати)))
Так, вроде все круто и замечательно, но только до тех пор, пока нам не нужно мерить отрицательные напряжения. А если нужно? Например, от -10 до +10 вольт. Решение есть!!!
Конечно, можно найти специальные микросхемы АЦП, которые могут работать с отрицательными напряжениями. Тогда всю входную схему можно свести рис. 3. Однако, во всеми любимыми AVR-ках АЦП не может измерять отрицательные относительно земли напряжения. Более того, если на любой вход микроконтроллера, в том числе и аналоговый, подать напряжение, меньше -0.5 вольта, то «спасибо» он за такое уж точно не скажет (смотри таблицу Absolute Maximum Ratings в даташите на МК).
Пусть Uin — это то напряжение, которое надо измерить, adc_in — напряжение, которое подается на вход АЦП после некой преобразующей схемы, опора у нас будет 2.5 вольт. Тогда нам надо сделать такую схему, которая реализует следующее:
- При Uin = +10v -> adc_in=2.25v
- При Uin = -10v -> adc_in=0.25v
- При Uin = 0v -> adc_in=1.25v
Т.е. нам нужно вогнать диапазон -10..+10 вольт в 0.25..2.25, причем при напряжении на входе, равном нулю, на АЦП подается половина напряжения опоры.
По-началу, задача может казаться сложной, но на самом деле все реализуется на одном операционнике и пяти резисторах!
Давайте вспомним схему неинвертирующего сумматора на ОУ:
Рис. 4. Неинвертирующий сумматор на ОУ.
А теперь давайте посмотрим на схему, решающую нашу задачу:
Рис. 5. Схема из шести деталей))
По сути это самый обыкновенный сумматор с двумя входами с разными коэффициентами подмешивания для каждого из входов. На первый вход подается напряжение опоры, коэффициент суммирования у которого 0.5. Второй вход измерительный, его коэффициент в нашем случае 0.1. Вот и получается, что напряжение на выходе равно adc_in=(0.5*2.5) + (0.1*Uin):
- (0.5*2.5) + (0.1*10) = 2.25v выходе при входном напряжении Uin равном +10v;
- (0.5*2.5) + (0.1*0) = 1.25v при Uin=0v;
- (0.5*2.5) + (0.1*(-10)) = 0.25v при минимально возможном напряжении на входе Uin=-10 вольт.
Надеюсь, это понятно))
Update 24.05.2019: подробности см. тут:)) http://dimoon.ru/spravochnik/ou/shemy-na-ou-drajver-aczp.html
А работает все это вот так:
Рис. 6. Осциллограмма входного и выходного сигналов
На рис. 6 представлен результат симуляции нашей схемы в isis Proteus. Красный график — сигнал на входе, зеленый — на выходе. Протеус классная вещь все-таки))
Есть тут один момент, на который следует обратить внимание. Для корректной работы Rail-to-Rail операционника его напряжение питания должно быть больше или равно максимально возможному напряжению на его входах и выходе.
Давайте разбираться, какие напряжения у нас гуляют по схеме.
Выход ОУ фактически является сигналом adc_in, и тут должно быть напряжение от 0.25 до 2.25 вольт. Так, один диапазон установили. На отрицательный вход ОУ напряжение через делитель на R1, R2 подается с выхода ОУ, поэтому тут не может быть потенциал больше 2.25 вольт.
А как дела обстоят с положительным входом? Чтобы не впадать в математические расчеты, можно прямо в Proteus-e измерить напряжение на этом входе при изменении Uin в пределах -10..+10 вольт.
Рис. 7. Точка измерения напряжения U1_+
Результат радует:
Рис. 8. Результат измерения на положительном входе ОУ
Напряжение на положительном входе ОУ колеблется в диапазоне 0.25..2.05 вольт. Можно заключить, что для корректной работы схемы на рис. 5 требуется Rail-to-Rail ОУ с однополярным питанием от 2.25 и более вольт. Надо лишь обратить внимание на то, что не стоит его поднимать выше напряжения питания МК, чтоб в случае нештатного режима работы схемы исключить попадание на аналоговый вход микроконтроллера слишком большого потенциала.
При необходимости, можно перестроить входной диапазон напряжений до нужного значения, подобрав правильным образом номиналы резисторов в схеме. Более того, эта схема может работать не только как аттенюатор (ослабитель сигнала), но и как усилитель!!! Чем меньше величина резистора R3, тем меньше диапазон входных напряжений, и наоборот. Если R3 выбрать равным 1 ком (и R2 поставить тоже 1 ком, почему так, см. далее) то диапазон входных напряжений уже будет не ±10 вольт, а ±0.1 вольт, а на выходе сигнал будет меняться в тех же пределах, что и в предыдущем случае:
Рис. 9. Схема с перестроенным входным диапазоном. Красный — Uin, зеленый — adc_in
При перенастройки схемы нужно выполнять следующие правила относительно номиналов резисторов :
- R4=R5
- R1 = R4/2=R5/2
- R2=R3
При выполнении этих трех условий схема будет работать правильно в широком диапазоне (в пределах разумного, конечно)) ) значений резисторов.
Есть и готовые микросхемы, выполняющие данные функции, например, INA159. Вот тут на него есть обзор. Но готовые решения не всегда удовлетворяют всем требованиям, и нет возможности тонкой настройки схемы под себя))
Драйвер АЦП, про который я рассказал, хорошо зарекомендовал себя в одной довольно сложной и высокоточной конструкции, поэтому при необходимости буду его пихать везде, где только можно))
Так, на этом, пожалуй, закончу)) Получилось довольно много текста, и на мой взгляд некоторые места слишком занудные. Перечитаю пару раз, может что где поправлю. Всем пока)))
P.S. Кое-что поправил.
P.P.S. 24.05.2019: Уже не помню, каким из пальцев левой ноги я писал эту статью, но в комментах правильно подметили, что коэффициенты суммирования схемы на рис. 5 равны 0.5 и 0.1, а не 0.5 и 0.125. Поправил)))
AVR ADC Аналого-цифровое преобразование
Знаете ли вы? «Реальный» мир, в котором мы живем, — Аналоговый! Будь то звук, свет, температура или влажность — все они постоянно меняются. Однако, когда мы хотим общаться с «цифровым» миром, крайне важно использовать цифровые значения, которые могут быть легко распознаны компьютерными системами. Вычислительная система понимает это, преобразовывая их в двоичные числа.
Итак, для передачи внешней непрерывной информации (аналоговой информации) в цифровую / вычислительную систему мы должны преобразовать их в целые (цифровые) значения.Этот тип преобразования выполняется аналого-цифровым преобразователем (АЦП). Процесс преобразования аналогового значения в цифровое значение известен как аналого-цифровое преобразование. Короче говоря, аналоговые сигналы — это сигналы реального мира вокруг нас, такие как звук и свет.
Цифровые сигналы — это аналоговые эквиваленты в цифровом или числовом формате, которые хорошо понимаются цифровыми системами, такими как микроконтроллеры. АЦП — одно из таких аппаратных средств, которое измеряет аналоговые сигналы и выдает цифровой эквивалент того же сигнала.Микроконтроллеры AVR имеют встроенное средство АЦП для преобразования аналогового напряжения в целое число. AVR преобразует его в 10-битное число от 0 до 1023.
Обратите внимание, что у нас также есть аналоговое опорное напряжение (Aref), которое будет считаться эквивалентным 1023, и любое значение напряжения меньше этого Aref будет иметь меньшее число, чем 1023. Диапазон ввода — 0-Aref, а цифровой выход — 0-1023. . Здесь 0V будет равно 0, а Aref / 2 будет равно 512 и так далее.
АЦП в Atmega8
Теперь у вас есть основы АЦП, давайте перейдем к встроенному АЦП микроконтроллеров AVR.Прежде всего, обратите внимание, что АЦП мультиплексирован с портом C, и он может работать в режиме одиночного преобразования и в режиме автономной работы. В режиме одиночного преобразования АЦП выполняет одиночное преобразование и останавливается. Но в режиме автономной работы АЦП непрерывно преобразует, то есть выполняет преобразование, а затем сразу же после этого начинает следующее преобразование. Вот несколько концепций относительно Atmega8, о которых следует знать заранее:
- Предварительное деление частоты АЦП: для работы АЦП необходим тактовый импульс, и для этого системные часы делятся на число (2, 4, 16, 32, 64 и 128), чтобы получить меньшую частоту (для АЦП требуется частота в диапазоне 50 кГц. до 200 кГц)
- Каналы АЦП: АЦП в пакете Atmega8 PDIP имеет 6 каналов, позволяет брать образцы с 6 разных контактов
- Регистры АЦП: Регистр обеспечивает связь между ЦП и АЦП.Вы можете настроить АЦП в соответствии с вашими потребностями, используя эти регистры. У АЦП всего 3 регистра:
- Регистр выбора мультиплексора АЦП — ADMUX: для выбора опорного напряжения и входного канала
- Регистр управления и состояния ADC A — ADCSRA: он имеет статус ADC и также используется для управления им.
- Регистр данных АЦП — ADCL и ADCH: здесь сохраняется окончательный результат преобразования.
- AVCC: этот вывод подает питание на АЦП. AVCC не должен отличаться более чем на ± 0.3 В от Vcc
- AREF: Еще один вывод, который можно использовать как внешний опорный вывод напряжения.
- Разрешение по напряжению: это наименьшее приращение напряжения, которое можно измерить. Для 10-битного АЦП может быть 1024 различных напряжения (для 8-битного АЦП может быть 256 различных напряжений)
В принципе, АЦП в микроконтроллерах AVR использует метод, известный как последовательное приближение, путем сравнения входного напряжения с половиной опорного напряжения, генерируемого внутри.Сравнение продолжается дальнейшим делением напряжения и обновлением каждого бита в регистре АЦП на 1, если входное напряжение высокое, и на 0 в противном случае. Этот процесс длится 10 раз (для 10-битного АЦП) и генерирует результирующий двоичный выходной сигнал.
Небольшой перерыв в скучной теории! Давайте запустим простую тестовую программу, чтобы увидеть наш АЦП в действии. В этом примере Atmega8 считывает потенциометр 10K, подключенный к PORT C, и включает (или выключает) светодиоды, подключенные к PORT D. Здесь АЦП используется в режиме одиночного преобразования с точностью до 10 бит.Подключите оборудование, как показано, и подайте код на Atmega8. Когда работа закончена, медленно поверните потенциометр 10K и проверьте результат. В соответствии с кодировкой, если значение меньше 512, тогда должен быть включен LED1 (на PD6), иначе LED2 (на PD7).
(Сейчас подходящее время снова взять таблицу данных Atmega8, чтобы перейти к главе АЦП. Просто откройте главу АЦП и внимательно прочтите описание каждого регистра, а также все о схемах АЦП)
#включают #define PORT_ON (порт, контакт) порт | = (1→ Часть 14: AVR и UART
← Часть 12: ШИМ-широтно-импульсная модуляция AVR
Добро пожаловать в AVRbeginners.сеть!
Добро пожаловать на AVRbeginners.net!ATmega8 ADC Пример
Это очень простой пример, который вы, вероятно, не встретите ни в каком серьезном проекте, но он прост и несложен для устранения неполадок. Мы хотим прочитать выходное напряжение потенциометра и показать 8 старших разрядов результата преобразования на порте D (разрешение АЦП составляет 10 бит!).
Выбор режима АЦП и тактовой частоты
АЦП mega8 предлагает 2 режима работы: режим одиночного преобразования и режим автономной работы.У обоих есть свои преимущества и недостатки, и я постараюсь обсудить их оба достаточно подробно.
В автономном режиме новое преобразование запускается после его завершения. Новое преобразование выполняется для канала АЦП, установленного в ADMUX. Если необходимо преобразовать новый канал, его номер должен быть установлен * до * начала нового преобразования. Если для обработки результатов АЦП и обновления ADMUX используется ISR, следует соблюдать осторожность, так как изменение ADMUX сразу после начала преобразования может иметь непредсказуемые результаты (подробнее см. На страницах 196/197 таблицы данных mega8).Поскольку мы хотим работать только с одним каналом АЦП, для нас это не проблема. Только самое первое преобразование должно быть запущено установкой бита ADSC!
В режиме одиночного преобразования каждое преобразование должно запускаться установкой бита ADSC (ADC Start Conversion) в ADCSR. Преимущество этого заключается в том, что новый канал можно выбрать до начала преобразования, не обращая внимания на проблемы с синхронизацией или непредсказуемые результаты. Если для этого используется ADC Conversion Complete ISR, потеря скорости будет довольно небольшой.
В этом случае мы можем использовать автономный режим — нам не нужно менять ADMUX (используется только один канал).
Рекомендуемый диапазон тактовой частоты АЦП составляет от 50 кГц до 200 кГц. Если используются более быстрые часы АЦП, разрешение снизится. Тактовая частота АЦП предварительно масштабируется от основной тактовой частоты отдельным предделителем АЦП. Коэффициент деления выбирается битами ADPS2..0 в ADCSR (см. Страницы 203/204 таблицы данных). Для 4 МГц подходящими значениями являются 32 (результирующая тактовая частота АЦП 125 кГц) и 64 (результирующая тактовая частота АЦП 62.5 кГц). Мы будем использовать 32.
Вектор прерывания mega8 для ISR завершения преобразования АЦП не имеет большого значения. Когда он вызывается, свежий результат АЦП доступен в ADCL и ADCH. Он преобразуется в 8 бит (два младших бита не используются) и записывается в PortD. На STK500 светодиоды имеют низкий активный низкий уровень, поэтому рекомендуется инвертировать результат перед записью в PortD.
ISR, конечно, вызывается только в том случае, если установлен бит ADIE (ADC Interrupt Enble) в ADCSR и если разрешены глобальные прерывания.
.org 0x0000 сброс rjmp .org 0x000E rjmp ADC_ISR сброс: ldi r16, низкий (RAMEND) out SPL, r16 ldi r16, high (RAMEND) out SPH, r16 out SPH, r16 r16, 0xFF выход DDRD, r16 ldi r16, 0 выход ADMUX, r16 ldi r16, 0b11101101 выход ADCSR, r16 sei цикл : цикл rjmp вход rjmp, вход rjmp, вход rjmp, вход rjmp, вход rjmp, вход rjmp, вход rjmp, вход rjmp 63 SREG push r16 push r17 in r16, ADCL in r17, ADCH lsr r17 ror r16 lsr r17 ror r16 com r16 pop r1763 pop r16, pop r16поп р16 рети | ; сбросить вектор ; перейти к «сбросу» ; ; Вектор прерывания завершения преобразования АЦП: ; перейти на «ADC_ISR» ; ; код сброса: ; настройка стека; установите SPH: SPL на ; RAMEND ; ; ; ; установите все выводы PortD на выход ; ; ; напишите ноль ; в ADMUX (выберите канал 0) ; слева направо: включение АЦП, начало преобразования, автономный режим, запись ; от нуля до флага ADC Int, включить int, предварительный делитель: 101 для XTAL / 32 ; ; разрешить прерывания ; ; и петля ; навсегда ; ; Вот и наш ISR! ; сохранить r16 ; используйте r16 16 для сохранения SREG ; (поместите оба в стек) ; также сохраните r17 ; ; получить последний результат АЦП, сначала младший байт, ; затем старший байт ; сдвинуть результат АЦП вправо (2 бита) ; сначала сдвинув бит 0 в r16, затем сдвинув его в r17 ; ; (дважды) ; ; теперь инвертируем результат ; и пишем в PortD ; ; восстановить r17, ; SREG ; ; и r16 ; и возвращаем |
ATMega8, конфигурация, характеристики и техническое описание
Конфигурация контактов ATMEGA8Контактный № | Название пина | Описание | Альтернативная функция |
1 | PC6 (СБРОС) | Pin6 PORTC | Вывод по умолчанию используется как вывод сброса.Если запрограммирован предохранитель RSTDISBL, PC6 можно использовать как вывод ввода / вывода. (ВЫСОКОЕ значение контроллера сброса) |
2 | PD0 (RXD) | Pin0 PORTD | RXD (входной контакт USART) Интерфейс последовательной связи USART [Может использоваться для программирования] |
3 | PD1 (TXD) | Контакт1 PORTD | TXD (выходной контакт USART) Интерфейс последовательной связи USART [Может использоваться для программирования] INT2 (вход внешнего прерывания 2) |
4 | PD2 (INT0) | Контакт 2 PORTD | Внешнее прерывание INT0 |
5 | PD3 (INT1) | Контакт 3 PORTD | Внешнее прерывание INT1 |
6 | PD4 (XCK / T0) | Pin4 PORTD | T0 (Вход внешнего счетчика Timer0) XCK (ввод / вывод внешних часов USART) |
7 | VCC | ||
8 | ЗЕМЛЯ | ||
9 | PB6 (XTAL1 / TOSC1) | Pin6 PORTB | XTAL1 (вывод 1 генератора тактовых импульсов или вход внешнего тактового сигнала) TOSC1 (вывод 1 генератора таймера) |
10 | PB7 (XTAL2 / TOSC2) | Pin7 порта PORTB | XTAL2 (вывод 2 генератора тактовой частоты) TOSC2 (вывод 2 генератора таймера) |
11 | ПД5 (Т1) | Контакт 5 PORTD | T1 (Вход внешнего счетчика Timer1) |
12 | PD6 (AIN0) | Pin6 PORTD | AIN0 (положительный I / P аналогового компаратора) |
13 | PD7 (AIN1) | Pin7 PORTD | AIN1 (отрицательный I / P аналогового компаратора) |
14 | PB0 (ICP1) | Pin0 порта PORTB | ICP1 (Вход захвата таймера / счетчика 1) |
15 | PB1 (OC1A) | Pin1 порта PORTB | OC1A (выход таймера / счетчика1, выход сравнения A) |
16 | PB2 (SS / OC1B) | Контакт 2 порта PORTB | SS (вход выбора ведомого SPI).Этот вывод низкий, когда контроллер действует как ведомый. [Последовательный периферийный интерфейс (SPI) для программирования] OC1B (Выход таймера / счетчика1, выход сравнения B) |
17 | PB3 (MOSI / OC2) | Контакт 3 PORTB | MOSI (главный выход, подчиненный вход).Когда контроллер действует как подчиненный, данные принимаются на этот вывод. [Последовательный периферийный интерфейс (SPI) для программирования] OC2 (Выход таймера / счетчика2, выход сравнения) |
18 | PB4 (MISO) | Pin4 порта PORTB | MISO (главный вход и выход подчиненного устройства). Когда контроллер действует как подчиненный, данные передаются этим контроллером мастеру через этот вывод. [Последовательный периферийный интерфейс (SPI) для программирования] |
19 | PB5 (SCK) | Контакт 5 PORTB | SCK (последовательные часы шины SPI). Это часы, совместно используемые этим контроллером и другой системой для точной передачи данных. [Последовательный периферийный интерфейс (SPI) для программирования] |
20 | AVCC | Vcc для внутреннего преобразователя АЦП | |
21 | AREF | Вывод аналогового опорного сигнала для АЦП | |
22 | ЗЕМЛЯ | ЗЕМЛЯ | |
23 | PC0 (АЦП0) | Pin0 PORTC | ADC0 (входной канал ADC 0) |
24 | ПК1 (АЦП1) | Контакт1 PORTC | АЦП1 (входной канал АЦП 1) |
25 | ПК2 (АЦП2) | Контакт 2 PORTC | АЦП2 (входной канал 2 АЦП) |
26 | PC3 (АЦП3) | Контакт 3 PORTC | АЦП3 (входной канал АЦП 3) |
27 | PC4 (АЦП4 / SDA) | Pin4 PORTC | АЦП4 (входной канал АЦП 4) SDA (линия ввода / вывода данных двухпроводной последовательной шины) |
28 | PC5 (ADC5 / SCL) | Контакт 5 PORTC | ADC5 (входной канал ADC 5) SCL (Линия синхронизации двухпроводной последовательной шины) |
ATMEGA8 — упрощенные функции | |
ЦП | 8-битный AVR |
Количество контактов | 28 |
Рабочее напряжение (В) | +2.7 В ДО +5,5 В (ATmega8L) +4,5 В ДО +5,5 В (ATmega8) (+ 5,5 В является абсолютным максимумом) |
Количество контактов ввода / вывода | 23 |
Коммуникационный интерфейс | Главный / подчиненный последовательный интерфейс SPI (16,17,18,19 контактов) [Может использоваться для программирования этого контроллера] Программируемый последовательный USART (2,3 PINS) [Может использоваться для программирования этого контроллера] Двухпроводной последовательный интерфейс (27,28 контактов) [Может использоваться для подключения периферийных устройств, таких как датчики и ЖК-дисплеи] |
Интерфейс JTAG | Не доступен |
Модуль АЦП | 6 каналов, разрешение 10 бит АЦП |
Модуль таймера | Два 8-битных счетчика, Один 16-битный счетчик [Всего три] |
Аналоговые компараторы | 1 |
Модуль ЦАП | Нет |
ШИМ каналов | 3 |
Внешний осциллятор | 0-8 МГц для ATMEGA8L 0-16 МГц для ATMEGA8 |
Внутренний осциллятор | Калиброванный внутренний осциллятор 0–8 МГц |
Тип памяти программ | Вспышка |
Программная память или флэш-память | 8 Кбайт [10000 циклов записи / стирания] |
Скорость процессора (MIPS) | 16 MIPS |
RAM | 1 Кбайт |
EEPROM | 512 |
Сторожевой таймер | Программируемый сторожевой таймер с отдельным встроенным генератором |
Блокировка программы | Есть |
Режимы энергосбережения | Шесть режимов [режим ожидания, шумоподавление АЦП, энергосбережение, отключение питания, режим ожидания и расширенный режим ожидания] |
Рабочая температура | от -55 ° C до + 125 ° C (+125 — абсолютный максимум, -55 — абсолютный минимум) |
ATMEGA328P
Альтернативы ATMEGA8ATMEGA16, ATMEGA32, ATMEGA8535
Где использовать микроконтроллер ATMEGA8ATMEGA8 — это 28-контактный микроконтроллер AVR .Несмотря на то, что у нас есть много похожих микроконтроллеров, ATMEGA8 популярен, потому что это один из самых дешевых микроконтроллеров и предоставляет множество функций на меньших контактах. Благодаря программной памяти 8 Кбайт приложение ATMEGA8 очень универсально. С различными режимами ЭНЕРГОСБЕРЕЖЕНИЯ он может работать в МОБИЛЬНЫХ ВСТРОЕННЫХ СИСТЕМАХ. Благодаря своему компактному размеру его можно разместить на многих небольших досках. Благодаря сторожевому таймеру для сброса при ошибке его можно использовать в системах с минимальным вмешательством человека. Эти функции, объединенные в одном контроллере, делают ATMEGA8 популярным.
Как использовать микроконтроллер ATMEGA8Использование ATMega8 аналогично использованию других микроконтроллеров ATMega, таких как ATMega32. Точно так же микроконтроллер необходимо запрограммировать и добавить соответствующие периферийные устройства для получения выходного сигнала. Без программирования контроллер — пустая фишка.
Для работы ATMEGA8 сначала необходимо записать соответствующий программный файл во флэш-память ATMEGA8 . После сброса этого программного кода контроллер выполняет этот код и дает соответствующий ответ.
Весь процесс использования ATMEGA8 выглядит следующим образом:
- Список функций, которые должны выполняться ATMEGA8.
- Напишите функции на языке программирования в программах IDE. Вы можете бесплатно скачать программу IDE. Программа IDE для контроллеров AVR — ATMEL STUDIO. Ссылка на ATMELSTUDIO приведена ниже.
(Обычно Atmel Studio 6.0 для Windows7 [http://atmel-studio.software.informer.com/6.0/],
Atmel Studio 7 для Windows10 [https: // www.microchip.com/avr-support/atmel-studio-7])
(помните, что для этих IDE программа должна быть написана на языке «C»)
- После написания нужных программ скомпилируйте для устранения ошибок с помощью IDE.
- Заставить среду IDE сгенерировать HEX-файл для написанной программы.
- Выберите устройство программирования (обычно программатор SPI для контроллеров AVR), который устанавливает связь между ПК и ATMEGA8.
- Запустите программу записи файлов HEX, которая предоставляется для выбранного устройства программирования.
- Выберите соответствующий шестнадцатеричный файл программы в SPI или другом программном обеспечении.
- Запишите шестнадцатеричный файл записанной программы во флэш-память ATMEGA8, используя эту программу.
- Отключите программатор, подключите соответствующие периферийные устройства для контроллера и запустите систему.
Есть сотни приложений для ATMEGA8.
- Промышленные системы управления.
- SMPS и системы регулирования мощности.
- Измерение аналоговых сигналов и манипуляции с ними.
- Встроенные системы, такие как кофеварка, торговый автомат.
- Системы управления двигателями.
- Дисплейные единицы.
- Система периферийного интерфейса.
Все размеры указаны в миллиметрах.
Генератор сигналовATmega8
; ; ************************************************* * ; * Регулируемый генератор прямоугольников с ATmega8 * ; * Частота (0.25 Гц..8 МГц) и ширины импульса (0,00 .. * ; * 100,00%) переменная, ЖК-дисплей (по выбору) ; * левая / двойная строка, 16..40 символов в строке), дис- * ; * частота воспроизведения или количество оборотов в минуту и пульс * ; * ширина в% * ; * Требуются включаемые файлы "rectgen_m8_table.inc" * ; * и "Lcd8_02WO_rec.inc" * ; * Версия 1 от 21 апреля 2006 г. * ; * (C) 2006, автор info! At! Avr-asm-tutorial.net * ; ************************************************* * ; .НОЛИСТ .ВКЛЮЧАЙТЕ "m8def.inc" .СПИСОК ; ; Информация об отладке ; .EQU dbgOn = 0; отладка включена или выключена .IF dbgOn .EQU cAdc0 = 1000; Значение ADC0 .EQU cAdc1 = 511; Значение ADC1 .EQU cFlg = 0 ; .EQU cFlg = (1 << bTime) ; .EQU cFlg = (1 << bRpm) ; .EQU cFlg = (1 << bPw) .ENDIF .EQU dbghx = 0; отладка шестнадцатеричного вывода на ЖК-дисплее ; ; Аппаратное обеспечение ; ___________ ; __ 10к / | _ ; + 5V O- | __ | - | СБРОС PC5 | --O - O O-- | Ширина импульса дисплея ; | | _ (Только однострочный ЖК-дисплей!) ; ЖК-дисплей D0 O-- | PD0 PC4 | --O - O O-- | Обратный сигнал ; | | _ ; ЖК-дисплей D1 O-- | PD1 PC3 | --O - O O-- | Показывать RPM ; | | _ ; ЖК-дисплей D2 O-- | PD2 PC2 | --O - O O-- | Время отображения ; | | ; ЖК-дисплей D3 O-- | PD3 ADC1 | --O 0.Регулировка ширины импульса 5 В ; | A T | ; LCD D4 O-- | PD4 ADC0 | --O 0..5V Регулировка частоты ; | мега | ; + 5V O-- | VCC GND | --O GND ; | 8 | 10 нФ ; GND O-- | GND AREF | --O-- || - | AREF ; | | ___ 22 ч / 10 нФ ; XTAL1 O-- | XTAL1 AVCC | --O-- | ___ | --O + 5 В ; | | ; XTAL2 O-- | XTAL2 PB5SCK | --O ЖК-дисплей R / W, SCK ; | | ; ЖК-дисплей D5 O-- | PD5 PB4MISO | --O ЖК-дисплей RS, MISO ; | | ; ЖК-дисплей D6 O-- | PD6 PB3MOSI | --O MOSI ; | | ; LCD D7 O-- | PD7 PB2OC1B | --O Выход B ; | | ; LCD E O-- | PB0 PB1OC1A | --O Выход A ; | ____________ | ; ; ; Сроки ; ------- ; ; TC0: предварительный делитель = 1024, прерывание переполнения, @ 16 МГц: ; 16.384 мс, обратный отсчет от 30 до 0, если ноль ; (491,52 мс) запускает цикл преобразования АЦП ; ; Каналы АЦП 1 и 2: преобразование начинается с TC0, ; предварительный делитель частоты = 128, @ 16MHz, первое завершение ; прерывание через 200 мкс, второе прерывание после ; 104 мкс, АЦП отключен и установлен флаг полной ; после двух полных преобразований ; ; АЦП завершен: считывает значение для настройки ICR1-CTC из ; запись в таблице для ADC0, вычисляет COMPA / COMPB ; значение из CTC-значения и ADC1, устанавливает TC1-ICR1 ; и значения COMPA / COMPB, обновляет предварительный делитель TC1 ; и TC1-выход-полярность-режимы ; ; TC1: режим быстрой ШИМ / WGM = 14, предварительный делитель = 1..1024 (де- ; в ожидании от выбранной частоты), ICR1 определяет ; мин TOP, COMPA / B определяет фазомодулированный ; инверсия выходных сигналов ; ; ************************************************ ; Д Е Ф И Н И Т И О Н С ; ************************************************ ; ; Константы ; .EQU clock = 16000000; тактовая частота .EQU cDivF5 = $ 00; = часы * 100 (5 байтов) .EQU cDivF4 = 5F долларов .EQU cDivF3 = 5 евро .EQU cDivF2 = 10 долларов США .EQU cDivF1 = $ 00. .EQU cDivU5 = 16 долларов США; = часы * 100 * 60 (5 байтов) .EQU cDivU4 = 5 долларов США .EQU cDivU3 = 0 млрд долларов .EQU cDivU2 = $ C0 .EQU cDivU1 = $ 00. .EQU cLcdLw = 24; Ширина линии ЖК-дисплея .EQU cLcdLn = 2; количество строк ЖК-дисплея ; .EQU cLcdMicro = $ E4; микро-символ на ЖК-дисплее, не работает на L2432 .EQU cLcdMicro = 'и' .EQU cEn = 1; английская или немецкая версия ; ; Зависимые константы ; .EQU cTMult = (256000000 / часы) * 100 .IF cEn .EQU c1000s = 2 цента; комма .EQU cDecs = $ 2E; точка .ЕЩЕ .EQU c1000s = 2E долларов США; точка .EQU cDecs = $ 2C; комма .ENDIF ; ; Регистры ; ; использованы: R0..R13 для расчетов ; бесплатно: R14 .DEF rSreg = R15; Регистр сохранения статуса .DEF rmp = R16; Многоцелевой реестр за пределами Интса .DEF обод = R17; Многоцелевой регистр внутри Ints .DEF rFlg = R18; регистр флагов .EQU bTime = 0; отображать время вместо частоты .EQU bRpm = 1; отображать обороты вместо частоты .EQU bInv = 2; инвертировать выходной сигнал .EQU bAdc0 = 3; Флаг завершения канала 0 АЦП .EQU bAdc1 = 4; Флаг завершения канала 1 АЦП .IF cLcdLn == 1 .EQU bPw = 7; отображение ширины импульса в строке 1 однострочного ЖК-дисплея .ENDIF .DEF rAdc0L = R19; LSB последний результат ADC0 .DEF rAdc0H = R20; dto., MSB .DEF rAdc1L = R21; LSB последний результат ADC1 .DEF rAdc1H = R22; dto., MSB .DEF rAdcC = R23; счетчик задержки запуска цикла АЦП ; бесплатно: R24..R25 ; использовано: X (R27: R26) для расчетов ; бесплатно: Y (R29: R28) ; использованы: Z (R31: R30) для расчетов ; ; Порты ; ; LCD-порты .EQU pLcdData = ПОРТД .EQU pLcdCtrl = ПОРТБ .EQU pbLcdE = 0 .EQU pbLcdRs = 4 .EQU pbLcdRw = 5 ; Ключевые порты .EQU pSwtchOut = ПОРТК .EQU pSwtchIn = PINC .EQU pbTime = 2 .EQU pbRpm = 3 .EQU pbInv = 4 .EQU pbPwm = 5 ; Сигнальные выходы .EQU pSignOut = ПОРТB .EQU pSignDdr = DDRB .EQU pbSignA = 1 .EQU pbSignB = 2 ; ; Позиции SRAM ; .DSEG .ORG $ 0060 sCtc:; Делитель CTC TC1 .BYTE 2 sCmp:; COMPA / B ширина импульса TC1 .BYTE 2 sPre:; Прескейлер TC1 .BYTE 1 sMode:; режим TC1 .BYTE 1 sLcdL1:; Строка 1 ЖК-дисплея .BYTE cLcdLw .IF cLcdLn> 1 sLcdL2:; Строка 2 ЖК-дисплея .BYTE cLcdLw .ENDIF ; ; ************************************************ ; R E S E T - и I N T - V E C T O R S ; ************************************************ ; ; Сегмент кода .CSEG .ORG $ 0000 ; rjmp main; Сбросить вектор, перейти к основному циклу рети; INT0, не используется рети; INT1, не используется рети; TIMER2COMP, не используется рети; TIMER2OVF, не используется рети; TIMER1CAPT, не используется рети; TIMER1COMPA, не используется рети; TIMER1COMPB, не используется рети; TIMER1OVF rjmp TC0OvflwInt; TIMER0OVF рети; SPI, STC, не используется рети; USART, RXC, не используется рети; USART, UDRE, не используется рети; USART, TXC, не используется rjmp AdcInt; АЦП рети; EE_RDY, не используется рети; ANA_COMP, не используется рети; TWI, не используется рети; SPM_RDY, не используется ; ; ************************************************ ; И Н Т - В Е К Т О Р - Р О У Т И Н Е С ; ************************************************ ; ; TC0 Overflow Interrupt, запускает цикл обновления АЦП. ; TC0OvflwInt: в rSreg, SREG; сохранить статус dec rAdcC; счетчик начальных циклов обратного отсчета brne TC0OvflwInt1 ldi rAdcC, 30; счетчик перезапуска ldi rimp, (1 << REFS0); установите ADMUX на канал 0 из ADMUX, обод ldi rimp, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1 >> | (1 << ADPS0) из ADCSRA, обод; начать конверсию канал 0 cbr rFlg, 1 << bAdc0; очистить канал 0, флаг завершения TC0OvflwInt1: из SREG, rSreg; восстановить статус Рети ; ; Прерывание готовности АЦП, считывает значение АЦП ; AdcInt: в rSreg, SREG; сохранить статус sbrc rFlg, bAdc0; канал 0 завершен? rjmp AdcInt1; да, начать следующий канал в rAdc0L, ADCL; читать канал 0 в rAdc0H, ADCH ldi rimp, (1 << REFS0) | (1 << MUX0); установить канал 1 из ADMUX, обод ldi rimp, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1 >> | (1 << ADPS0) из ADCSRA, обод; начать конверсию канал 1 sbr rFlg, 1 << bAdc0; установить флаг завершения канала 0 из SREG, rSreg; восстановить статус Рети AdcInt1: в rAdc1L, ADCL; читать канал 1 в rAdc1H, ADCH ldi rimp, (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); отключить АЦП из ADCSRA, обод sbr rFlg, 1 << bAdc1; установить флаг завершения канала 1 из SREG, rSreg; восстановить статус Рети ; ; ************************************************ ; С У Б Р О У Т И Н Е С ; ************************************************ ; ; Считывает текущее значение CTC и предварительного делителя и вычисляет ; скорость в R7: R6: R5: R4 ; GetRate: lds rmp, sPre; читать прескалер в rmp andi rmp, (1 << CS12) | (1 << CS11) | (1 << CS10) breq GetRate2; Предделитель равен нулю, установить флаг переноса lds R4, sCtc; читать разделитель на R7: R6: R5: R4 lds R5, sCtc + 1 clr R6 clr R7 dec rmp breq GetRate1; предварительный делитель = 1 lsl R4; разделитель * 2 rol R5 rol R6 rol R7 lsl R4; разделитель * 4 rol R5 rol R6 rol R7 lsl R4; делитель * 8 rol R5 rol R6 rol R7 dec rmp breq GetRate1; предварительный делитель = 8 lsl R4; делитель * 16 rol R5 rol R6 rol R7 lsl R4; делитель * 32 rol R5 rol R6 rol R7 lsl R4; делитель * 64 rol R5 rol R6 rol R7 dec rmp breq GetRate1; предварительный делитель = 64 lsl R4; делитель * 128 rol R5 rol R6 rol R7 lsl R4; делитель * 256 rol R5 rol R6 rol R7 dec rmp breq GetRate1; предварительный делитель = 256 lsl R4; делитель * 512 rol R5 rol R6 rol R7 lsl R4; делитель * 1024 rol R5 rol R6 rol R7 GetRate1:; Таймер активен, четкий перенос clc Ret GetRate2:; Таймер неактивен, установить перенос сек Ret ; ; Вычислить отображаемый текст по текущим параметрам таймера ; Расчет: sbrc rFlg, bTime; время отображения? rjmp CalcTime; да, переезжай туда clr R8; результат четкого разделения в R11: R10: R9: R8 inc R8; установить последний бит как счетчик clr R9 clr R10 clr R11 rcall GetRate brcs L1Lcd; Таймер выключен, частота = 0 clr R3; установить делитель в R3: R2: R1: R0: ZH: ZL: XH: XL clr R2 clr R1 sbrc rFlg, bRpm; отображать обороты? rjmp Calc1; да ldi rmp, cDivF5; частота отображения mov R0, rmp ldi ZH, cDivF4 ldi ZL, cDivF3 ldi XH, cDivF2 ldi XL, cDivF1 rjmp Calc2 Calc1: ldi rmp, cDivU5; отображение оборотов в минуту mov R0, rmp ldi ZH, cDivU4 ldi ZL, cDivU3 ldi XH, cDivU2 ldi XL, cDivU1 Calc2: lsl XL; * 2 rol XH rol ZL rol ZH rol R0 rol R1 rol R2 rol R3 cp R0, R4; сравнивать cpc R1, R5 cpc R2, R6 cpc R3, R7 brcs Calc3 sub R0, R4; вычесть сбн R1, R5 SBC R2, R6 сбн R3, R7 сек rjmp Calc4 Calc3: clc Calc4: rol R8; свернуть бит результата в rol R9 rol R10 rol R11 brcc Calc2; повторить 32 раза lsl ZH; округлять? rol R0 rol R1 rol R2 rol R3 cp R0, R4 cpc R1, R5 cpc R2, R6 cpc R3, R7 brcs Calc5 ldi rmp, 1 добавить R8, об / мин ldi rmp, 0 adc R9, об / мин adc R10, об / мин adc R11, об / мин Calc5: ; ; Отобразите результат в R11: R10: R9: R8 в строке 1 ; L1Lcd: clr R0; R0 - ведущий пустой флаг ldi ZH, HIGH (2 * DecTab32); указать на десятичную таблицу ldi ZL, LOW (2 * DecTab32) ldi XH, ВЫСОКИЙ (sLcdL1); X указывает на линию ЖК-дисплея ldi XL, НИЗКИЙ (sLcdL1) ldi rmp, 'F'; частота отображения sbrc rFlg, bRpm ldi rmp, 'R'; отображение оборотов в минуту sbrc rFlg, bTime ldi rmp, 'T'; время отображения ст X +, об / мин; установить первый символ .ЕСЛИ cLcdLw> 16 ldi rmp, ''; добавить пробел ст X +, пасс. ldi rmp, '='; добавить = ст X +, пасс. rcall Dec32; написать 10 миллионов .ЕЩЕ rcall Dec32; напиши десять миллионов ld rmp, -X; читать символ последняя позиция cpi rmp, ''; это пусто? brne L1Lcd00 ldi rmp, '='; добавить = ст X, пасс. L1Lcd00: adiw XL, 1 .ENDIF rcall Dec32; написать миллионы ldi rmp, c1000s tst R0 brne L1Lcd0a ldi rmp, '' L1Lcd0a: ст X +, пасс. rcall Dec32; написать 100000 rcall Dec32; написать 10 000 rcall Dec32; написать тысячу ldi rmp, c1000s tst R0 brne L1Lcd0b ldi rmp, '' L1Lcd0b: ст X +, пасс. rcall Dec32; написать 100 rcall Dec32; написать 10 inc R0; убрать начальные пробелы rcall Dec32; написать 1 tst R8; отображать десятичные дроби? breq L1Lcd1 ldi rmp, cDecs; установить десятичный символ ст X +, пасс. rcall Dec32; напишите 0.1-е ldi rmp, '0' добавить обороты, R8; написать 0,01 ст X +, пасс. rjmp L1Lcd2 L1Lcd1: ldi rmp, ''; установить десятичные дроби пустыми ст X +, пасс. ст X +, пасс. ст X +, пасс. L1Lcd2: .IF cLcdLw> 16 ldi rmp, ''; добавить еще один пробел ст X +, пасс. .ENDIF sbrc rFlg, bTime; время отображения? rjmp L1Lcd4; да sbrc rFlg, bRpm; Диплай РПМ? rjmp L1Lcd3; да ldi rmp, 'H'; частота отображения ст X +, пасс. ldi rmp, 'z' ст X +, пасс. rjmp L1Lcd5 L1Lcd3: ldi rmp, 'p'; отображение оборотов в минуту ст X +, пасс. ldi rmp, 'm' ст X +, пасс. rjmp L1Lcd5 L1Lcd4: ldi rmp, cLcdMicro ст X +, пасс. ldi rmp, 's' ст X +, пасс. L1Lcd5: .ЕСЛИ cLcdLw> 16 ldi rmp, '' mov R0, rmp ldi rmp, cLcdLw-19 L1Lcd6: ст X +, R0 dec rmp brne L1Lcd6 .ENDIF Ret ; ; Вычислить следующую десятичную цифру 32-битного числа ; Dec32: л / мин R4, Z +; прочитать следующее десятичное число л / мин R5, Z + л / мин R6, Z + л / мин R7, Z + clr rmp Dec32a: cp R8, R4; сравните число с десятичной цифрой цена за клик R9, R5 cpc R10, R6 cpc R11, R7 brcs Dec32b sub R8, R4 сбк R9, R5 SBC R10, R6 SBC R11, R7 inc rmp; inc результат rjmp Dec32a; повторить Dec32b: добавить R0, об / мин; добавить к начальному пустому флагу subi rmp, - '0'; добавить ноль ASCII tst R0; все еще ведущие пробелы? brne Dec32c ldi rmp, ''; установить начальный пробел Dec32c: ст X +, об / мин; сохранить символ в буфере SAM Ret ; ; 32-битная десятичная таблица для преобразования ; DecTab32: .00 долларов США, CA, 9 долларов США, 3 млрд долларов США; 1000 мрд .DB $ 00, $ E1, $ F5, $ 05; 100 млн .DB 80, 96, 98, 00 долларов; 10 млн .DB 40, 42, 0, 00 долларов; 1 млн .DB $ A0, 86, $ 01, $ 00; 100 000 DecTab16: .DB $ 10, 27, $ 00, $ 00; 10 000 .DB $ E8, $ 03, $ 00, $ 00; 1,000 .DB $ 64, $ 00, $ 00, $ 00; 100 .DB $ 0A, $ 00, $ 00, $ 00; 10 ; ; Рассчитать и отобразить время ; CalcTime: rcall GetRate; скорость чтения до R7: R6: R5: R4 brcc CalcTime1; таймер активен, время расчета rjmp L1Lcd; таймер неактивен, отображается 0 CalcTime1: mov R2, R4; переместите мультипликатор на R7: R: R5: R4: R3: R2 mov R3, R5 mov R4, R6 mov R5, R7 clr R6 clr R7 clr R8; очистить результат в R13: R12: R11: R10: R9: R8 clr R9 clr R10 clr R11 clr R12 clr R13 ldi rmp, HIGH (cTMult); множитель нагрузки на R1: R0 mov R1, rmp ldi rmp, LOW (cTMult) mov R0, rmp CalcTime2: lsr R1; сдвинуть следующий бит умножителя для переноса ror R0 brcc CalcTime3 добавить R8, R2; добавить мультипликатор АЦП R9, R3 АЦП R10, R4 АЦП R11, R5 АЦП R12, R6 АЦП R13, R7 CalcTime3: lsl R2; умножить множитель на 2 rol R3 rol R4 rol R5 rol R6 rol R7 tst R0; проверьте LSB для окончания умножения brne CalcTime2 tst R1; проверьте MSB на конец умножения brne CalcTime2 mov rmp, R8; оставить младший байт для округления mov R8, R9; сдвинуть результат вправо = разделить на 256 mov R9, R10 mov R10, R11 mov R11, R12 tst R13; проверить на переполнение breq CalcTime5 CalcTime4: ldi rmp, 0xFF; переполнение, установить максимальное число mov R8, rmp mov R9, rmp mov R10, об / мин mov R11, rmp rjmp L1Lcd; и дисплей CalcTime5: cpi rmp, 0x80 brcs CalcTime6 ldi rmp, 0x01; округлять добавить R8, об / мин ldi rmp, 0x00 adc R9, об / мин adc R10, об / мин adc R11, об / мин brcs CalcTime4 CalcTime6: rjmp L1Lcd ; ; Рассчитайте ширину импульса, сначала умножьте длительность импульса на 10000, ; затем разделите результат на общую продолжительность паузы ; CalcPw: lds R7, sCmp; Считайте активную длительность импульса в R10: R9: R8: R7 lds R8, sCmp + 1 clr R9 clr R10 clr R0; четкий результат умножения в R6: R5: R4: R2: R1: R0 clr R1 clr R2 clr R3 clr R4 clr R5 clr R6 ldi rmp, HIGH (10000); установить R12: R11 на 10000 mov R12, об / мин ldi rmp, НИЗКИЙ (10000) mov R11, rmp CalcPw1: lsr R12; сдвинуть следующий бит вправо, чтобы перенести ror R11 brcc CalcPw2; ноль сдвинут добавить R0, R7; добавить мультипликатор АЦП R1, R8 АЦП R2, R9 АЦП R3, R10 CalcPw2: lsl R7; умножить на 2 rol R8 rol R9 rol R10 tst R11; проверить конец умножения brne CalcPw1; продолжать tst R12 brne CalcPw1; продолжать lds R7, sCtc; считывать значение CTC в R9: R8: R7 lds R8, sCtc + 1 clr R9 clr R10; четкий результат деления inc R10 clr R11 clr R12 clr R13 CalcPw3: lsl R0; сдвиг влево rol R1 rol R2 rol R3 rol R4 rol R5 rol R6 cp R4, R7; сравнить по разделителю cpc R5, R8 cpc R6, R9 brcs CalcPw4; не зашивать sub R4, R7 сбк R5, R8 сбк R6, R9 сек rjmp CalcPw5; сдвинуть 1 дюйм CalcPw4: clc; сдвинуть 0 в CalcPw5: rol R10; сдвинуть результат в rol R11 rol R12 rol R13 brcc CalcPw3 lsl R3; круглый результат rol R4 rol R5 rol R6 cp R4, R7 cpc R5, R8 cpc R6, R9 brcs L2Lcd ldi rmp, 1 добавить R10, об / мин ldi rmp, 0 adc R11, об / мин adc R12, об / мин adc R13, об / мин L2Lcd: mov R8, R10 mov R9, R11 mov R10, R12 mov R11, R13 ldi ZH, HIGH (2 * DecTab16) ldi ZL, LOW (2 * DecTab16) clr R0 .ЕСЛИ cLcdLn == 1 ldi XH, ВЫСОКИЙ (sLcdL1) ldi XL, НИЗКИЙ (sLcdL1) .ЕЩЕ ldi XH, ВЫСОКИЙ (sLcdL2) ldi XL, НИЗКИЙ (sLcdL2) .ENDIF ldi rmp, 'P' ст X +, пасс. ldi rmp, '' ст X +, пасс. ldi rmp, '=' ст X +, пасс. rcall Dec32; написать 100 rcall Dec32; написать 10 inc R0 rcall Dec32; написать 1 ldi rmp, cDecs; написать десятичный разделитель ст X +, пасс. rcall Dec32; написать 0,1 ldi rmp, '0'; написать 0,01 добавить обороты, R8 ст X +, пасс. ldi rmp, '%' ст X +, пасс. ldi rmp, '' mov R0, rmp ldi rmp, cLcdLw-9 L2Lcd1: ст X +, R0 dec rmp brne L2Lcd1 Ret ; ; ************************************************ ; У П Д А Т Е Т И М Е Р В А Л У Е С ; ************************************************ ; ; Преобразование значений АЦП и установка таймера ; Перерабатывать: ldi ZH, HIGH (2 * с датой) ldi ZL, LOW (2 * с датой) добавить ZL, rAdc0L; добавить значение ADC0 adc ZH, rAdc0H добавить ZL, rAdc0L; снова добавить значение ADC0 adc ZH, rAdc0H л / мин R0, Z +; прочитать значение таблицы л / мин R1, Z п. ст. ст., R0; копировать в SRAM п. ст. ст. + 1, 1 лиц. clr R2; ясно для умножения в R3: R2: R1: R0 clr R3 mov R4, rAdc1L; скопировать результат ADC1 в R5: R4 mov R5, rAdc1H clr R9; очистить результат в R9: R8: R7: R6 clr R8 clr R7 clr R6 Конвертировать1: lsr R5; сдвинуть младший бит для переноса ror R4 brcc Convert2; бит равен нулю, не добавляйте добавить R6, R0 АЦП R7, R1 АЦП R8, R2 АЦП R9, R3 Конвертировать2: lsl R0; сдвинуть мультипликатор на один влево rol R1 rol R2 rol R3 tst R4; проверить, равен ли мультипликатор нулю brne Convert1 tst R5 brne Convert1 lsr R9; разделить результат на 2 ror R8 ror R7 lsr R9; разделить результат на 4 ror R8 ror R7 brcc Convert3 ldi rmp, 1; округлять добавить R7, об / мин ldi rmp, 0 adc R8, об / мин Конвертировать3: ст.ст.с.м.п., R7; хранить в SRAM ст.с.м.п. + 1, R8 mov ZL, rAdc0L; скопировать ADC0 в Z mov ZH, rAdc0H ldi XL, НИЗКИЙ (392) ldi XH, ВЫСОКИЙ (392) ldi rmp, (1 << WGM13) | (1 << WGM12) | (1 << CS10) cp ZL, XL cpc ZH, XH brcc Convert4 ldi rmp, (1 << WGM13) | (1 << WGM12) | (1 << CS11) ldi XL, НИЗКИЙ (225) ldi XH, ВЫСОКИЙ (225) cp ZL, XL cpc ZH, XH brcc Convert4 ldi rmp, (1 << WGM13) | (1 << WGM12) | (1 << CS10) | (1 << CS11) ldi XL, НИЗКИЙ (60) ldi XH, ВЫСОКИЙ (60) cp ZL, XL cpc ZH, XH brcc Convert4 ldi rmp, (1 << WGM13) | (1 << WGM12) | (1 << CS12) cpi ZL, 3 brcc Convert4 ldi rmp, (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10) Конвертировать4: sts sPre, rmp; сохранить в хранилище управляющих байтов предварительного делителя ldi rmp, (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11) sbis pSwtchIn, pbInv; спросить перевернутый ldi rmp, (1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) sts sMode, rmp Ret ; ; Запишите новые значения в TC1 ; UpdateTc1: lds rmp, sCmp + 1; установить значение сравнения соответствия A выход OCR1AH, об / мин lds rmp, sCmp выход OCR1AL, об / мин lds rmp, sCmp + 1; установить значение сравнения соответствия B выход OCR1BH, об / мин lds rmp, sCmp выход OCR1BL, об / мин lds rmp, sCtc + 1; установить значение CTC выход ICR1H, об / мин lds rmp, sCtc выход ICR1L, об / мин lds rmp, sMode; установить режим TC1 выход TCCR1A, об / мин lds rmp, sPre выход TCCR1B, об / мин Ret ; ; ************************************************ ; L C D - R O U T I N E S ; ************************************************ ; ; Запустить ЖК-дисплей ; InitLcd: ldi ZH, HIGH (2 * LcdInitText) ldi ZL, LOW (2 * LcdInitText) rjmp LcdInit ; ; Строка дисплея 1 ЖК-дисплея ; LcdL1: ldi ZH, HIGH (sLcdL1); Z в строку 1 в SRAM ldi ZL, НИЗКИЙ (sLcdL1) rjmp LcdLine1 ; ; Строка дисплея 2 ЖК-дисплея ; .ЕСЛИ cLcdLn> 1 LcdL2: ldi ZH, ВЫСОКИЙ (sLcdL2); Z в строку 2 в SRAM ldi ZL, НИЗКИЙ (sLcdL2) rjmp LcdLine2 .ENDIF ; ; Отображение параметров TC1 в шестнадцатеричном виде в строке 1 дисплея ; .IF dbghx LcdHexPar: rcall LcdHome lds ZH, sCtc + 1 lds ZL, sCtc rcall Displ4Hex ldi rmp, '' mov R0, rmp rcall LcdChar lds ZH, sCmp + 1 lds ZL, sCmp rcall Displ4Hex ldi rmp, '' mov R0, rmp rcall LcdChar lds rmp, sMode rcall Displ2Hex ldi rmp, '' mov R0, rmp rcall LcdChar lds rmp, sPre rcall Displ2Hex ldi rmp, '' mov R0, rmp rjmp LcdChar Displ4Hex: mov rmp, ZH rcall Displ2Hex mov rmp, ZL Displ2Hex: толкать rmp своп rmp rcall Displ1Hex поп rmp Displ1Hex: andi rmp, 0x0F subi rmp, - '0' cpi rmp, '9' + 1 brcs Displ1Hex1 subi rmp, -7 Displ1Hex1: mov R0, rmp rjmp LcdChar .ENDIF ; ; ************************************************ ; М А И Н П Р О Г Р А М И Н И Т ; ************************************************ ; Главный: ldi rmp, HIGH (RAMEND); стек инициализации выход SPH, об / мин ldi rmp, НИЗКИЙ (RAMEND) выходное звуковое давление, об / мин ; порт ввода ключа инициализации ldi rmp, (1 << pbTime) | (1 << pbRpm) | (1 << pbInv) | (1 << pbPwm) out pSwtchOut, об / мин ; Инициируйте сигнальные выходы sbi pSignDdr, pbSignA sbi pSignDdr, pbSignB cbi pSignOut, pbSignA sbi pSignOut, pbSignB ; флаги инициализации clr rFlg .IF dbgOn; отладка математики ldi rmp, HIGH (cAdc0) mov rAdc0H, rmp ldi rmp, LOW (cAdc0) mov rAdc0L, rmp ldi rmp, HIGH (cAdc1) mov rAdc1H, rmp ldi rmp, LOW (cAdc1) mov rAdc1L, rmp ldi rFlg, cFlg rcall Конвертировать rcall UpdateTc1 .IF cLcdLn> 1 rcall Calc rcall CalcPw .ЕЩЕ sbrc rFlg, bPw rjmp dbgPw rcall Calc rjmp dbgloop dbgPw: rcall CalcPw .ENDIF dbgloop: rjmp dbgloop .ENDIF ; запустить ЖК-дисплей rcall InitLcd ; инициировать преобразование АЦП ldi rmp, (1 << REFS0); установите ADMUX на канал 0 выход ADMUX, об / мин ldi rmp, (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) выход ADCSRA, rmp; начать конверсию канал 0 ldi rAdcC, 1; установить начальное значение для задержки АЦП ldi rmp, (1 << CS02) | (1 << CS00); предварительный делитель 1024 выход TCCR0, об / мин ldi rmp, 1 << TOIE0; включить переполнение TC0 int из ТИМСК, об / мин sei ; ; ************************************************ ; М А И Н П Р О Г Р А М Л О О П ; ************************************************ ; Петля: спать нет sbrs rFlg, bAdc1; Флаг готовности АЦП установлен? rjmp Loop; нет, спать дальше cbr rFlg, 1 << bAdc1; сбросить флаг готовности АЦП .ЕСЛИ cLcdLn == 1 cbr rFlg, (1 << bTime) | (1 << bRpm) | (1 << bPw) | (1 << bInv) sbis pSwtchIn, pbPwm sbr rFlg, 1 << bPw .ЕЩЕ cbr rFlg, (1 << bTime) | (1 << bRpm) | (1 << bInv) .ENDIF sbis pSwtchIn, pbInv; инвертированные сигналы? sbr rFlg, 1 << bInv sbis pSwtchIn, pbTime sbr rFlg, 1 << bTime sbis pSwtchIn, pbRpm sbr rFlg, 1 << bRpm rcall Convert; преобразовать АЦП в значения TC1 rcall UpdateTc1 .IF cLcdLn> 1 rcall Calc; рассчитать частоту rcall CalcPw; рассчитать ширину импульса rcall LcdL2; строка дисплея 2 .ЕЩЕ sbrc rFlg, bPw; проверьте, отображается ли ширина импульса rjmp CPw; да, рассчитать ширину импульса rcall Calc; рассчитать частоту rjmp Loop1; и частота отображения CPw: rcall CalcPw; рассчитать ширину импульса .ENDIF Loop1: rcall LcdL1; строка дисплея 1 .IF dbghx rcall LcdHexPar .ENDIF rjmp Loop; иди спать снова ; ; ************************************************ ; И Н К Л У Д Е Т Е Л К Д Р О У Т И Н Е С ; ************************************************ ; .INCLUDE "Lcd8_02WO_rect.inc " ; ; Начальный текст ЖК-дисплея ; LcdInitText: .IF cLcdLn == 1 .IF cLcdLw == 40 .DB "Генератор прямоугольников DG4FAC ATmega8 V1.0" .ЕЩЕ .IF cLcdLw == 24 .DB "Rect Generator M8 V1.0" .ЕЩЕ .IF cLcdLw == 20 .DB "Rect Generator V1.0" .ЕЩЕ .IF cLcdLw == 16 .DB "Rect-Gen M8 V1.0" .ЕЩЕ .DB "RG M8 V1" .ENDIF .ENDIF .ENDIF .ENDIF .ЕЩЕ .IF cLcdLw == 40 .DB "Генератор прямоугольников DG4FAC ATmega8 V1.0", 0x0D .DB "(C) 2006, автор info! At! Avr-asm-tutorial.сеть " .ЕЩЕ .IF cLcdLw == 24 .DB "Генератор Rect M8 V1.0", 0x0D .DB "www.avr-asm-tutorial.net" .ЕЩЕ .IF cLcdLw == 20 .DB "Rect Generator V1.0", 0x0D .DB "avr-asm-tutorial.net" .ЕЩЕ .IF cLcdLw == 16 .DB "Rect-Gen M8 V1.0", 0x0D, "avr-asm-tutorial", 0x00 .ЕЩЕ .DB "RG M8 V1", 0x0D, "avr-asm" .ENDIF .ENDIF .ENDIF .ENDIF .ENDIF .DB 0,0 ; ; ************************************************ ; К О Н В Е Р С И О Н - Т А Б Л Е ; ************************************************ ; .ВКЛЮЧИТЬ "rectgen_m8_table.inc" ;
Одной из наиболее важных особенностей микроконтроллера ATmega8 является то, что, кроме 5 контактов, все остальные контакты могут использоваться для поддержки двух сигналов.
Спящий режим микроконтроллера ATmega8:Микроконтроллер работает в 5 спящих режимах, как указано ниже:
|
Добро пожаловать в MicrochipDirect
- Продукты 8-битные микроконтроллеры 16-битные микроконтроллеры 32-битные микроконтроллеры 32-битные микропроцессоры Аналоговый Управление энергопотреблением Часы и время Высокоскоростная сеть и видео Интерфейс и возможности подключения Драйверы дисплеев и светодиодов Встроенные контроллеры и Super I / O объем памяти Касание и жест Беспроводной ИС безопасности Инструменты разработки Автомобильный класс Запчасти со скидкой Расширенные инструменты выбора продукта
- Услуги по программированию Центр программирования Поиск стоимости программирования Управляйте своими частями программирования Код загрузки Запросить образцы для проверки Утвердить / отклонить подтверждение Разместить производственный заказ Часто задаваемые вопросы по программированию Учебник по программированию
- Цена за объем Запросить ценовое предложение на большое количество Проверить статус предложения / разместить заказ Подать заявку на открытие бизнес-счета Запросить новую кредитную линию или увеличение кредита
- Как мы можем помочь? Часто задаваемые вопросы (FAQ) Поддержка продаж / Свяжитесь с нами Техподдержка Данные экспортного контроля Селектор инструментов разработки Microchip Популярные ссылки
- Быстрый ввод заказа
ATmega8 (A) 로드 — 변환기 (ADC) 관련 레지스터 들
여기 에서는 이전 에 이어서 ACD 에 관련된 레지스터 들 에 대해서 알아 보도록 하겠다.
A / D 변환 결과 는 10 비트 이기 때문에 SFR 두 개가 필요한데 ADCH 과 ADCL 두개 의 레지스터 변환 된 값 이 저장 되는 레지스터 이다. 변환 값 의 상위 바이트 와 하위 ADC 의 최대 분해능 이 10 비트 이기 때문에 이중 에 10 개의 비트 만 이 변환 값 을 저장 하는데 사용 된다. 뒤에 설명 할 ADMUX 레지스터 의 ADLAR 비트 의 값 에 따라 저장 하는 방식 은 두 가지 가 이를 [그림 1] 과 [그림 2] 에 도시 하였다.
[그림 1] ADLAR = ‘0’ 일 때 변환 결과 를 저장 하는 방식 (우측 정렬)
[그림 2] ADLAR = ‘1’ 일 때 변환 결과 를 저장 하는 방식 (좌측 정렬)
변환 값 을 10 비트 모두 사용 하고자 한다면 [그림 1] 과 같이 ADLAR = ‘0’ 으로 설정 한 후 상위 6 개의 비트 는 무시 하고 사용 하면 된다. 하지만, 변환 결과 를 8 비트 만 쓰고 싶을 때에는 [그림 2] 와 같이 ADLAR = ‘1’ 로 설정 한 후 ADCH 값 만을 취하여 사용 하면 된다.이후 로 는 16 비트 메모리 [ADCH: ADCL] 을 줄여서 ADC 라고 표기 한다. A / D 변환 결과 는 다음 과 같은 식 으로 계산할 수 있다.
여기서 Vin 은 선택된 입력 핀 의 전압 값 이고 Vref 는 기준 전압 이다.
ADCSRA (Регистр управления и состояния АЦП) 레지스터 는 ADC 의 전반적인 동작 을 제어 하는 기능 을 수행 한다. 구조 는 다음 과 같다.
[그림 3] ADCSRA 레지스터 의 구조
• ADEN (ADc ENable) 비트 는 ‘1’ 로 설정 해야 ADC 의 모든 동작 이 허용 된다. ‘0’ 으로 설정 하면 ADC 의 모든 동작 이 금지 만약 변환 중에 ‘0’ 으로 클리어 되면 이 즉시 중지 된다.
• ADSC (начальное преобразование АЦП) 비트 가 ‘1’ 로 세트 되면 ADC 가 시작 된다. 연속 변환 모드 에서는 이 비트 가 첫 번째 변환 수행 된 이후 자동 으로 계속 변환 이 수행 된다.ADEN 비트 가 ‘1’ 로 설정된 이후 의 최초 의 변환 ADC 의 초기화 때문에 25 클럭 이 소요 두 번째 변환 부터는 13 클럭 이 소요 된다. 변환 이 진행 중이 라면 이 를 읽으면 ‘1’ 값 이 읽혀 지고 변환 이 완료 되면 ‘0’ 값 으로 되돌아 간다.
• ADFR (выбор ADc Free Running) 비트 는 ADC 를 연속 변환 모드 로 설정 한다. 연속 변환 모드 에서는 ADC 변환 이 자동 으로 연속적 으로 일어나 므로 임의 의 시점 에서 최신 변환 결과 수 있다.
• ADIF (флаг прерывания АЦП) 비트 는 A / D 변환 이 완료 되어 ADC 레지스터 값 이 갱신 ‘1’ 로 세트 되며, 만약 ADIE 비트 ‘1’ 로 라면 요청 하게 된다. 해당 ISR 이 호출 되면 ADIF 비트 는 자동 으로 ‘0’ 으로 리셋 되며, 만약 사용자 가 강제 로 ‘0’ 으로 클리어 하려면 이 ‘1’ 을 주어야 한다.
• ADIE (разрешение прерывания от АЦП) 비트 를 ‘1’ 로 설정 하면 A / D 변환 완료 인터럽트 를 허용 한다.실제로 인터럽트 가 발생 하려면 SREG 레지스터 의 I 비트 가 ‘1’ 로 설정 되어 있어야 한다.
• ADPS2: 0 비트 들은 ADC 에 인가 되는 클럭 의 분주 비 를 선택 한다. A / D 변환기 에서 사용 하는 클럭 은 10 비트 연속 가 정상적으로 수행 되기 위해서 50 ~ 200 кГц 범위 이내 이어야 한다고 데이터 쉬트 에 기록 되어 있다. 따라서 본 실습 키트 의 경우 클럭 이 16 МГц 일 때에는 정상적인 A / D 변환 을 위해서는 <표 8.3.1> 에 표시 한 바와 같이 ADSP2: 0 = ‘110’ 혹은 ADSP2: 0 = ‘111’ 이어야 한다.
단, 10 보다 낮은 분해능 으로 사용할 경우 에는 200 кГц 보다 더 높은 주파수 를 사용할 수 있다고 되어 있다.
[표 1] АЦП 로 인간 되는 클럭 의 분주 비
ADSP2 | ADSP1 | ADSP1 | |||||||
0 | 0 | 0 | 2 | 8,000 кГц | |||||
400000090 | |||||||||
4 900 900 | 2 | 8000 кГц | |||||||
0 | 1 | 0 | 4 | 4,000 кГц 04 | 1 | 8 | 1000 кГц | ||
1 | 9007 80 | 16 | 500 кГц | ||||||
1 | 0 | 1 | 44 | 04 | 44 9001 | 1 | 0 | 64 | 125 кГц |
1 | 40 | 405 кГц |
ADMUX (регистр выбора ADc MUltipleXer) 레지스터 는 ADC 의 입력 핀 을 선택 하는 기능 과 기준 전압원 전압원 선택 하거나 변환 결과 를 레지스터 하는 형식 을 지정 을.
[4] ADMUX 레지스터 의 구조
• REFS1: 0 두 비트 는 A / D 변환 의 기준 전압 을 선택 한다.
[표 2] АЦП 기준 전압 선택
REFS1 | REFS0 | 0 선택 | 4489 AREF 에 인가 되는 전압|||
0 | 1 | AVCC 에 인가 되는 전압 (1) | |||
1 | 0 | 0 | 1 | 1 | 내부 2.56 В 전압 (1) |
(1) AREF 핀 에 외부 전압 을 GND 와 0,1 мкФ 의 커패시터 를 연결할 것.
• ADLAR (результат регулировки ADc влево) 비트 는 ‘1’ 로 설정 되면 A / D 변환 결과 가 ADC 레지스터 에 저장 될 때 <8.2.2> 와 같이 정렬 되고 ‘0’ 으로 설정 되면 <그림 8.2. 1.> 과 같이 정렬 된다.
• MUX3: 0 비트 들은 ADC 의 입력 핀 을 선택 한다. PDIP 는 외부 핀 이 ADC5 번 까지만 있고, TQFP / MLF 패키지 는 ADC7 번 까지 있다.
[표 3] 입력 채널 선택
MUX3: 0 | 단 극성 입력 (односторонний вход) | 0000 비고 | ADC0 | PDIP 패키지 | ||
0001 | ADC1 | |||||
0010 | ADC2 44444444 | 0100 | ADC4 | |||
0101 | ADC5 | |||||
0110 | ADC6 | F000 | ADC6 | F000 | 2 | ADC7 |
1000 ~ 1101 | 9 1189 — | |||||
1110 | 1. |