AVR. Учебный курс. Устройство и работа портов ввода-вывода

Распечатать

С внешним миром микроконтроллер общается через порты ввода вывода. Схема порта ввода вывода указана в даташите:

Но новичку там разобраться довольно сложно. Поэтому я ее несколько упростил:

Итак, что же представляет собой один вывод микроконтроллера. Вначале на входе стоит небольшая защита из диодов, она призвана защитить ввод микроконтроллера от превышения напряжения. Если напряжение будет выше питания, то верхний диод откроется и это напряжение будет стравлено на шину питания, где с ним будет уже бороться источник питания и его фильтры. Если на ввод попадет отрицательное (ниже нулевого уровня) напряжение, то оно будет нейтрализовано через нижний диод и погасится на землю. Впрочем, диоды там хилые и защита эта помогает только от микроскопических импульсов от помех. Если же ты по ошибке вкачаешь в ножку микроконтроллера вольт 6-7 при 5 вольтах питания, то никакой диод его не спасет.

Конденсатор, нарисованный пунктиром, это паразитная емкость вывода. Хоть она и крошечная, но присутствует. Обычно ее не учитывают, но она есть. Не забивай голову, просто знай это, как нибудь я тебе даже покажу как её можно применить ;)

Дальше идут ключи управления. Это я их нарисовал рубильниками, на самом деле там стоят полевые транзисторы, но особой сути это не меняет. А рубильники наглядней.
Каждый рубильник подчинен логическому условию которое я подписал на рисунке. Когда условие выполняется — ключ замыкается. PIN, PORT, DDR это регистры конфигурации порта.

Есть в каждом контроллере AVRPIC есть тоже подобные регистры, только звать их по другому).

Например, смотри в даташите на цоколевку микросхемы:

Видишь у каждой почти ножки есть обозначение Pxx. Например, PB4 где буква «B» означает имя порта, а цифра — номер бита в порту. За порт «B» отвечают три восьмиразрядных регистра PORTB, PINB, DDRB, а каждый бит в этом регистре отвечает за соответствующую ножку порта. За порт «А» таким же образом отвечают PORTA, DDRA, PINA.

PINх
Это регистр чтения. Из него можно только читать. В регистре PINx содержится информация о реальном текущем логическом уровне на выводах порта. Вне зависимости от настроек порта. Так что если хотим узнать что у нас на входе — читаем соответствующий бит регистра PINx Причем существует две границы: граница гарантированного нуля и граница гарантированной единицы — пороги за которыми мы можем однозначно четко определить текущий логический уровень. Для пятивольтового питания это 1.4 и 1.8 вольт соответственно. То есть при снижении напряжения от максимума до минимума бит в регистре PIN переключится с 1 на 0 только при снижении напруги ниже 1.4 вольт, а вот когда напруга нарастает от минимума до максимума переключение бита с 0 на 1 будет только по достижении напряжения в 1.8 вольта. То есть возникает гистерезис переключения с 0 на 1, что исключает хаотичные переключения под действием помех и наводок, а также исключает ошибочное считывание логического уровня между порогами переключения.

При снижении напряжения питания разумеется эти пороги также снижаются, график зависимости порогов переключения от питающего напряжения можно найти в даташите.

DDRx
Это регистр направления порта. Порт в конкретный момент времени может быть либо входом либо выходом (но для состояния битов PIN это значения не имеет. Читать из PIN реальное значение можно всегда).

  • DDRxy=0 — вывод работает как ВХОД.
  • DDRxy=1 вывод работает на ВЫХОД.

PORTx
Режим управления состоянием вывода. Когда мы настраиваем вывод на вход, то от PORT зависит тип входа (Hi-Z или PullUp, об этом чуть ниже).
Когда ножка настроена на выход, то значение соответствующего бита в регистре PORTx определяет состояние вывода. Если PORTxy=1 то на выводе лог1, если PORTxy=0 то на выводе лог0.
Когда ножка настроена на вход, то если PORTxy=0, то вывод в режиме Hi-Z. Если PORTxy=1 то вывод в режиме PullUp с подтяжкой резистором в 100к до питания.

Есть еще бит PUD (PullUp Disable) в регистре SFIOR он запрещает включение подтяжки сразу для всех портов. По дефолту он равен 0. Честно говоря, я даже не знаю нафиг он нужен — ни разу не доводилось его применять и даже не представляю себе ситуацию когда бы мне надо было запретить использование подтяжки сразу для всех портов. Ну да ладно, инженерам Atmel видней, просто знай что такой бит есть. Мало ли, вдруг будешь чужую прошивку ковырять и увидишь что у тебя подтяжка не работает, а вроде как должна. Тогда слазаешь и проверишь этот бит, вдруг автор прошивки заранее где то его сбросил.

Общая картина работы порта показана на рисунке:

Теперь кратко о режимах:

  • Режим выхода
    Ну тут, думаю, все понятно — если нам надо выдать в порт 1 мы включаем порт на выход (DDRxy=1) и записываем в PORTxy единицу — при этом замыкается верхний ключ и на выводе появляется напряжение близкое к питанию. А если надо ноль, то в PORTxy записываем 0 и открывается уже нижний вентиль, что дает на выводе около нуля вольт.
  • Вход Hi-Z — режим высокоимпендансного входа.
    Этот режим включен по умолчанию. Все вентили разомкнуты, а сопротивление порта очень велико. В принципе, по сравнению с другими режимами, можно его считать бесконечностью. То есть электрически вывод как бы вообще никуда не подключен и ни на что не влияет. Но! При этом он постоянно считывает свое состояние в регистр PIN и мы всегда можем узнать что у нас на входе — единица или ноль. Этот режим хорош для прослушивания какой либо шины данных, т.к. он не оказывает на шину никакого влияния. А что будет если вход висит в воздухе? А в этом случае напряжение будет на нем скакать в зависимости от внешних наводок, электромагнитных помех и вообще от фазы луны и погоды на Марсе (идеальный способ нарубить случайных чисел!). Очень часто на порту в этом случае нестабильный синус 50Гц — наводка от сети 220В, а в регистре PIN будет меняться 0 и 1 с частотой около 50Гц
  • Вход PullUp — вход с подтяжкой.
    При DDRxy=0 и PORTxy=1 замыкается ключ подтяжки и к линии подключается резистор в 100кОм, что моментально приводит неподключенную никуда линию в состояние лог1. Цель подтяжки очевидна — недопустить хаотичного изменения состояния на входе под действием наводок. Но если на входе появится логический ноль (замыкание линии на землю кнопкой или другим микроконтроллером/микросхемой), то слабый 100кОмный резистор не сможет удерживать напряжение на линии на уровне лог1 и на входе будет нуль.

Также почти каждая ножка имеет дополнительные функции. На распиновке они подписаны в скобках. Это могут быть выводы приемопередатчиков, разные последовательные интерфейсы, аналоговые входы, выходы ШИМ генераторов. Да чего там только нет. По умолчанию все эти функции отключены, а вывод управляется исключительно парой DDR и PORT, но если включить какую-либо дополнительную функцию, то тут уже управление может полностью или частично перейти под контроль периферийного устройства и тогда хоть запишись в DDR/PORT — ничего не изменится. До тех пор пока не выключишь периферию занимающую эти выводы.
Например, приемник USART. Стоит только выставить бит разрешения приема RXEN как вывод RxD, как бы он ни был настроен до этого, переходит в режим входа.

Совет:
С целью снижения энергопотребления и повышения надежности рекомендуется все неиспользованные пины включить в режим PullUp тогда их не будет дергать туда сюда помехой, а если на порт свалится грубая сила (например, монтажник отвертку уронит и коротнет на землю) то линия не выгорит.

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

Итак:

  • Самый безопасный для МК и схемы, ни на что не влияющий режим это Hi-Z.
  • Очевидно что этот режим и должен быть по дефолту.
  • Значения большинства портов I/O при включении питания/сбросе = 0х00, PORT и DDR не исключение.
  • Соответственно когда DDR=0 и PORT=0 это High-Z — самый безопасный режим, оптимальный при старте.
  • Hi-Z это вход, значит при DDR=0 нога настроена на вход. Запомнили.
  • Однако, если DDR=0 — вход, то что будет если PORT переключить в 1?
  • Очевидно, что будет другой режим входа. Какой? Pullup, другого не дано! Логично? Логично. Запомнили.
  • Раз дефолтный режим был входом и одновременно в регистрах нуль, то для того, чтобы настроить вывод на выход надо в DDR записать 1.
  • Ну, а состояние выхода уже соответствует регистру PORT — высокий это 1, низкий это 0.
  • Читаем же из регистра PIN.

Есть еще один способ, мнемонический:
1 похожа на стрелку. Стрелка выходящая из МК — выход. Значит DDR=1 это выход! 0 похож на гнездо, дырку — вход! Резистор подтяжки дает в висящем порту единичку, значит PORT в режиме Pullup должен быть в единичке!

Все просто! :)

Для детей в картинках и комиксах :)
Для большей ясности с режимами приведу образный пример:

