Tag Archives: AVR

AVR. Учебный курс. Таймеры

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

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

И такой счетчик есть, даже не один — это периферийные таймеры. В AVR их может быть несколько штук да еще с разной разрядностью. В ATmega16 три, в ATmega128 четыре. А в новых МК серии AVR может даже еще больше, не узнавал.

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

Что умееют таймеры

  • Тикать с разной скоростью, подсчитывая время
  • Считать входящие извне импульсы (режим счетчика)
  • Тикать от внешнего кварца на 32768гц
  • Генерировать несколько видов ШИМ сигнала
  • Выдавать прерывания (по полудесятку разных событий) и устанавливать флаги

Разные таймеры имеют разную функциональность и разную разрядность. Это подробней смотреть в даташите.
(далее…)

Read More »

USB программатор AVR — USBAsp

Вид сверху
Вид сверху

!!! ЭТЕНШН !!!
Появилась схема USB программатора которая НЕ требует предварительной прошивки управляющего микроконтроллера.

Так как у многих уже давным давно нет ни COM ни LPT порта, то я решил выложить схему USB программатора для AVR. Это будет широко известный в узких кругах USBASP. Схема простая как три копейки, но COM или LPT порт все же потребуется — для того, чтобы прошить управляющий контроллер. Так что можешь сходить к другану. Программатор строится на контроллере ATMega48 или ATMega8. Нужна именно 8 или 48, без всяких индексов L. Так как у нас требуется частота выше чем 8 Мгц. (далее…)

Read More »

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

Вот ты читаешь сейчас это и думаешь — память, регистры, стек и прочее это хорошо. Но ведь это не пощупать, не увидеть. Разве что в симуляторе, но я и на дельфи с тем же условием могу накодить. Где мясо!!!
 
В других курсах там, чуть ли не с первых строк, делают что то существенное — диодиком мигают и говорят, что это наш Hello World. А тут? Гыде???
 

Да-да-да, я тебя понимаю. Более того, наверняка ты уже сбегал к конкурентам и помигал у них диодиком ;)))) Ничего, простительно.
 

Я просто не хотел на этом же мигании дидодиков и остановиться, а для прогресса нужно четкое понимание основ и принципов — мощная теоретическая база. Но вот пришла очередь практики.
 

О портах было рассказано, шаблон программы у вас уже есть, так что сразу и начнем.
 
(далее…)

Read More »

Отладочная плата PinBoard v1.1

В один прекрасный момент я задумался — а какого черта я трачу столько времени на сооружении разного обвяза при отладке новых модулей и при подготовке экспериментов?

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

Что такое демоплата? Демоплата — это универсальный полигон для экспериментов. Идеальное средство для быстрого старта. На ней смонтирован микроконтроллер, а также вся необходимая обвязка для его работа. Плюс разные полуфабрикаты, позволяющие облегчить эксперименты.

Готовое устройство, где все уже подключено, разведено как надо. Купил — включил — работай. Риск что-либо сжечь в ходе экспериментов снижен максимально. Где нет нужды парить мозг проблемой «чем прошить», «как запустить», «Как правильно все подключить». Первые шаги делаются быстро и легко.
А потом, когда ты уже освоишься с контроллером, то запросто можно посмотреть как сделано на демоплате и перенести это решение в свое устройство.

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

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

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

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

Вот фичи которые мне удалось реализовать: (далее…)

Read More »

AVR. Учебный Курс. Конфигурация FUSE бит

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

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

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

Итак, главное:

В Atmel AVR принята следующая нотация: сброшенный в ноль fuse bit считается активным, т.е. включенным.
 

Пример Бит RSTDSBL, как можно догадаться из названия, это RESET DISABLE. Включил эту опцию и у тебя нога RESET превращается в порт ввода-вывода, но за это ты теряешь возможность перешить контроллер через ISP.
 

Так вот, чтобы выключить RESET (и получить большое западло с прошивкой в обмен на мелкую подачку в виде дополнительной ножки) в этот бит надо записать 0.
 

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

 
(далее…)

Read More »

AVR. Учебный Курс. Использование Bootloader’а

