Третья программа. Выдача данных с АЦП на UARTPrint This Post

Автор DI HALT
Опубликовано 14 Дек 2008 
Рубрики: AVR. Учебный курс
Метки: , , , , ,

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

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

Теоретическую часть я уже разобрал, осталось поставить эксперимент в реальном железе. Эксперимент будем ставить на ранее собранной отладочной плате. Хоть она и больше заточена на обкатку силового блока моего робота, но под наши задачи сгодится — на штыри выведены каналы ADC4 и ADC5, так что заюзаем их.

Осталось только впаять переменный резистор, которым мы будем задавать напряжение. В результате схема принимает вид:

Лирическое отступление, при желании можно его пропустить
Пока резистором, потом что-нибудь поинтересней всобачу, у меня тут по коробочкам много разных радиоэлектронных ништяков сныкано. Тетя Оля, региональный менеджер от компании ST Microelectronics, в свое время, выслала мне много подарков. За что скажем ей дружное спасибо и, из-за моря, помашем ручкой. Не забыв передать привет добрым дядям из Freescale semiconductors и помянем добрым словом службу рассылки Intersil, Analog Device, Kycon и службы доставки FedEX и UPS. О способах добычи ништяковых радиодеталей нахаляву я как нибудь еще обязательно напишу. Пока же, ближе к делу.

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

Также мне потребуется преобразователь UART — RS232, я взял сделанный ранее конвертер на MAX232. Также сгодится китайский USB датакабель на чипе Profilic или что они там сейчас пихают, лишь бы он организовывал в системе виртуальный COM порт. В нем нужно найти линии RxD и TxD

Сам MAX232 у меня смонтирован в разъеме и воткнут в комп. В плату же втыкаются его проводки: Красный на плюс пять вольт, черный на землю, желтый это передача из компа — вешается на вход RXD микроконтроллера. Зеленый же, соответственно, прием. Цепляю его на выход TxD, через него МК будет передавать в комп инфу.

Сам код я тут приводить не буду, выложу его в виде архива с проектом. Прокомментирую лишь его структуру.

Тело основной программы у меня пустое, весь экшн запрятан в обработчики прерываний. А то во всех прошлых примерах я реализовывал ручную обработку UART и тупо ждал ожидания флага. Здесь же, я организовал автоматику.

Итак, прога стартует и вначале выполняет код из файла init.asm (с недавних пор я все проги дроблю на функциональные файлы). В инициализации вначале обнуляетя ОЗУ и все регистры. На всякий случай. Тут совершенно бессмысленно, но, на будущее, знайте что это важно.

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

Обратите внимание на строку:
LDI R16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<TXCIE)
Тут мы указываем, что у нас разрешен прием, передача, а также прерывания от приема. О значениях битов и регистров UART я уже писал ранее.

LDI R16,(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
А тут задаем формат кадра. То есть 8 бит данных, один старт, один стоп. Скорость подсчитана выше с помощью очень удобного макроса. Все, после этой процедуры UART готов к отправке и приему данных.

Достаточно теперь записать что-нибудь в регистр UDR и он тотчас улетит по проводу в комп. А если из компа, что либо будет послано, то процессор метнется на прерывания от UART.

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

В таблице векторов находятся адреса куда процессор аппаратно перейдет при сработке того или иного события. О том как работают прерывания я рассказывал в прошлых уроках.
Находим вектора от UART и вписываем переход с вектора окончания приема. В вектор можно вписать всего одну команду, поэтому втыкаем сюда RJMP UART_RX, а в теле основной программы прописываем метку UART_RX и тут будет обработчик прерывания.

Также пропишем заодно и вектор от АЦПRJMP ADC_OK, один фиг пригодится. Так лазать не придется два раза :)

Возвращаемся в файл инициализации. Следующим пунктом тут идет иницализация АЦП. Сейчас мы только укажем следующие параметры:

OUTI ADMUX,0b01100100

Если рассмотреть засылаемое в ADMUX слово побитно, то получим такую картину:

