Ревич, Ю.В. Программирование микроконтроллеров 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 ) ) ;
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==