Суббота, 20.04.2024, 09:01
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Реклама Google
Форма входа
Категории раздела
Это нужно знать! [17]
Изучаем AVR [30]
Программаторы [12]
Необходимое ПО [8]
Готовые устройства [73]
Справочная [38]
Инструмент [0]
Технология [8]
Литература [0]
Arduino скетчи [18]
Поиск
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Микроконтроллеры - это просто!
Главная » Статьи » Изучаем AVR

Архитектура
Прежде чем приступить к созданию программ для AVR микроконтроллеров,  хорошо бы знать как эти самые программы исполняются, т.е. узнать побольше о архитектуре микроконтроллера. В качестве небольшого вступления, хотел бы отметить тот факт что компания Atmel, как и большинство производителей микроконтроллеров не рассекречивают внутреннее строение своего микроконтроллера, так что придется обходиться материалом предоставляемым разработчиком: даташиты, апп.ноты, блок-схемы и т.д. Таким образом производитель лишает нас возможности покритиковать его схемотехнические решения а также стырить какую-нибудь часть или весь контроллер целиком. В принципе те кому это нужно было давно это сделали.

Итак приступим. Микроконтроллеры AVR реализованны по принципу гарвардской архитектуры, где память программ и память данных, как и шины доступа к ним, разделены. Такое разделение позволяет, к примеру, одновременно считывать новую ассемблерную инструкцию из памяти программ по одной шине и в тот же момент записывать результат предыдущей команды в память данных микроконтроллера (ОЗУ/УВВ/РОН) по другой. Такое "разделение труда” называется конвейером (pipeline) и позволяет выполнять по одной команде за такт.


Рис.1 Архитектура AVR процессора

Память данных (Data Memory)

Одна из ключевых составляющих AVR микроконтроллера является 8-битная Шина Данных (8-bit Data Bus), связывающая между собой ОЗУ, счетчик команд, регистр состояния, регистры периферийных устройств а также RALU (Регистры общего назначения+АЛУ) микроконтроллера.

Память данных представляет собой совокупность регистров общего назначения (РОН), регистров ввода/вывода а также статического ОЗУ (SRAM). В AVR имеются несколько наборов ассемблерных команд которые предназначены специально для адресации, к регистрам ввода/вывода (со своим адресным пространством), а также набор команд для адресации  через шину данных ко всей области памяти данных (со своим адресным пространством).


Рис.2 Память данных

При программировании на языке Си, программист может оперировать несколькими типами данных:

char – 8-битная переменная.
int, short – 16-битные переменные.
long, float, double – 32-битные переменные.
а также struct, union

Если мы объявим переменную внутри функции, то есть сделаем ее локальной, то компилятор выделит для нее один или несколько регистров общего назначения. Если в данный момент не хватает РОН, компилятор поместит переменную в оперативную память (точнее в Стек), что в последствии потребует дополнительные такты для считывания переменной из ОЗУ/Стека. Если мы объявим переменную за пределами функции (сделаем ее глабальной) или определим ее как static, то компилятор не раздумывая выделит для нее место в ОЗУ памяти. Так что совет: старайтесь, по возможности, объявлять переменные внутри функций, тем самым предоставив компилятору возможность для выбора наиболее оптимального размещения переменных.

Также в языке Си можно рекомендовать (необязатель для исполнения) компилятору поместить ту или иную переменную в РОН при помощи ключевоого слова register.

register unsigned char value; // может быть помещена в РОН
static unsigned int data; // будет помещена в ОЗУ

Поскольку AVR, как и большинство 8-битных микроконтроллеров, не умеет (аппаратно) работать с 16-/32-/64-битными переменными, для таких случаев разработаны библиотечные функции, входящие в состав компиляторов высокоуровневых языков, таких как Си. Эти функции реализуют большое количество разнообразных математических/логических и пр. операций, таких как умножение/деление 16-/32-/64-битных переменных со знаком и без, работа с числами с плавающей запятой, работа со структурами, битовыми полями и т.д. Но как вы понимаете использование переменных данного типа, а значит и связанные с ними функции, приводит к увеличению числа тактов необходимых для чтения/записи а также регистров общего назначения используемых при адресации к таким переменным, а самое главное, хотя и небольшое, но дополнительное место в памяти программ, для хранения этих функций.

Память программ (Flash Program Memory)

Программа микроконтроллера по сути представляет собой один большой массив, каждая ячейка которого содержит одну ассемблерную инструкцию, в свою очередь одна ассемблерная инструкция занимает 2 байта памяти программ.  Срок действия памяти программ в AVR микроконтроллерах расчитан на 10000 циклов записи/стирания и может хранить информацию на протяжении 20 лет при температуре в 85°C и до 100 лет при температуре в 25°C.