На этом инициализация периферии закончена. Приступаем к коду.
В обработчике прерывания на прием мы всего лишь определяем что за символ нам пришел. Если это ‘0′ то выключаем АЦП, если не ‘0′, то включаем. Вот так все просто.

OUTI ADCSRA,(1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(1<<ADFR)|(3<<ADPS0)
Данная комбинация битов означает, что:

Подробно расписываться не буду, все было сказано в теоретической части, ну и, конечно, расписано в даташите.

Что произойдет дальше? А ничего особенного. АЦП начнет преобразование, а как только его закончит, то тут же выдаст прерывание и программа ускачет сначала на вектор, а потом, по RJMP на метку ADC_OK, где выковыряет данные из своего регистра и засунет их в UDR — приемный лоток UART. После чего все вернется в наш пустой основной цикл. И так до следующего прерывания от АЦП (процесс то мы запустили непрерывный!) либо пока на вход UART не придет из компа ‘0′ который отключит АЦП 

Запускаем теперь чумовую программку Terminal и, включив режим показа графика начинаем яростно крутить резистор из стороны в стороны, наблюдая как наша кривая описывает зигзаги.

Сложно? Нет! Буквально пара команд, а сколько удовольствия!

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

Головоломка:
Несмотря на то, что прога работает как часы, она написана через задницу. Кто допетрит в чем тут кривость?

Кроме того, обнаружился прикольный глюк! В AVR Studio в эмуляции ATmega8 криво работает АЦП! Т.е. запускаем мы непрерывное преобразование, а в студии оно не запускается. Точне стартует, но лишь один раз. Словно бит ADFR=0. В железе же все работает идеально, как и задумано.

Комментарии

27 комментариев на «Третья программа. Выдача данных с АЦП на UART»


  1. arkamax 14 Дек 2008 2:11

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

    И вообще. Если юзается восьмибитный УАРТ, то ИМХО правильнее писать не так. В обработчике прерывания АЦП скидываем значение в переменную - и ВСЕ. Потом в основном цикле та переменная сливается в УАРТ, но только если завершена предыдущая передача. Т.о. не будет никаких перегрузок пропускной способности УАРТа только из-за скорости АЦП. То же самое можно делать и в обработчике, просто я не любитель растягивать обработчики хоть на один байт больше необходимого.

    DI HALT

    Отправку в УАРТ из переменной можно поручить обработчику конца передачи.


  2. nwanomaly__ 14 Дек 2008 22:46

    недавно наткнулся на uzebox - где чел собрал игрой комп на основе авра.
    вот это я понимаю ) полное изучение возможностей + тетрис под рукой.
    всегда мечтал свой такой изобрести, возможно скоро начну.
    имхо на таком приятней изучать, что и как

    http://belogic.com/uzebox/index.htm

    DI HALT

    Видел я этот комп. Прикольная вещь получилась, ага.


  3. ArgusB 14 Дек 2008 23:56

    А почему бы и нет? Игрались в своё время на синклере? А мега по производительности рвёт z80 как Тузик грелку. Ведь RISC всё-таки. (Хотя, глядя на систему команд z80, систему команд меги трудно назвать сокращённой)

    SWG

    Сделать комп - не проблема. Проблема - программы. Собрав Синклера или хотя бы Микрошу, ты сразу получал доступ к сотням уже готовых программ для них, в том числе и компиляторы Бэйсика, Ассемблера, Форта, редакторы текстовые и графические, игры, и много еще чего. Для Синклера была даже удобная оболочка для загрузки программ, похожая на Нортон Командера. Сделав же свой, не похожий на другие, комп, ты должен будешь писать все это сам, начиная с драйверов клавиатуры, дисплея, джойстиков, графики, и кончая самими играми, редакторами, компиляторами. Даже собрав в 84г свой компьютер, совместимый программно и аппаратно (по основным сигналам шины) с “МИКРО 80″, я уже мог воспользоваться его программой “МОНИТОР”, и BASIC, и Макро Ассемблером, хотя и в 16-ричном коде пописал немало, в основном программки для программаторов. Тогда, в начале пути, это было интересно и вызывало большой энтузиазм. Сейчас, когда без мыша и Виндов вроде и делать нечего, самодельный комп покажется скучной и никчемной железякой. Ну, соединишь между собой пару микросхем и разьемы, подключишь к телевизору, потыркаешься в “TETRIS”. Через неделю все это надоест, и ты закинешь его подальше… И пойдешь опять гонять Фар кри или Контрол страйк.

    nwanomaly__

    точно такие же мысли можно подвести под всё, что тут описывается.
    минироботы на пиках и аврах? в магазине есть уже давно на порядок лучше и по цене доступные. плавают и летают.

    какие-нибудь самодельные осциллографы? хороший hp цифровой - это сказка.

    сенсоры, передатчики, забавные игрушки? так же по пунктам.

    такой миникомп нужен в основном не для игр или ностальжи, а для того, чтобы чел, его собравший, поверил в свои силы. 90% из моих знакомых, кто знает про такое - только на словах могут объяснить, как они легко его соберут.

    зы! кроме того, сделать-придумать узкоспециализированную задачу для такого компа думаю, что не сложно. написать один раз программу и пусть он сидит и тупо с видимокамеры движущихся человечков засекает или из шума голоса нужные гармоники )

    SWG

    Так это и будет не компьютер, а микроконтроллер. И под конкретную задачу его можно хорошо оптимизировать. И почему бы тогда не сделать его в виде робота? Возможностей и интереса будет намного больше, чем просто у коробки на столе, привязанной кабелем к телевизору. Одни мозги, без какой-либо периферии, когда не на что реагировать и нечем управлять - это скучно…

    nwanomaly__

    тогда с роботом тоже надо подходить основательно.
    я помню, как в детстве читал книжки про “это” и ходил в соответствующие кружки. в районе 60-70ых таких роботов делали, что выглядели как роботы )))

    и всякой механики, и научных идей. и всё из подручных элементов. тем бы людям наши вычислительные мощности - они б на луну ракету запустили )

    SWG

    Так и запускали. И не только ракеты, но и пара луноходов месяцами бегали, и пробурили Луну на несколько метров вглубь, и колонку грунта метра три длиной на Землю привезли еще в начале 70х. У американцев в то время была только высадка на Луну, и то до сих пор многие американцы в это не верят, хотя вроде аж несколько человек побывало.
    Потом были полеты к Марсу, Венере, комете Галлея… Кстати, у американцев с Венерой ничего серьезного так и не получилось, и они предпочли более простой и удобный Марс. А Советские аппараты на Венеру опускались, и даже некоторое время работали на поверхности, при 500 градусной температуре.
    Роботу не обязательно выглядеть как человек или роботы из фильмов. Конструкция должна быть рациональной и функциональной. А вот уж над функциональностью стоит повозиться. Робот для одной функции - это просто автомат. Чем их больше - тем интересней, тем “разумней” он будет выглядеть и действовать, тем больше опыта приобретешь. Ну и двухсторонняя связь желательна для интерактивного общения. Он тебе постоянно сообщает о своем состоянии и окружении, ходе выполнения задач, ты даешь ему новые задания…

    nwanomaly__

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

    роботы, которые летали на Венеру - эт хорошо. но я сомневаюсь, что на этом блоге есть больше 2ух человек, кто хотя бы раз удачно запускал своего робота )


  4. YurkaM 15 Дек 2008 16:18

    Было бы “культурней” в обработчике UART сохранять регистор SREG, ибо флаги портятся (командой CPI …). Это хорошо, что в основном цикле пусто, а то были бы глюки.
    И может стоить заметить, что читать ОДНУ половинку ADCx можно только старшую (ADCH). А если бы понадобилась только младшая (допустим если сдвиг вправо), то читать надо обязателно обе и притом сначала ADCL, а потом ADCH.

    DI HALT

    Ну я же говорю все через задницу тут :) По поводу половинок регистра ацп, да, но на то есть теоретическая часть :) Ну и я планирую еще пару практических примеров по АЦП сделать. С алгоритмами усреднения и накопления. Типо программное повышение точности.


  5. YurkaM 15 Дек 2008 16:28

    И, кстати первый коментарий совершенно справедлив. И дело не в скоростях UART и АЦП. У тебя передача по УАРТ в двух местах (эхо при приёме с компа и при завершении АЦП), и в обоих не проверяется его готовность. Могут быть накладки, хотя и не смертельно…

    DI HALT

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


  6. SATS 01 Янв 2009 19:49

    Стоолкнулся вот с такой проблемкой:
    Мое устройство изначально безошибочно работало (не важно , что выполняло)результат пересылало в ПК, но потом я задумал снимать аналоговую велечину. Для проверки АЦП я через реастат подавал напряжения в пределах от 0.2-3.5В на вход ADC0. И Вот что случилось: все замерло. Промучался полдня и не фига не выходит. Есть подозрения, что мог запортачить микруху, но как? разве можно через вход ацп?
    При этом программатор ее не видит и УАРТ перестал код гнать. Сразу скажу, что осцилографа нет.
    Помогите словом. Что случилось?


  7. testicq 04 Фев 2009 17:46

    Можно побробней о USB датакабеле на чипе Profilic. Это куда его тут воткнуть можно? И разве в USB дата-кабелях есть чипы?

    P.S. Описочка:
    “О том что значат быти конфигурации UART”
    д.б. “биты”

    ProgrammerForever

    У меня есть такой кабель. Покупал для своего телефона Motorola E365 (ныне покойного). Купил в стандартном ларьке, торгующими телефонами за 100 рублей. Сам удивился цене. При установки в систему, насколько я помню, создаёт виртуальный COM порт.


  8. DeNn 09 июня 2009 4:45

    Помогите сделать такое же на stk500? Что то у меня не выходит :(
    з.ы. Atmega 8535


  9. ProgrammerForever 18 Дек 2009 4:10

    DI HALT, подскажи, пожалуйста, на чём можно сделать. ТЗ такое: сделать многоканальный вольтметр с подключением по USB. Скорость опроса вольтметра не очень высока: на большинстве каналов хватит 10-20 в секунду; но надо сделать один-два побыстрее для некоего подобия осциллографа в звуковом диапазоне. Число каналов от 4х. А на стороне компа желательно чтобы это всё программами виделось как COM-порт[ы], ибо написано много в Инете про него.

    DI HALT

    На форуме Elementus уже сделал почти такое. Можешь у него спросить, правда он на пиках.

    А так все просто - АЦП опрашивает по очереди каналы и шлет данные в сом порт.


  10. evgen 23 мая 2010 16:14

    Нужна помощь. ниче понять не могу. мега8 работает на 8Мгц от внутреннего генератора. посылаю 2 байта данных с компа по ЮАРТ на скорости 9600 - работает нормально, контроллер шлет их обратно, меняю скорость - бред получаю.

    DI HALT

    Может у тебя срыв стека или кривой выход из прерывания? Или конфликт прерываний. А на скорости 9600 все очень удачно разруливалось само собой?

    Скорость (значение бодрейта) верно высчитал?


  11. evgen 23 мая 2010 16:20

    работаю через FT232RL. может это как-то влияет?

    DI HALT

    Я через фт всегда гнал не обращая внимания на скорость.


  12. evgen 23 мая 2010 16:59

    с мегой 16 та же фигня. на 9600 шлет с Ацп по юарту на terminal четко, а на других скоростях такое гонит. надо бы через настоящий com посмотреть, а не через FT232.


  13. evgen 23 мая 2010 19:13

    Все понял. На медленных скоростях, до 38400, и без кварца все нормально, а вот на высоких - гонево. Поставил кварц заточенный под ЮАРТ - 7.3728 Мгц- и все прет как надо на 115200.

Оставьте свой отзыв

Вы должны войти, чтобы оставлять комментарии.


Материалы сайта являются авторскими. Копирование и публикация материалов без активной ссылки на первоисточник запрещено.

Реклама: