Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру

Глава б. Основы программирования МКАVR 157 пришлось бы к тому же придумывать конвертер значения count в двоичное пред­ ставление для вывода в отдельные биты порта С - выводы АО-А2, работающие в нашем случае как обычные цифровые порты) . Не стали также возиться с собст­ венной программной задержкой, использовав штатную delayMicroseconds ( ) (о ве­ личине задержки 1 0 ООО мкс - см. врезку «Подробности» далее) . По идее delayMicroseconds ( ) является аналогом того же самого подхода с задержкой под­ счетом тактов, никаких таймеров она не использует, так что мы тут ничем не по­ грешили по сравнению с ассемблерной программой. Исключение составляет digitalRead ( ) , но можете заменить и ее тоже на непосредственное чтение PinD, от этого мало что изменится. А вот что важно: такая совсем несложная программа, вдвое меньше по объему текста, чем наша ассемблерная, тем не менее после ком­ пиляции оказывается примерно в 20 раз объемнее и занимает в памяти 762 байта. ПОДРОБНОСТИ Посмотрим, что мы еще тут выиграли . Да, функция ctelayMicroseconcts ( ) реализована не на прерываниях, а в виде простой программной задержки , - по идее полный ана­ лог нашего подхода. Но! Во-первых, в комментариях на официальном сайте Aгdu i пo про эту функцию сказано, что « " . наибольшее число , позволяющее сформировать точ­ ную задержку - 1 6383» . То есть более 1 6 мс она может работать кое-как, и проверить это трудно, почему мы и выбрали 1 0 ООО мкс в своей программе. Но еще хуже она се­ бя должна вести при очень малых задержках, т. к. оформлена в виде функции (макро­ сов нам в С не предлагается) . А вызов функции в Aгduiпo - это совершенно отдель­ ная песня , которая требует также отдельного обсуждения (если кому-то это интерес­ но, можете поизучать вопрос путем дизассемблирования кода Aгduiпo в AVR Stud io) . Наш же макрос будет безупречно работать при любых необходимых задержках: захо­ тим - добавим в него еще регистр , получим секунды и десятки секунд, доведем число регистров до 4-х - получим уже часы , и т. д. Точно отмерить задержки порядка мик­ росекунд и менее можно только так - даже в Aгduino это делают с помощью inl ine­ acceмблepa. Другое дело, что при использовании прерываний и задержках более миллисекунд к такому способу прибегать нецелесообразно: прерывания внесут неоп­ ределенность , если разместить задержку в главном цикле , или могут потеряться , если ее задействовать в кстом-нибудь из обработчиков. В реальности в Arduino с кнопкой правильно обращаться именно так, как мы сейчас показали, может быть чуть усложненным способом, отслеживая несколько состоя­ ний с небольшой паузой между ними. Я предлагаю вам самим попробовать разо­ браться в коде, который получается, если подойти к этому делу грамотно (привожу без пояснений фрагмент Аrduinо-программы для одного из моих приборов) . Выгля­ дит это примерно так (листинг 6 . 1 9) : boolean yes = false ; byte i=O ; const byte button = 2 ; кнопка whi le ( ! ye s ) { / /проверяем кнопку i++ ; boolean statel = ( digitalRead ( button ) &HIGH ) ; delayMicroseconds ( l O O ) ; / /задержка в 1 0 0 микросекунд yes= ( statel & ! digitalRead ( button ) ) ;

RkJQdWJsaXNoZXIy MTExODQxMg==