Аппаратные прерывания в Arduino



 

Аппаратные прерывания в Arduino Как подсказывает название, прерывания - это сигналы, прерывающие нормальное течение программы. Прерывания обычно используются для аппаратных устройств, требующих немедленной реакции на появление событий. Например, система последовательного порта или UART (универсальный асинхронный приемопередатчик) микроконтроллера должен быть обслужен при получении нового символа. Если этого не сделать быстро, новый символ может быть потерян. При поступлении нового символа UART генерирует прерывание. Микроконтроллер останавливает выполнение основной программы (приложения) и перескакивает на программу обработки прерываний (ISR), предназначенную для данного прерывания. В данном случае это прерывание по полученному символу. Эта ISR захватывает новый символ из UART, помещает в буфер, затем очищает прерывание и выполняет возврат. Когда ISR выполняет возврат, микроконтроллер возвращается в основную программу и продолжает её с точки вызова. Все это происходит в фоновом режиме и не влияет напрямую на основной код вашего приложения. Если запускается много прерываний или прерывания генерирует быстродействующий таймер, основная программа будет выполняться медленнее, так как микроконтроллер распределяет свое машинное время между основной программой и всеми функциями обработки прерываний. Давайте вычислим пример, чтобы увидеть, насколько важны процессы прерывания. Скажем, у есть последовательный порт со скоростью передачи данных 9600 бод. Это означает, что каждый бит символа посылается с частотой 9600 Гц или около 10 кГц. На каждый бит уходит 100 мкс. Около 10 бит требуется, чтобы послать один символ, так что мы получаем один полный символ каждую миллисекунду или около того. Если наш UART буферизован, мы должны извлечь последний символ до завершения приема следующего, это дает на всю работу 1 мс. Если UART не буферизован, необходимо избавиться от символа за 1 бит или 1 мкс. Рассмотрим для начала буферизованный пример. Нужно проверять получение байта быстрее, чем каждую миллисекунду, чтобы предотвратить потерю данных. Применительно к Arduino это означает, что наша функция цикла должна обращаться для чтения статуса UART и возможно, байта данных, 1000 раз в секунду. Это легко выполнимо, но сильно усложнит код, который вам нужно написать. До тех пор, пока функция цикла не требует больше 1 мс до завершения, это может сойти с рук. Но возможно, что нужно обслуживать несколько устройств ввода-вывода, или что необходимо работать на гораздо большей скорости передачи. Такие неприятности это вскоре может принести. С прерываниями не нужно отслеживать поступление символа. Аппаратура подает сигнал с помощью прерывания, и процессор быстро вызовет ISR, чтобы вовремя захватить символ. Вместо выделения огромной доли процессорного времени на проверку статуса UART, вы никогда не должны проверять статус, просто устанавливается аппаратное прерывание и выполняете необходимые действия в ISR. Главная программа напрямую не затрагивается, и от аппаратного устройства не требуется особых возможностей. .5.1 Прерывание по таймеру В данном разделе будет описано на использование программного таймера 2 для периодических прерываний. Исходная идея состояла в использовании этого таймера для генерации частоты биений в звуковых проектах Arduino. Чтобы выводить тон или частоту нам нужно переключать порт ввода-вывода на согласованной частоте. Это можно делать с использованием циклов задержки. Это просто, но означает, что наш процессор будет занят, ничего не выполняя, но ожидая точного времени переключения вывода. С использованием прерывания по таймеру мы можем заняться другими делами, а вывод пусть переключает ISR, когда таймер подаст сигнал, что время пришло. Необходимо только установить таймер, чтобы подавал сигнал с прерыванием в нужное время. Вместо прокрутки бесполезного цикла для задержки по времени, главная программа может делать что-то другое, например, контролировать датчик движения или управлять электроприводом. Что бы ни требовалось проекту, больше нам не нужно процессорное время для получения задержек. Далее будет описано ISR в общем только то, что касается прерываний таймера 2. Более подробно об использовании прерываний в процессорах AVR можно прочитать в руководстве пользователя avr-libc <#"justify">Arduino пользуется всеми тремя таймерами ATMega168: 1) Таймер 0 (Системное время, ШИМ 5 and 6) Используется для хранения счетчика времени работы программы. Функция millis() возвращает число миллисекунд с момента запуск программы, используя ISR глобального приращения таймера 0. Таймер 0 также используется для реализации ШИМ на выводах 5 и 6. ) Таймер 1 (ШИМ 9 и 10) Используется для реализации ШИМ для цифровых выводах 9 и 10. )Таймер 2 (ШИМ 3 и 11) Используется для управления выходами ШИМ для цифровых выводов 3 и 11. Хотя все таймеры используются, только Таймер 0 имеет назначенную таймеру ISR. Это означает, что можно захватить Таймер 1 и/или Таймер2 под свои нужды. Однако в результате нельзя будет использовать ШИМ на некоторых портах ввода-вывода. Если планируется использовать ШИМ, необходимо помнить об этом. .5.3 Загрузка микроконтроллера прерываниями Чтобы дать представление об эффекте, предположим, что таймер ISR запускался бы каждые 20 мкс. Процессор, работающий на 16 МГц, может выполнить около 1 машинной команды каждые 63 мс или около 320 машинных команд для каждого цикла прерывания (20 мкс). Предположим также, что исполнение каждой строки программы на С может занять много машинных команд. Каждая инструкция, используемая в ISR, отнимает время, доступное для исполнения любой другой программы. Если бы ISR использовала около 150 машинных циклов, было бы потрачено половина доступного процессорного времени. При активных прерываниях главная программа откладывалась бы около ½ времени, занимаемого ей в других случаях. 150 машинных команд - не очень большая программа на С, поэтому необходимо быть внимательны. Если будет слишком длинная ISR, то главная программа будет исполняться крайне медленно, если же ISR будет длиннее, чем продолжительность цикла таймера, то практически никогда не выполнится ваша главная программа, и, кроме того, в конце концов произойдет сбой системного стека. .5.4 Измерение загрузки прерываниями Поскольку необходимо иметь очень быстрый таймер ISR, то нужно измерить, насколько загружены доступные ресурсы. Для этого необходим некоторый метод. Таймер не был установлен в режим, когда он перезагружается автоматически. Это значит, что ISR должна перезагрузить таймер для следующего интервала счета. Было бы точнее иметь автоматически перезагружаемый таймер, но, используя этот режим, можно измерить время, проводимое в ISR, и соответственно исправить время, загружаемое в таймер. Ключ в том, что при помощи этой коррекции при разумной точности, также получаем и число, показывающее, сколько времени проводим в ISR. Метод заключается в том, что таймер хранит время, даже если он переполнен и прерван. В конце ISR можно захватить текущее значение счетчика таймера. Это значение представляет то время, которое он отнял у разработчика до следующей точки программы. Это суммарное время, затраченное на переход в процедуру прерывания и выполнение программы в ISR. Небольшая ошибка будет оттого, что не подсчитывается время, затраченное на команду перезагрузки таймера, но эту ошибку можно исправить эмпирически. Фактически именно поэтому используется в формуле подсчета загружаемого значения 257 вместо 256. Было обнаружено опытным путем, что это дает лучший результат. Лишний такт компенсирует команду перезагрузки таймера. .5.5 Использование прерываний в Arduino Часто при работе с проектами на микроконтроллерах требуется запускать фоновую функцию через равные промежутки времени. Это часто реализуется установкой аппаратного таймера для выработки прерывания. Это прерывание запускает программу обработки прерываний (Interrupt Service Routine, ISR) для управления периодическим прерыванием. В настоящей статье я описываю установку 8-битного таймера 2 для выработки прерываний на микроконтроллере ATMega168 Arduino. Я пройдусь по этапам, требуемым для установки программы обработки прерываний и внутри нее самой. Arduino подразумевает процессор ATMega168. Этот микроконтроллер имеет несколько систем ввода-вывода, которые доступны каждому пользователю Arduino, поскольку библиотека Arduino облегчает их использование. К примеру, цифровой ввод-вывод, ШИМ, аналого-цифровые входы и последовательный порт. ATMega168 также имеет три внутренних аппаратных таймера. Хотя библиотека Arduino позволяет использовать некоторые свойства таймеров, нельзя напрямую использовать таймер для выработки периодических прерываний. таймер память цоколевка stepper 2. Библиотеки Arduino .1 Библиотека Servo .2 Библиотека EERPOM Микроконтроллеры ATmega имеют свою энергонезависимую память, то есть у пользователей Ардуино есть возможность сохранять данные в этой памяти и они могут быть использованы после выключения-включения или перезагрузки контроллера. Arduino библиотека EERPOM предоставляет удобный и простой интерфейс работы с этой памятью. Разные модели микроконтроллеров различаются объемом EERPOM памяти, так ATMega328 имеет 1024 байт, 512 байт у ATmega168 и ATmega8 и по 4Кб (4096 байт) у ATmega1280 и ATmega2560. Функции 1)read <#"justify">.3 Библиотека SPI Библиотека SPI позволяет контроллеру Arduino взаимодействовать с устройствами поддерживающими SPI протокол. Arduino в данном случае выступает в качестве ведущего устройства. Последовательный периферийный интерфейс (SPI) - это последовательный синхронный протокол передачи данных используемый микроконтроллерами для обмена данными с одним или несколькими периферийными устройствами на небольших расстояниях. Для организации соединения SPI необходимо одно ведущее устройство, обычно это микроконтроллер, которое управляет соединением с ведомыми устройствами. Обычно подключение осуществляется тремя общими линиями и линией выбора периферийного (ведомого) устройства: 1)Master In Slave Out (MISO), переводится как "вход ведущего выход ведомого", используется для передачи данных от ведомого к ведущему. )Master Out Slave In (MOSI) - выход ведущего вход ведомого, для передачи данных от ведущего к периферийным устройствам. 3)Serial Clock (SCK) - синхронизирующая линия, синхросигнал генерируется ведущим устройством. 4)Slave Select pin - вход на ведомых устройствах с помощью которого ведущий может инициировать обмен данными с периферийным устройством. Если на этом входе LOW, <#"justify">При работе с SPI устройствами надо учитывать следующие моменты: 1)Какой порядок вывода данных используется: Most Significant Bit (MSB - старший бит (разряд)) or Least Significant Bit (LSB - младший бит) первый. Порядок может быть изменен функцией SPI.setBitOrder <#"justify">2)Уровень сигнала синхронизации - по какому синхронизирующему сигналу (HIGH или LOW) передаются данные. 3)Фаза синхронизации - влияет на последовательность установки и выборки данных. Фаза синхронизации SPI и уровень сигнала задается функцией SPI.setDataMode <#"justify">Функции 1)begin <#"justify">.4 Библиотека Stepper Библиотека Stepper предоставляет удобный интерфейс управления биполярными и униполярными шаговыми двигателями. Для управления шаговым двигателем, в зависимости от его типа (биполярный или униполярный) и выбранного способа подключения, понадобятся некоторые дополнительные электронные компоненты.


Дата добавления: 2018-11-24; просмотров: 308; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!