Tag Archives: Трюки

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

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

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

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

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

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

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

(далее…)

Read More »

AVR. Учебный Курс. Типовые конструкции

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

▌Условие if-then-else
Тут проще всего методом последовательной проверки проложить маршрут до нужного блока кода. Приведу пример:

1
2
3
4
5
6
7
8
9
if (А>=B)
 	{
	action_a
	}
else 
	{
	action_b
	}
next_action

Как это проще всего сделать на ассемблере?
(далее…)

Read More »

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

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

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

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

Read More »