Почти все микроконтроллеры серии Mega с памятью от 8КБ могут прошиваться через бутлоадер. Фишка удобная и применяется довольно часто, однако подробного мануала как работать с бутлоадером на AVR я в свое время не нашел и пришлось разбираться самостоятельно. С той поры мало что изменилось. Пора бы дать подробное описание как выбрать, скомпилировать, прошить и в дальнейшем использовать bootloader для AVR.
 

Ликбез
Что же это такое бут и с чем его едят. BootLoader это всего лишь небольшая программка которая сидит в специальной области памяти микроконтроллера и слушает какой-либо интерфейс. Обычно это UART, но бывает и SPI, USB и даже SoftUSB бутлоадеры.
 

При загрузке контроллера управление первым делом передается бутлоадеру и он проверяет есть ли условие для запуска. Условие может быть любым, но обычно это либо наличие спец байта по интерфейсу, либо наличие нужного логического уровня на выбранной ножке контроллера, сигнализирующее о том, что мы хотим обратиться к буту прошивку. Если условие есть — то бутлоадер может, например, принять прошивку по UART‘у и сам прошить ее во флеш. Или, наоборот, считать прошивку из флеша и выдать через UART, считать или записать EEPROM, подрыгать ножками. Да что угодно. Но обычно все же с помощью бута осуществляют прошивку микроконтроллера без применения спец программатора.
 

Если разрешающего условия при старте нет, то бут завершает свою работу и передает управление основной программе.
 

(далее…)

Read More »

Программатор Громова

Самый простой вариант программатора для AVR это пять проводков, припаиваемых к порту контроллера и втыкаемых в LPT порт. Не спорю, можно и так. Но я все же не рекомендую этот способ. Даже схему подключения давать не буду — если надо будет сам найдешь. Так как данный метод не очень стабилен, возможны сбои при прошивке, длина проводков ограничена двадцатью сантиметрами (если больше, то будет глючить), поэтому придется шариться в комповой заднице. Да и LPT порт спалить проще простого. В общем не рулез.

Шарясь по инету, я нашел отличный программатор, работающий через RS232 он же COM порт. А также удобную программу для прошивки контроллера UniProf от Николаева. Схему программатора придумал Громов, создатель Algorithm Builder.

Саму программу UniProf можно скачать у меня, но лучше взять с сайта автора. Возможно там будет версия посвежее.
(далее…)

Read More »

AVR. Учебный курс. Трактат о программаторах

Программа для микроконтроллера пишется на любом удобном языке программирования, компилируется в бинарный файл (или файл формата intel HEX) и заливается в микроконтроллер посредством программатора.
 

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

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

Программаторы бывают разные под разные семейства контроллеров существуют свои программаторы. Впрочем, бывают и универсальные. Более того, даже ту же простейшую AVR’ку можно прошить несколькими способами:
 

Внутрисхемное программирование (ISP)
Самый популярный способ прошивать современные контроллеры. Внутрисхемным данный метод называется потому, что микроконтроллер в этот момент находится в схеме целевого устройства — он может быть даже наглухо туда впаян. Для нужд программатора в этом случае выделяется несколько выводов контроллера (обычно 3..5 в зависимости от контроллера).

(далее…)

Read More »

Подключение микроконтроллера. Ликбез.

Казалось бы простая тема, а однако в комментах меня завалили вопросами как подключить микроконтроллер. Как подключить к нему светодиод, кнопку, питание. Что делать с AGND или AREF. Зачем нужен AVCC и все в таком духе. Итак, раз есть вопросы, значит тема не понятна и надо дать по возможности исчерпывающий ответ. Все описываю для контроллеров AVR, но для каких нибудь PIC все очень и очень похоже. Т.к. принципы тут едины.
 

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

 