Рис.3 Память программ

Регистры процессора

Регистры, являются "рабочими лошадками” любого микроконтроллера. При помощи регистров передаются/считываются/хронятся/записываются/вычисляются и т.д. значения переменных, адреса переходов и т.п., через регистры производится настройка и управление периферийными устройствами. Основные регистры учавствующие в вычислениях, контроле, настройке и упралении как периферийными устройствами так и всего микроконтроллера являются: регистровый файл общего назначения, регистр состояния, счетчик команд, указатель стека, регистры ввода/вывода.

Регистровый Файл общего назначения (General Purpose Register File) – регистровый файл состоит из 32 регистров общего назначения. Эти регистры используются в качестве операндов в процесе исполнения команд. При программировании на С, программисту предоставляется возможность оперировать  переменными, которые в поледствии будут помещены компилятором в регистровый файл (РОН) или ОЗУ микроконтроллера. То есть некий уровень абстракции. При программировании на ассемблере, программист работает непосредственно с регистрами общего назначения, адресами ОЗУ и т.д.

Регистр состояния (Status Register) – данный регистр содержит информацию о результате исполнения предыдущей ассемблерной интсрукции. При помощи данного результата, можно менять ход исполнения (ветвление) программы, то есть принимать решения в зависимости от результата предыдущей операции. Арифметические, логические и операции с битами приводят к изменению регистра состояния. Все остальные ассемблерные команды не изменяют поля регистра состаяния.

Счетчик команд (Program counter) – в этом регистре содержится адрес одной ячейки памяти программ (2 байта), то есть адрес ассемблерной инструкции которую на следующем такте надлежит извлечь и передать на исполнение. При подаче напряжения питания (включении микроконтроллера), гарантированно что в счетчике команд, будет находиться значение 0 (нуль), что означает что следующая команда (которая будет передана на исполнение) расположена по адресу 0 (нуль) памяти программ, то есть самая первая команда. После того как команда была извлечена и передана на исполнение, счетчик команд загружает адрес следующей команды.

 PC = PC + 1 // следующая ячейка памяти программ

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

Указатель стека (Stack pointer) – чтобы знать что такое указатель стека, надо знать что такое стек (Stack).



Стек используется в основном для хранения временных данных, таких как локальные переменные (те самые что не помещаются в регистры общего назначения), а также адреса возвратов из подпрограмм/прерываний. Следует отметить, что стек обычно расположен в верхней области ОЗУ, начиная с самой последней ОЗУ ячейки (RAM_END). В нижней ОЗУ, начиная с адреса 0×60 памяти данных, расположены глобальные переменные, массивы данных, константы, область памяти называемая Куча (Heap), используемая для динамического распределения памяти и т.д.

Указатель стека представляет собой два 8-битных регистра, которые всегда указывают на вершину стека, то есть в них хранится адрес последней помещенной в стек переменной. Читать/записывать данные можно только по адресу содержащегося в указателе стека. В то время как "нижняя часть” ОЗУ памяти остается неизменной, стек растет навстречу данным хранящимся в ОЗУ и может случится так, что данные стека перепишут данные ОЗУ. Если такая ситуация произойдет то ход исполнения всей программы будет нарушен и в дальнейшем непредсказуем. Таких ситуаций следует избегать и чтобы их не допустить рекомендуется использовать как можно меньше вложенных функций и временных переменных, а также не тратить попусту ОЗУ, впрочем нехватка оперативки извечная проблема.

Регистры ввода/вывода (I/O registers) – при помощи регистров ввода/вывода реализуется настройка и упраление периферийными устройствами микроконтроллера. При написании программы, регистрами ввода/вывода можно пользоваться как обычными переменными. У большинства периферийных устройств есть регистр контроля (Control Register), при помощи которого можно настроить режим работы периферийного устройства, а также регистр состояния, при помощи которого можно следить за ходом работы периферийного устройства.

В разделе "Instruction Set Summary” каждого даташита, можно найти описание всех ассемблерных инструкций, в том числе какие биты регистра состояния (Flags) они могут изменить, за сколько тактов выполняется каждая инструкция (Clocks).


Рис. 4 Пример ассемблерных инструкций

На рис.4 приведены несколько ассемблерных инструкций из которых можно заметить что команды ветвления (Branch instructions) не воздействуют на регистр состояния (кроме команды reti), а также эти инструкции выполняются за большее число тактов чем остальные. Также здесь можно посмотреть как работают счетчик команд (PC) и указатель стека (STACK).
Категория: Изучаем AVR | Добавил: Alex (28.12.2013)
Просмотров: 2795 | Рейтинг: 5.0/3
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright MyCorp © 2024