Уровень напряжения на выводе словно планка, которая может двигаться вертикально вверх или вниз. В режиме Hi-Z мы можем на эту планку только смотреть, а двигать или как то на нее воздействовать мы не можем. Поэтому любая помеха может ее дрыгать как угодно, но зато если мы ее куда прицепим, то ее уровень будет зависеть только от другой цепи и ей мы не помешаем.

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

В режиме OUT у нас планка прибита гвоздями к земле или прижата домкратом к питанию. Внешняя сила может ее пересилить только сломав домкрат или сломается сама. Тупая внешняя сила просто разрушает наш домкрат или вырывает гвозди из пола с мясом. В любом случае — девайс в помойку.

Запись опубликована в рубрике AVR. Учебный курс с метками , , , , . Добавьте в закладки постоянную ссылку.

103 комментария: AVR. Учебный курс. Устройство и работа портов ввода-вывода

  1. pkm говорит:

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

  2. Werewolf-Prankster говорит:

    А-а-а-а! Комиксы — круто! :)

    Кстати, спасибо большое, за то что объяснил что такое Hi-Z, а то я долго вкурить не мог.

  3. Lerman говорит:

    Вот ножка AVR одной картинкой упрощенно http://s48.radikal.ru/i120/0908/e5/8099e6d45399.gif

    У некоторый AVR запись «1″ в PIXx.n меняет уровень на выходе.

  4. levantine говорит:

    Жжош!!! Над картинками рыдал.)

  5. Medved говорит:

    Бугага!! аффтар нереально отжог с комексами! =)))) упячко-мэн понравилсо =) +1024 аффтару

  6. Melted Metal говорит:

    Рыдал пацтулом))) Особенно над помехой =)

  7. Melted Metal говорит:

    Кстати, почему на ПИКах почти ничего не делают, а вот раздел про АВР содержит стопицот тем?

    • SWG говорит:

      А это смотря что искать. У меня в «избранном» ссылок по PIC куда больше, чем по ATMEL.
      А вообще — то я использую и те, и те. Смотря что удобней, или при повторении чего-то готового, когда переделывать лень. Атмеловские контроллеры мне понятны, потому что я в 80-90х годах много работал с MCS 48, предком MCS 51, и по 51 тоже читал в то время много, ну а PIC сами по себе хороши… Другое дело — по конкретным сайтам, там обычно уклон в ту или иную сторону. Этот, например, начинался как учебник по AVR, что и определило соответственно посетителей. Но есть немало и работающих с PIC.
      А если смотреть, например, по моему архиву сохраненных страничек лет за 10, конструкций на PIC гораздо больше. Как и программаторов для них.

    • DI HALT говорит:

      ИМХО AVR немного проще для программирования. Ну а у меня по PIC ничего нет т.к. я плохо знаю этот МК и никогда особо не загонялся по нему.

  8. tchicago говорит:

    Хорошие учебные материалы, только я бы нецензур поубирал.

  9. Levsha100 говорит:

    Афтар жжот не подетски :)))
    Хотя, возможно, скоро эти картинки и пригодятся, когда в детском садике будут обучать программирования МК :)))))

  10. kry-love говорит:

    Привет, DI! Немного оффтоп, но тоже про IO: задумал я сделать примитивный софтовый уарт чтоб юзать его на милипиздрических тиньках типа 10й или 12й. Однакопришла мысль, что таким макаром можно сделать только полудуплекс, ибо одновременно на вход и выход порт работать не может. Или все-таки с ноги порта, настроенного на выход, можно читать уровни, подаваемые извне?

  11. Vitaha говорит:

    На Пиках значение регистра направления порта (TRIS) проще запомнить:
    выход = 0 (лог. ноль) от англ. «O»utput
    вход = 1 (лог. единица) от англ. «I»nput
    Вот это я понимаю, красиво и логично, а на AVR вывернули наизнанку

    • SWG говорит:

      Кроме того, в PIC удобнее работать с портами. Не надо разделять порт на регистры для чтения и записи. В любой команде просто указываем, например, Port B. Мало того, с портом можно делать любые логические и арифметические операции, как и с любым другим регистром. У PIC вообще нет отдельно выделенных регистров «Общего назначения» как таковых, которых вечно нехватает, да еще при прерываниях или вызове подпрограмм их надо сохранять в стеке, потом не забыть извлекать обратно, причем в порядке, обратном загрузке. Все регистры равноправны — ОЗУ, порты, регистры управления… Можно с любым делать любые операции, как байтовые, так и битовые, а также проверять любой бит с последующим условным переходом. Потому у PIC и команд всего 33 — 35 — 37 от младшего семейства до старшего, что все команды работают одинаково со всеми регистрами. А у AVR десятки одинаковых команд, но работающих только с определенными группами регистров или с каким-нибудь видом адресации. После дизассемблирования листинг хрен поймешь, с каждой командой отдельно приходится разбираться. А еще говорят, что AVR проще программировать…

      • Vitaha говорит:

        Коллега, я вас поддерживаю на все 100! Развяжем холиварчик PIC vs AVR? :)
        В ранних пиках была проблемка при записи в порт — там выполнялась процедура чтение-модификация-запись. Т.е. записали в порт 1, потом с портом провели какой AND или XOR, и если порт сильно нагружен (т.е. «просажен» нагрузкой), то прочитается не 1, а 0. В пиках поновее поэтому уже имеем 3 регистра работы с портами: TRISx (регистр направления порта), PORTx (регистр порта) и LATx (защёлка порта).

        • SWG говорит:

          «“просажен” нагрузкой» — В нормально спроектированной схеме такого быть не должно по определению. Что же это за нагрузка, которая просаживает порт так, что его логический уровень меняется на противоположный? И почему тогда не поставили какой — нибудь буферный усилитель? Для того в даташитах и указывают нагрузочные параметры, чтобы их соблюдать… Другое дело, что если записали в порт какое — то значение, затем часть линий перевели на ввод, выполнили логическую операцию с портом, в ходе которой как раз и произойдет чтение — модификация — запись, потом опять захотели использовать записанное ранее в защелке — так и коту понятно, что оно изменилось, что вытекает из логики работы порта в таких случаях. Так за этим должен следить сам программист, и сохранять где — нибудь значение, которое было записано в порт, если оно будет нужно в дальнейшем. Опять же, фирменные мануалы постоянно об этом напоминают.

          • Vitaha говорит:

            Если схема достаточно сложна, то нормально её спроектировать нет никакой возможности — на это есть и формальная теорема, что достаточно сложные системы отладить на 100% никак нельзя (название забыл). Поэтому и приходится делать макетки, а не заказывать сразу печатки, а также ловить баги и прочее. Да и от импульсных помех и иголок по питанию мало кто застрахован. Вот потом сидишь и чешешь репу — это аппаратный прикол, или опять где в коде накосячил? Ну а в общем с Вами согласен.

          • SWG говорит:

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

          • IDOL 1234 говорит:

            А я-то думал, отчего меня с упячки так глючит. Оказывается, помехи…

        • DI HALT говорит:

          А зачем там LATx?

          • SWG говорит:

            Понятия не имею. Мне такие не попадались. Обычно защелка порта реализована аппаратно, чего еще городить?

      • DI HALT говорит:

        Раз там все так равноправно, то на кой черт там регистр W судя по ассемблеру все операции идут исключительно через него. Или я ошибаюсь?

        • SWG говорит:

          «на кой черт там регистр W» — так это типичный регистр — аккумулятор. Есть в любом процессоре (например, в 8080 — регистр A). Как же без него? куда грузить переменные, константы, временно хранить результаты операций, к чему привязать флаги статуса? Он и у AVR есть. Ты наверное имеешь в виду, что в PIC нельзя, например, сложить сразу регистр с регистром? Так это и в AVR можно далеко не со всяким регистром. А расширенная функциональность небольшой группы «регистров общего назначения» в AVR сводится на нет убогостью операций со всеми остальными. В PIC же я могу одной командой, например, установить или сбросить бит ЛЮБОГО регистра (и ячейки ОЗУ, и порта, и регистров управления), причем без предварительной пересылки в аккумулятор и обратно, сделать условный переход по состоянию любого бита ЛЮБОГО регистра (то есть, и всего ОЗУ!). Команды, использующие аккумулятор (регистр W), имеют возможность сохранить результат или в аккумуляторе, или в другом регистре, участвующем в операции. Это очень удобно, сокращает количество пересылок, а также позволяет делать операции (например, используя маски), не меняя содержимого самого регистра, или наоборот, сохраняя в нем сразу результат. Я много работал с ассемблером I8080 и I8048, немного изучал также Мотороловский M6800 с двумя аккумуляторами (A и B), а также использовавшийся в Эплах 6502, работаю немного и с AVR, и в сравнении с ними PIC мне представляются довольно удобными. Просто с ними надо поработать, чтобы оценить их гениальную простоту. А на языке высокого уровня, например, МикроПаскале, так и вовсе нет особой разницы, для PIC или AVR писать. Хотя одна и та же программа на PIC получается короче, и 8к байт программной памяти Меги 8 и 8 к слов PIC16F876 — большая разница в пользу PIC (у него все команды = 1 слово), хотя по набору периферии они примерно одинаковы. (Но предделитель таймера PIC при подаче сигнала с внешнего вывода способен работать до 70-80МГц, независимо от частоты самого PIC!).
          Обычно считают, что на AVR 1 команда = 1 такт. Хрен там! Это только за счет конвейера, и только на линейной последовательности команд. А попробуйте сделать переход, вызов подпрограммы, или вход в обработчик прерывания… Плюс еще неизбежная возня со стеком для сохранения некоторых регистров «общего назначения», которых вечно для всех задач не хватает. В PIC кроме аккумулятора и слова состояния сохранять ничего не надо, у него регистры — все ОЗУ, просто каждая подпрограмма использует свои, не перекрываясь. Кроме того, стек не отьедает кусок ОЗУ, и не проедется по нему при малейшем сбое, сметая все содержимое… Да много еще чего…

          • DI HALT говорит:

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

          • SWG говорит:

            «В AVR нет аккумулятора». В исходном MCS 51 (I8051), акумулятор был в явном виде (регистр ACC). В AVR его функции раскидали на блок из 32 универсальных регистров, причем неравномерно. Можно считать, что там 32 аккумулятора, но это не совсем так, из за их разной функциональности. Поэтому я и продолжаю считать, что там тоже есть аккумулятор (просто так мне привычнее, для совместимости с другими контроллерами).
            Кроме того, есть деление на регистровый файл, служебные регистры или «память ввода-вывода», статическое ОЗУ (SRAM). В PIC же практически все это — просто регистры, без явного разграничения с точки зрения выполняемых с ними операций в командах. В любой команде, работающей с регистрами, может использоваться любой из 7F регистров текущего банка, независимо, регистр ли это порта, управляющий регистр, или область ОЗУ.

          • DI HALT говорит:

            AVR ближе к Load/Store архитектуре. Его 32 регистра это именно как аккумулятор. Зато ОЗУ может быть слоноподобного размера и обращение задается к ней через индексы. Не нужно переключать банки, работает с ОЗУ как с куском.

            Переход по битам из IO тоже возможен (кроме последних АВР, где число периферии уже таково, что адресация IO не влазит в разрядность команды и приходится через Load/Store орудовать, впрочем, команды проверки бита в регистре (любом) это нивелируют.

            Я так обычно 32 регистра юзаю как сплошной Temp, а при входе и выходе делаю массивный прогруз из ОЗУ. Либо через стек.

          • SWG говорит:

            Все дело в привычке. Но в каждой архитектуре есть свои плюсы и минусы. И если PIC и AVR идут в моих предпочтениях довольно близко друг к другу, то с другими фирмами — отрыв огромный. Сколько ни просматривал их контроллеры — отрыв большой, никогда не возникало желания их использовать. Уж больно они все какие — однобокие, заточенные под свои, узкие, сферы применения. В свое время Микрочиз нашел удачное сочетание свойств, периферии, достаточно полное, но без избыточности. АТМЕЛ это удачно использовало, но на базе другого популярного ядра. Результат на лице.
            Работа с ОЗУ огромного размера, в большинстве существующих моделей AVR реально отсутствующего, и соизмеримого по реально установленному обьему с ОЗУ в аналогичных по функциональности PIC, не кажется такой уж необходимой. Работа же с банками тоже не так сложна, как кажется. В простых случаях вообще хватает одного банка, в более сложных обычно используется язык высокого уровня, который берет на себя эту проблему. Кроме того, есть 16 регистров ОЗУ в верху, адресуемых из любого банка. В них удобно сохранять, например, аккумулятр и регистр статуса при входе в обработчик прерывания, и глобальные переменные, доступных из любого места программы.
            Зато в PIC практически не приходится работать со стеком. Там нечего хранить, кроме адреса возврата, а это делается автоматически, поэтому 8 уровней — за глаза. Тем более компилятор постоянно следит за количеством вложений (по крайней мере те компиляторы, что я использую).

  12. skadi.exe говорит:

    Ну елки, 4 комбинации 2 бит запомнить так тяжело…
    Но для начала курса — в самый раз.

    • DI HALT говорит:

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

  13. VBKesha говорит:

    Да кратинки прикольные 5.

  14. SIM говорит:

    Еще можно уточнить что втекающий ток максимальный выще чем вытекающий (немного), и разные порты имеют разную мощность. Актуально если кто хочет снимать по 20 ма с каждой ноги:

    PDIP Package:

    1] The sum of all IOL, for all ports, should not exceed 400 mA.
    2] The sum of all IOL, for ports C0 — C5 should not exceed 200 mA.
    3] The sum of all IOL, for ports B0 — B7, C6, D0 — D7 and XTAL2, should not exceed 100 mA.

    PDIP Package:
    1] The sum of all IOH, for all ports, should not exceed 400 mA.
    2] The sum of all IOH, for port C0 — C5, should not exceed 100 mA. (меньше! или ошибка?)
    3] The sum of all IOH, for ports B0 — B7, C6, D0 — D7 and XTAL2, should not exceed 100 mA.

  15. cahbtexhuk говорит:

    Вырвать гвозди из пола с мясом. Суровый мясной паркет.
    А про «1 похожа на стрелку…» — мне у ПИКов нравится логика для TRIS регистра: 1nput-0utput.

  16. Asmodey говорит:

    Хозяину блога большой респект :) Была попытка освоить микроконтроллеры AVR, но нарвавшись в свое время на avr123… забил на это дело, там хотя и немало инфы, но глаз и моск в процессе ее усвоения на том ресурсе сломать можно запросто! Буду здесь ошиваццо, может просеку чего в деле программирования AVR.

  17. hexFF говорит:

    ЗЫЫЫ… Упячко-мэн… Под столом…

  18. VEC7OR говорит:

    Бугаг, хозяин ну ты отжег.

    И да, картинка с диодом и переключателем в коментах про АВР порт — проще еще не видел.

  19. Hermes говорит:

    Не, я понимаю сухой текст проиллюстрировать схемками (а упрощенными это бывает редко), но еще и комиксы — чуть со стула не грохнулся!!! MSPaint рулит :-)

  20. alvad89 говорит:

    класссно) теперь можно будет и преподу так нарисовать.
    хорошая статья. мне как раз надо начинать разбираться с Atmega. все-таки и лаба ждет и курсач грядет)

  21. Buxxter говорит:

    Вы уж извините, но я даже с комиксами не понял. Видимо особо одаренный :(. Скорее всего принина в отсутствии подписей (какая картинка к какому режиму).
    Итак, сложившееся представление:
    1. Порт — группа из восьми ножек.
    2. Порт в единицу времени может быть либо входом, либо выходом (все 8 ножек).
    2.1. Если он выход — то выход и ниипет… можем в него записывать из программы (изнутри), и узнать, чего записали.
    2.2. Если он вход, то тут два варианта:
    2.2.1. Hi-Z:
    2.2.1.1. Если висит в воздухе — считывает экстрасенсорные сигналы головного мозга обезьяны на расстоянии 100м.
    2.2.1.2. Если подключен — тут вопрос: как отличить 0 от 1? Если я правильно понял, то в ход идет любая разница в напряжении между тактами. Если разница >0, то 1, 3.5В — то 1, иначе 0.

    Исходя из описания к п.2.2 для потока данных лучше использовать Hi-Z, для событий и четкого потока (либо 5В, либо 0В) — PullUp

    З.Ы.
    Вы уж извините, но микроконтроллеры всегда были для меня магией. Образования в этом плане (и во всех связанных) НОЛЬ. Всегда была мечта идиота: взял бы какой-нть гуманитарий, да описал все на детском языке. Как мне показалось, нашел ресурс своей мечты.

    Подтвердите или опровергните плз все пункты, включая «З.Ы.».

    • Buxxter говорит:

      Ф-ции изменения каментов явно не хватает, поток мыслей с выводом в текстовом виде последнее в кашу превращает…

      2.2.1.2. Если подключен — тут вопрос: как отличить 0 от 1? Если я правильно понял, то в ход идет любая разница в напряжении между тактами. Если разница >0, то 1, иначе 0. (U[i] — U[i-1] > 0, y = 1)
      2.2.2. PullUp — четкая граница мжду 0 и 1. Если напряжение на ноге, скажем >3.5В — 1, иначе 0.

    • DI HALT говорит:

      1 — да
      2 — нет. Порт частью ножек может быть на вход, частью на выход. Каждая нога настраивается индивидуально.

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

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

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

      • Buxxter говорит:

        Так… Картинка проясняется…
        Т.о. если я к ноге подключаю, к примеру, выход с другой микросхемы, то лучше Hi-z. А если кнопку, или, скажем, анод фотодиода (катод на землю), то тут полюбас PullUp (подтянутый кверху).

        Может сравнение тупорылое, но по-другому похоже не получится:
        Hi-Z — это выключатель (щелкнули вверх — пояыилась единица, вниз — 0)
        PullUp — это кнопка дверного звонка в обратную сторону — пока давим, звонок не звонит (0), отпустили, звонок звонит сам по себе (1).

  22. karlson говорит:

    «Как запомнить режимы, чтобы не лазать каждый раз в справочник: » (на грани больной фантазии) можно сравнить регистр DDR с половыми органами: 0 принимает , 1 отдает. запомнить проще. по крайней мере мне.

  23. eldrantom говорит:

    направление портов легче запомнить так:
    0 -»дырка» куда суют 1,значит вход.
    1 — то что суют в 0 («дырку»),значит выход.

  24. eldrantom говорит:

    забыл дописать. спасиб за Z-состояние, а то в книгах с этим ппц.

  25. tarasadidas говорит:

    Помоему забыли еще про гистерезис.Напряжение перехода от нуля к еденице и на оборот различаются.Читал помоему в AVR 1.2.3 Учебный курс.

  26. elita_sgm говорит:

    Компового БП хватит для питания МК?

  27. slava_32 говорит:

    Знач так, мож я туплю, а мож иза той литры пива что вдудлил… у Вас в статье: нога МК имеет три режима:
    1) Выход — читаем(DDR = 1, PORT — делает погоду)
    2) Вход — читает МК(DDR = 0, PORT = 1)
    3) Вход HI-Z «Этот режим хорош для прослушивания какой либо шины данных, т.к. он не оказывает на шину никакого влияния», тоесть мы читаем — парадокс:(.

    Потом: книга «Юрий Ревич — Практическое программирование Микроконтроллеров AVR на языке ассемблера» скачана из Вашего сайта, страница 16 строка 10: «все выводы в них могут пребывать в трех состояниях (вход — отключен — выход)».

    Проблема: мой мозг незнает кому поверить, можно я буду считать что HI-Z ето не вход а отключен?

  28. barrako говорит:

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

  29. AlexRom говорит:

    Автор 1++ спс за инфу! Доступно все и с комиксами :)

  30. piro говорит:

    Ребя!
    Мне вот надо на вход мк с ЛПТ порта единичку подать допустим…
    так как мне вход настраивать?
    как пулап или как хайзет,а?
    с кнопкой и замыканием на землю всё ясно,а с +5в как быть?
    хочу шаговиком порулить (софт-МК-L293-ШД).

    • DI HALT говорит:

      Можно и так и так. Но хайзед будет корректней — т.к. LPT порту не придется пересиливать подтяжку при утягивании ноги вниз.

      • piro говорит:

        Во! Спасибо за быстрый ответ.
        И протэус мне показал что хайзет работает…
        щас накатаю софтинку с одной кнопкой «крути_по часовой»,проверю…
        ещё раз тенькью.

  31. neon-f говорит:

    а что предпочтительнее для порта висящего в воздухе(кнопка) в плане энергосбережения (при переключении контролера в режиме POWER SAVE) — оставить входом с подтяжкой, или сделать выходом и записать лог нуль??

    • DI HALT говорит:

      Оставить режим Hi-Z ;) Если конечно эта кнопка не юзаетсяд для выхода из спячки.

      • neon-f говорит:

        так тыж сам пишешь, что пин в Z состоянии, если никуда не подключен, ловит на себе окружающие наводки, от этого входной буфер хаотически и многократно переключается, и следовательно ОЧЕНЬ много жрет.
        Вот я и спрашиваю, как будет меньше потребление, если оставить входом с подтяжкой или выходом с нулём? (при переходе в POWER SAVE. в это время выводы мне не нужны, просыпаюсь от таймера)

        • DI HALT говорит:

          ЕМНИП в PowrSave периферия отключается, так что жрать нечему. Но можно и на землю подтянуть. Тут разницы нет

          • neon-f говорит:

            отключается?? само? странно. в моей «любимой книге» Евстифеев А.В. — Микроконтроллеры AVR семейства Mega сказано лишь что в новых мегах можно отключать входные буферы. а в старых (я работаю с мега16а) нужно САМОСТОЯТЕЛЬНО сконфигурировать порты на наименьшее потребление. Вот я и решаю, как мне их конфигурировать во время сна…..

          • DI HALT говорит:

            Ну тогда кури даташит. Т.к. у меня среднее потребление устройства в 99% около киловатта и милливатты микроконтроллера я даже за потери не считаю и никогда на энергопотребление не заморачивался.

            Но по логике вещей:

            Кнопка на Pull Up обычно работает, но этот режим самый неэкономичный. Т.к. кнопка может нажаться и будет лишняя утечка энергии.

            Надо перевести в экономичный:
            HI-Z если логика порта засыпает и самый безопасный от последствий
            Low или High — в зависимости от схемотехники кнопки. Т.к. перевод в high или Low может убить вывод порта если кнопка будет давить порт в противоположное направлении. Опять же, если есть внешние подтяжки кнопки — будет лишнее потребление. Плюс надо учитывать тот момент когда происходит выход из спячки и делать сразу же переконфигурирование портов. Иначе будут эффекты.

  32. Electronik говорит:

    Простите за оффтоп. Я хочу прочитать данные с термодатчика DS18B20, порт настроен на вход. На экране осциллографа напряжение единички на уровне 2,5 вольт. В чём может быть дело?

  33. tyuseman говорит:

    Прежде всего. Сайт — класс! Радуюсь, что гугление привело к нему.

    А вопрос по статье следующий — мелькало слово «сила», «пересиливать». Я понимаю, что это для упрощения :). Просто не понимаю, что является «мерой» этой силы. Ведь цифровой выход — это низкий импеданс (только сопротивление канала МОП), ключ на 1 или на 0. Соответственно, если нога-вход AVR подтянута, а на выходе ставится 0, то на резисторе подтяжки падает всё напряжение, соответственно, PIN=0.

    И ещё не понял. Почему от «грубой силы» (закорот от упавшей отвёртки), лучше защищает режим Pull-Up, чем Hi-Z?

    Заранее спасибо :).

    • DI HALT говорит:

      Под силой тут можно принято ток. Т.е. какой ток может обеспечить источник и какой ток может просадить выход без разрушения. Грубо говоря у кого меньше сопротивление (внутреннее сопротивление источника против сопротивления выхода) тот и победит.

      Разницы никакой. Но Pull-UP дает подтяжку и обеспечивает определенный уровень. не позволяя выводу болтаться под действием помех как на HiZ

  34. Fck_r_sns говорит:

    «В режиме OUT у нас планка прибита гвоздями к земле или прижата домкратом к питанию. Внешняя сила может ее пересилить только сломав домкрат или сломается сама. Тупая внешняя сила просто разрушает наш домкрат или вырывает гвозди из пола с мясом. В любом случае — девайс в помойку.»

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

  35. neon-f говорит:

    так должно быть теоретически, но практически очень часто с контроллером ничего не случается. Особенно если только один вывод закорочен. Ток КЗ ограничивается до какого нибудь большого, но «вменяемого» уровня, и контроллер остается жив. При этом иногда даже не нарушается работа остальных узлов.

  36. neon-f говорит:

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

    • SIM говорит:

      В даташите всё описанно :) Удвоить нельзя помоему, может 20% даст улучшения, и снижение сопротивления источника тока. Там есть суммарное ограничение тока порта и контроллера, оно намного ниже чем допустимая мощность каждой ноги. Несинхронное переключение даст массу глюков, проще транзистор прилепить помоему и будет хоть 80 мА, хоть 80 ампер :)

  37. portfolis говорит:

    ———
    Есть еще бит PUD (PullUp Disable) в регистре SFIOR он запрещает включение подтяжки сразу для всех портов. По дефолту он равен 0. Честно говоря, я даже не знаю нафиг он нужен — ни разу не доводилось его применять и даже не представляю себе ситуацию когда бы мне надо было запретить использование подтяжки сразу для всех портов. Ну да ладно, инженерам Atmel видней
    ———
    У меня в datasheete сказано, что при уходе в сон для меньших затрат электроэнергии лучше отключать все Pull-up резисторы. Видимо здесь и будет полезен этот бит

  38. AlexSkv говорит:

    Добрый день,DI!
    Начал ковырять микроконтроллеры по Вашим материалам и с помощью вашей платы!
    Возник такой вопрос!
    Зажигаю я диодик при включении МК, при этом значение в регистре PORTB ни на что не влияет! Хоть он 0, хоть 1, если вывод работает на выход (DDRB=1) диод горит!
    Как именно PORTB (1 или 0) в режиме работы на выход влияет на работу МК?

    ldi temp, 0b00000001
    ; ldi temp1, 0
    out DDRB, temp
    ; out PORTB, temp1 ; диод горит и при 1, и при 0

  39. AlexSkv говорит:

    Вопрос снят в силу своей глупости и корявости рук))!
    Осталось только непонимание вот в чём:
    диод зажигается от двух команд:
    ldi temp, 0b00000001
    out DDRB, temp
    То есть явно прописывать PORTB=0 (у меня схема порт-питание) почему-то не нужно!
    Если я принудительно пропишу PORTB=1, естественно ничего не горит, но в тоже время диод загорается и без явного указания PORTB=0. Это и непонятно.

Добавить комментарий