Питание
Для работы микроконтроллеру нужна энергия — электричество. Для этого на него естественно нужно завести питалово. Напряжение питание у МК Atmel AVR разнится от 1.8 до 5 вольт, в зависимости от серии и модели. Все AVR могут работать от 5 вольт (если есть чисто низковольтные серии, то просьба уточнить в комментах, т.к. я таких не встречал). Так что будем считать что напряжение питания контроллера у нас всегда 5 вольт или около того. Плюс напряжения питания обычно обозначается как Vcc. Нулевой вывод (а также Земля, Корпус, да как только его не называют) обозначают GND. Если взять за пример комповый блок питания. То черный провод это GND (кстати, земляной провод традиционно окрашивают в черный цвет), а красный это +5, будет нашим Vcc. Если ты собираешься запитать микроконтроллер от батареек, то минус батареек примем за GND, а плюс за Vcc (главное чтобы напряжение питания с батарей было в заданных пределах для данного МК, позырь в даташите. Параметр обычно написан на первой странице в общем описании фич:
 

• Operating Voltages
–1.8 — 5.5V (ATtiny2313V)
–2.7 — 5.5V (ATtiny2313)
• Speed Grades
–ATtiny2313V: 0 — 4 MHz @ 1.8 — 5.5V, 0 — 10 MHz @ 2.7 — 5.5V
–ATtiny2313: 0 — 10 MHz @ 2.7 — 5.5V, 0 — 20 MHz @ 4.5 — 5.5V
 

Обрати внимание, что есть особые низковольтные серии (например 2313V низковльтная) у которых нижня граница напряжения питания сильно меньше. Также стоит обратить внимание на следующий пункт, про частоты. Тут показана зависимость максимальной частоты от напряжения питания. Видно, что на низком напряжении предельные частоты ниже. А низковольтные серии раза в два медленней своих высоковольтных коллег. Впрочем, разгону все процессоры покорны ;))))) (далее…)

Read More »

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

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

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

Read More »

AVR. Учебный Курс. Оценка загрузки контроллера.

Как оценить загруженность микроконтроллера? С памятью все понятно — размеры занимаемого кода и оперативной памяти показывает компилятор, а что делать с процессорным временем? Конечно, в линейной программе можно взять и посчитать время выполнения каждой процедуры и станет ясно успеет микроконтроллер выполнить все на него повешанное или слажает в каком-нибудь критичном месте.
Куда сложней оценивать время в кооперативной операционной системе реального времени. Тут задачка получается нетривиальной — у нас куча процессов скачут через диспетчер. В ходе программирования задачи навешиваешь одну за другой, как бусинки на нить — каждый процесс обработки чего либо составляет подобную цепочку, а всего их может быть просто тьма. Ядро же у контроллера всего одно, а значит выполнять можно всего одну задачу за раз и если у нас в диспетчере скопится много критичных ко времени процессов (вообще их лучше развешивать на прерывания, но бывает и прерываний на всех не напасешься), то возможно либо переполнение очереди диспетчера, либо превышение времени ожидания, что тоже не праздник.
Самое западло в том, что умозрительно отлаживать такие вещи довольно сложно. Единственный вариант — рисовать временные диаграммы запуска каждой задачи и смотреть где у нас узкие места. Еще можно попробовать в AVR Studio поставить Break Point на переполнение диспетчера, но студия не сэмулирует всю ту прорву периферии, а в пошаговой отладке этого не увидеть — да и момент надо подобрать так, чтобы все навалилось.

В один момент мне пришла в голову одна идея — а почему бы не заставить рисовать временные диаграммы работы задач сам контроллер? Это же просто! Берем и в диспетчере, перед вызовом задачи выставляем бит порта в 1. А когда диспетчер задач опустошается полностью, то есть выполняется переход на Idle — сбрасываем бит в 0. В результате, у нас на выходе будет подобие ШИМ. Если постоянно крутится Idle — будут нули перманентно. Если же проц в поте лица гонит через себя непрерывно код, то будут высокий уровнь сплошняком. А если все прерывисто — что то ШИМообразное. Причем чем больше загрузка процессора тем выше заполнение. Можно поставить интегрирующую RC цепочку и получим аналоговый сигнал. Хоть на стрелочный индикатор заводи :). Сказано — сделано.
(далее…)

Read More »

AVR. Учебный курс. Операционная система. Пример.

