AVR401: 8-ми битный прецизионный аналого-цифровой преобразователь
Здесь находятся подпрограммы описанные в документе, а также программа примера, на ассемблере. (можно просматривать блокнотом)
AVR401: 8-ми битный прецизионный аналого-цифровой преобразователь
Оригинал: Application Note AVR401 фирмы ATMEL
перевел: Sinbad г.Самара. 20.10.2000 г
Особенности
- Очень низкая стоимость
- Высокая точность
- Авто-калибровка устраняет погрешность, вызываемую элементной базой
- Измерение напряжения от 0 до Vcc
- Максимальное время преобразования: 1,1 ms
Это приложение описывает, как сделать так называемый А/Ц преобразователь с двойным интегрированием на основе AVR микроконтроллера. Преобразователь очень дешевый, требуется только шесть дискретных компонентов плюс AVR. Используется пять выводов контроллера (см. рисунок 1). Этот пример базируется на AT90S1200, но может использоваться любой AVR контроллер с компаратором.
Рисунок 1. А/Ц преобразователь
Принцип работы
Конденсатор заряжается постоянным током, формируемым транзистором. И напряжение на конденсаторе возрастает линейно. Для разрядки конденсатора, вывод AIN0 устанавливается как выход выдающий "ноль". Опорное напряжение равное Vcc/2 формируется цепочкой резисторов Rref1 и Rref2. Когда выводы PB1 и PB2 сконфигурированы как входы, опорное напряжение отключено, и напряжение на выводе AIN1 будет входным напряжением Vin. При установке выводов как выходы и выдаче "0" и "1", уровень напряжения на выводе AIN1 будет VCC/2 (если резисторы одинаковые). Входной резистор Rin должен быть минимум в 100 раз больше чем опорные резисторы Rref1 и Rref2 , чтобы избежать погрешностей измерений.
Алгоритм, используемый для преобразования следующий:
- Включить опорное напряжение
- Зарядить конденсатор до тех пор, пока напряжение на нем не достигнет опорного. Измерить время необходимое для этого, Tref.
- Выключить опорное напряжение и разрядить конденсатор
- Зарядить конденсатор до тех пор, пока напряжение на нем достигнет входного.
Измерить время необходимое для этого, Tin.
Предположим, что Vcc 5 вольт. Отношение между входным и опорным напряжениями: Выражение 1 Vin = Vref x Tin / Tref Идеальный результат преобразования это 8-ми битное число, где 0 вольт соответствует 0, а 5 вольтам соответствует 255. Опорному напряжению соответствует, таким образом, 128. Равенство может быть переписано как: Выражение 2 Vin = Tin x 128 / Tref Однако из-за погрешностей опорных сопротивлений, опорное напряжение может слегка отличаться. Для компенсации этого, можно выполнить калибровку, подав известное напряжение на вход и сравнить его с опорным. Если используемое калибровочное напряжение равно точно 2,5 вольт, опорное напряжение может быть найдено с помощью выражения: Выражение 3 Vref = Tref x Vcal / T cal = Tref x 128 / Tcal Цикл калибровки выполняется при удержании низкого уровня на выводе PB7 при включении питания. Затем подается калибровочное напряжение, и вывод PB7 освобождается. Это запускает калибровку и после однократного выполнения, значение опорного напряжения сохраняется в EEPROM. Во время нормального преобразования, опорное напряжение считывается из EEPROM, и входное напряжение вычисляется по выражению 1. Пример конфигурации
Так как выдаваемый результат 8-ми битный, таймер должен быть минимум 9-ти битным для обеспечения необходимого разрешения. Элементы должны быть подобраны так чтобы номинальное время зарядки конденсатора до Vcc было около 256 тактов. В этом случае погрешности значений элементов и изменение температуры позволяют не делать время зарядки больше, чем максимальный период таймера, или же значительно меньше, давая низкое разрешение.
Для достижения необходимой точности должна использоваться разрядность 8 или выше. Таймер в AT90S1200 только 8-ми битный, так что 9-ый бит должен учитываться программно. Следующий пример показывает, как можно найти номиналы элементов. Сначала, решите, какую частоту кварцевого генератора использовать. С 4 МГц кварцем длительность такта - 250 нс. При установке предварительного делителя CK/8, таймер увеличивается каждые 2 мкс. Максимальный период таймера при 9 битах равен 512 х 2 мкс = 1,024 мс. Исходя из этого, мы берем 2 х Tref равное 512 мс. Зарядка конденсатора постоянным током описывается выражением: Выражение 4 dV = I/C x dt Мы можем найти требуемый ток, когда емкость конденсатора, приращение времени и напряжения известны: Выражение 5 I = dV x C / dt Конденсатор будет заряжен до 5 вольт, и при емкости 0,22 мкФ, транзистор должен выдавать ток 2,15 мА. Значение R зависит от hFE транзистора. У pnp транзистора BC558A hFE находиться между 125 и 250. Это делает данный транзистор идеальным для применения, так как может использоваться любое значение hFE в указанном диапазоне. Чтобы быть уверенным, что может быть использован весь диапазон hFE, в вычислениях используем среднее значение, 188. В результате ток базы равен 11,4 мкА. Транзистор включается выдачей "0" на соответствующем выводе. При данном значении тока, напряжение база-эмиттер транзистора около 0,1 В. Базовый резистор находится как: Равенство 6 R B = ( Vcc + Vbe )/ Ib = 4.9 В/11.4 мкА = 430 кОм Опорное напряжение вырабатывается делителем R ref1 и R ref2. R in должен быть значительно больше, чем эти два, так чтобы входное напряжение не влияло на опорное. Подходят R in - 100 кОм и 1 кОм - R ref1 и R ref2 каждый. Транзистор должен быть подключен к выводам как можно дальше от входов компаратора. При переключении выводов, шумовые помехи появляются на соседних выводах.
Это может вызвать проблемы при измерении маленьких напряжений, так как помехи могут переключить компаратор до того, как напряжение на конденсаторе достигнет измеряемого. Рисунок 3 показывает характеристику преобразования устройства с тактовой частотой 4 МГц, использующего значения элементов рассчитанные в выше приведенном примере. Рисунок 3. Линейность преобразования
Исполнение
Программное обеспечение состоит из нескольких подпрограмм. Подпрограммы "reference" и "convert" управляют зарядкой и синхронизацией. После того, как они полностью выполнены, основная программа должна выполнить необходимые вычисления. Это происходит с помощью двух подпрограмм, осуществляющих деление и умножение, "div17u" и "mul9". Есть также две задержки, используемые другими подпрограммами и основной программой. Они используются для полного разряда конденсатора и формирования паузы между преобразованиями. Подпрограмма "reference" - измерение опорного напряжения
Подпрограмма разряжает конденсатор, включает транзистор и заряжает конденсатор до тех пор, пока напряжение на нем не сравняется с опорным напряжением. Измеряется время от начала зарядки до момента совпадения напряжений. Затем конденсатор снова разряжается. Это время зарядки используется вместе со временем зарядки из подпрограммы "convert" для вычисления входного напряжения. Подпрограмма не должна вызываться при каждом преобразовании, все зависит от изменения окружающей температуры. Особенно сильно от температуры зависит параметр транзистора hFE, так что если окружающая температура изменятся, подпрограмма должна выполняться часто. В примере программы, подпрограмма"reference" вызывается при выполнении каждого преобразования. Рисунок 4. Блок схема "reference"
Таблица 1. Параметры подпрограммы "reference"
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
24 слова |
Выполняемые циклы |
Зависят от опорного напряжения |
Используемые регистры |
|
b> Таблица 2. Регистры используемые "reference"
РЕГИСТР |
НА ВХОДЕ |
ВНУТРИ |
НА ВЫХОДЕ |
R17 |
"Tref"-содержит время достижения опорного напряжения | ||
R18 |
"TH" - старшая часть таймера |
||
R20 |
"temp" |
Подпрограмма включает транзистор и заряжает конденсатор до тех пор, пока напряжение на нем не сравняется с входным напряжением. Затем конденсатор разряжается. Время необходимое для этого измеряется и сохраняется в T in. Здесь должна быть пауза в несколько микросекунд между двумя циклами преобразования, чтобы быть уверенным, что конденсатор полностью разряжен. В примере программы это осуществляется вызовом подпрограммы задержки. Рисунок 5. Блок схема подпрограммы "input"
Таблица 3. Параметры подпрограммы "input"
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
19 слов |
Выполняемые циклы |
Зависят от входного напряжения |
Используемые регистры |
|
РЕГИСТР |
НА ВХОДЕ |
ВНУТРИ |
НА ВЫХОДЕ |
R14 |
"TinH" - старший байт времени зарядки до входного напряжения | ||
R15 |
"TinL" - младший байт времени зарядки до входного напряжения | ||
R20 |
"temp" |
Единственная функция этой подпрограммы увеличение переменной TH, чтобы получился 16-ти битный счетчик. Используется только 9 бит. Таблица 5. . Характеристики подпрограммы прерывания "T0_int"
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
2 слова |
Выполняемые циклы |
9 - вместе с инструкцией RETI |
Используемые регистры |
|
Эта подпрограмма выполняет умножение 9х8 бит. 9-ти битный множитель должен быть сохранен во флаге переноса (MSB) и в регистре "mp9u". 8-ми битный множитель сохраняется в регистре "mc9u".
Результат располагается в "C:m9uH:m9uL". Регистры, используемые для результата те же самые, что используются как входные в подпрограмме деления. Подпрограмма основана на подпрограмме умножения "mpy8u", описанной в приложении AVR 200 (прим. "application note AVR 200" на сайте ATMEL). Таблица 6. Параметры подпрограммы "mpy9u"
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
11 слов |
Выполняемые циклы |
83 |
Используемые регистры |
|
РЕГИСТР |
НА ВХОДЕ |
ВНУТРИ |
НА ВЫХОДЕ |
R0 |
"mc9u" - множитель |
||
R1 |
"mp9u" - множитель |
m9uL - младший байт результата | |
R2 |
m9uH - старший байт результата | ||
C - Флаг |
9-тый бит множителя |
17-тый бит результата | |
R20 |
"temp"-используется как счетчик циклов |
Эта подпрограмма выполняет умножение 9х8 бит. 9-ти битный множитель должен быть сохранен во флаге переноса (MSB) и в регистре "mp9u". 8-ми битный множитель сохраняется в регистре "mc9u". Результат располагается в "C:m9uH:m9uL". Регистры, используемые для результата те же самые, что используются как входные в подпрограмме деления. Подпрограмма основана на подпрограмме умножения "mpy8u", описанной в приложении AVR 200 (прим. "application note AVR 200" на сайте ATMEL). Таблица 8. Параметры подпрограммы "div17u"
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
18 слов |
Выполняемые циклы |
209 минимум, 292 максимум |
Используемые регистры |
|
РЕГИСТР |
НА ВХОДЕ |
ВНУТРИ |
НА ВЫХОДЕ |
R1 |
"didL" - младший байт делимого |
"dresL" - младший байт результата | |
R2 |
"didH" - старший байт делимого |
"dresH" - старший байт результата | |
R3 |
"divL" - младший байт делителя |
||
C - Флаг |
17-тый бит делимого |
||
R4 |
"divH" - старший байт делителя |
||
R5 |
"remL" - младший байт остатка | ||
R6 |
"remH" - старший байт остатка |
b> Пример программы
Запущенная программа примера выполняет повторяющиеся преобразования. Сначала измеряется время зарядки для опорного напряжения, затем для входного. Результат преобразования выводится в Порт D и 7 вывод Порта В (MSB). Результат инвертируется перед выдачей, так что для демонстрации результата могут быть подключены светодиодные индикаторы с общим катодом. Цикл преобразования повторяется бесконечно. Если при включении питания вывод PB7 подключен к массе, выполняется калибровка. Пользователь должен подать 2,5 вольта на вход перед освобождением вывода PB7. Откалиброванное V ref сохраняется в EEPROM, откуда считывается при каждом нормальном включении питания. Таблица 10..Общие параметры
ПАРАМЕТР |
ЗНАЧЕНИЕ |
Размер кода |
43 слова - только подпрограммы преобразования (без mpy9u и div17u) 147 слов - все приложение |
Выполняемые циклы |
209 минимум, 292 максимум |
Используемые регистры |
|
Используемые прерывания | Прерывание переполнения таймера/счетчика 0 Прерывание аналогового компаратора |
Используемая периферия | Таймер/Счетчик 0 Аналоговый компаратор Порт B, выводы от 0 до 3 и вывод 7 Порт D, все выводы (только в программе примера) Порт B, вывод 4 (только в программе примера) |
Подпрограмма калибровки может быть пропущена, если измерены только относительные значения. Опорное напряжение тогда берется равным "128", что также упрощает вычисления. Опорная цепь может быть заменена опорным напряжением для получения более высокой точности. Тогда возможно измерение изменений Vcc, подключая через делитель напряжения питания ко входу.