Отлично, с теорией работы ОС ознакомил. Устанавливать научил, осталось научить использовать весь этот конвеерно таймерный шухер. Чем я сейчас и займусь. Сразу берем быка за рога и формулируем учебно-боевую программу.
Тестовое задание:
Пусть у нас будет ATMega8, с несколькими кнопками. АЦП и подключеним к компу через UART. На меге будет три светодиода.

  • Девайс должен при включении начинать мигать зеленым диодом, мол работаю.
  • При этом раз в секунду сканировать показания АЦП и если показания ниже порога — Моргать красным диодом.
  • По сигналу с UARТ с целью защиты от ошибок сделать по байту ‘R’ установку флага готовности, а потом, в течении 10ms если не придет байт ‘A’ сбросить флаг готовности и игнорировать все входящие байты кроме ‘R’. Если ‘A’ придет в течении 10мс после ‘R’, то отправить в UART ответ и зажечь белый диод на 1 секунду.

Вот так вот, не сильно сложно. Но мне просто лень делать что либо сложней, а для тестовой задачи сгодится. (далее…)

Read More »

AVR. Учебный курс. Операционная система. Установка

Ядро у нас есть, теперь осталось это все хозяйство запихать на МК. Для этого всего лишь надо рассовать нужные части кода в исходник. Показывать буду на примере ATmega8. Для других МК разница минимальная. Может быть с таймером что нибудь помудрить придется, но не более того.
Например, недавно, вкорячивал ту же схему на ATmega168, так пришлось подправить иницилизацию таймера — регистры там зовутся по другому. Пришлось изменить макрос OUTI — так как многие привычные уже регистры перестали загружаться через комадну OUT — выпали из диапазона, только через LDS/STS ну и, собственно, все хлопоты. Потратил минут 20 на переименование регистров и заработало.
(далее…)

Read More »

AVR. Учебный курс. Операционная система. Таймерная служба

Третья часть марлезонского балета описалова самопальной операционной системы для AVR.

Итак, у нас есть очередь задач и общая логика работы системы. Но одной очереди задач с диспетчером мало. Нужно распределять задачи по времени, задавать интервалы, запускать отложенные задачи. Всем этим будет заниматься служба таймеров.

В чем ее суть ее работы:
Время разбивается на интервалы, скажем, по 1мс. Такой выдержки хватает для большинства задач. Также у нас должна быть очередь программных таймеров, размещенных в ОЗУ. На каждый таймер отводится три байта:
Первый — идентификатор задачи. Два других — выдержка в миллисекундах.

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

Один из свободных аппаратных таймеров программируем на то, чтобы он генерировал прерывание каждые 0.001с

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

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

Read More »

AVR. Учебный курс. Операционная система. Диспетчер задач.

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

Общая диаграмма работы ОС

Что из себя представляет задача
Это практически то же самое, что и процедура, вызываемая командой RCALL с тремя отличиями:

  • Вызывается она не мгновенно, а в порядке очереди.
  • Вызов задачи идет не по ее адресу, а по ее порядковому номеру в таблице переходов.
  • Возврат из нее идет не в то же место откуда вызывали, а в цикл диспетчера задач.

Сама задача представляет собой обычную процедуру, записанную без каких либо замудреностей.
(далее…)

Read More »

AVR. Учебный курс. Операционная система. Введение.

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

В результате было написано микроядро. Камрад Serg2x2 подглядел концепцию в прошивке сотового телефона Motorola и портировал на микроконтроллер АТ89С2051, после ее перенесли на AVR, а я привел все в библиотечный и структурированный вид, обвязал все удобными макросами, а также подробно описал и задокументировал. Так что теперь интеграция ядра операционки в проект под микроконтроллер AVR занимает буквально пару минут работы Copy-Paste.

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

Параметры и системные требования микроядра:

  • Занимаемый обьем в Flash — 500 байт, при желании можно ужать до 400 байт, выкинув ненужные функции.
  • Рекомендуемый объем RAM — не менее 20 байт+стек, впрочем, можно еще ужать если нагрузка небольшая.
  • Крайне желательная поддержка команд STS и LDS, можно и без них, но неудобно. Впрочем, макросы решают.

(далее…)

Read More »

AVR. Учебный курс. Скелет программы

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

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

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

Суперцикл
Все программы на микроконтроллерах обычно зацикленные. Т.е. у нас есть какой то главный цикл, который вращается непрерывно.

Структура же программы при этом следующая:

  • Макросы и макроопредения
  • Сегмент ОЗУ
  • Точка входа — ORG 0000
  • Таблица векторов — и вектора, ведущие в секцию обработчиков прерываний
  • Обработчики прерываний — тела обработчиков, возврат отсюда только по RETI
  • Инициализация памяти — а вот уже отсюда начинается активная часть программы
  • Инициализация стека
  • Инициализация внутренней периферии — программирование и запуск в работу всяких таймеров, интерфейсов, выставление портов ввода-вывода в нужные уровни. Разрешение прерываний.
  • Инициализация внешней периферии — инициализация дисплеев, внешней памяти, разных аппаратных примочек, что подключены к микроконтроллеру извне.
  • Запуск фоновых процессов — процессы работающие непрерывно, вне зависимости от условий. Такие как сканирование клавиатуры, обновление экрана и так далее.
  • Главный цикл — тут уже идет вся управляющая логика программы.
  • Сегмент ЕЕПРОМ

(далее…)

Read More »

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

Таблицы переходов
Вот представь, что нам надо сделать мега CASE, когда на вход валится число от 1 до 100 и нам надо сто вариантов действий.

Как будешь делать? Если лепить сто штук CPI с последующими переходами, то можно дальше убиться головой об стену. У тебя только эти CPI/BR** сожрут половину памяти кристалла. Учитывая, что каждая CPI это два байта, а каждый BR** еще байт. А о том сколько тактов эта шняга будет выполняться я даже не упоминаю.

Делается это все круче. Помнишь я тебе рассказывал в прошлых уроках о таких командах как ICALL и IJMP. Нет, это не новомодная яблочная истерия, а индексный переход. Прикол в том, что переход (или вызов подпрограммы, не важно) осуществляется тут не по метке, а по адресу в регистре Z (о том что Z это пара R30:R31 я пожалуй больше напоминать не буду, пора бы запомнить).
(далее…)

Read More »

AVR. Учебный курс. Флаги и условные переходы

Есть в AVR (да и, пожалуй, во всех остальных процессорах) особый регистр SREG. О нем я несколько раз упоминал в прошлых статьях, но не вдавался в подробности. Чтож, пришло время рассказать, что же это же SREG такой и зачем он нужен.

SREG это регистр состояния ядра. Он так называется Status Register. В этом регистре находится независимых битов — флажков. Которые могут быть либо 1 либо 0, в зависимости от выполненных в прошлом операций.

И вот по тому какие флаги стоят, можно понять что произошло с процессором и что нам дальше делать.

Например, если флаг Z (Zero) выставлен в 1, значит в ходе вычисления предыдущей математической операции в результате образовался ноль.

А если выставлен флаг С (Carry — заем, перенос), то мы из меньшего числа отняли большее, или же прибавили такое число, что результат стал больше 255.

А теперь подробней по каждому флагу.
(далее…)

Read More »

AVR. Учебный курс. Подпрограммы и прерывания

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

Вот, например, кусок кода, передающий в регистр UDR байты с некоторой выдержкой, выдержка делается за счет вращения бесконечного цикла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
	.CSEG
	LDI R16,Low(RAMEND)	; Инициализация стека
	OUT SPL,R16		; Обязательно!!!
 
	LDI R16,High(RAMEND)
	OUT SPH,R16
 
	.equ	Byte 	= 50
	.equ 	Delay 	= 20
 
	LDI	R16,Byte	; Загрузили значение
Start:	OUT	UDR,R16		; Выдали его в порт
 
	LDI	R17,Delay	; Загрузили длительность задержки
M1:	DEC	R17		; Уменьшили на 1
	NOP			; Пустая операция
	BRNE	M1		; Длительность не равна 0? Переход если не 0
 
	OUT	UDR,R16		; Выдали значение в порт
 
	LDI	R17,Delay	; Аналогично
M2:	DEC	R17
	NOP
	BRNE	M2
 
	OUT	UDR,R16
 
	LDI	R17,Delay
M3:	DEC	R17
	NOP
	BRNE	M3
 
	RJMP	Start		; Зациклим программу

Сразу напрашивается повторяющийся участок кода вынести за скобки.

1
2
3
4
	LDI	R17,Delay
M2:	DEC	R17
	NOP
	BRNE	M2

Для этих целей есть группа команд перехода к подпрограмме CALL (ICALL, RCALL, CALL)
И команда возврата из подпрограммы RET
(далее…)

Read More »