1.7. Стек. Указатель стека — Stack Pointer — sp
Микроконтроллер AVR ATmega8515оснащен 16-разрядным указателем стека– регистром SP, размещенным в двух регистрах пространства I/O по адресам $3E ($5E) и $3D ($5D) (Таблица 1). Поскольку ATmega8515 поддерживает объем SRAM до 64 Кбайт, то используются все 16 разрядов указателя стека.
Указатель стека указывает на область в SRAM данных, в которой размещаются стеки подпрограмм и прерываний. Объем стека в SRAM данных должен задаваться программой перед каждым вызовом подпрограммы и обработкой разрешенного прерывания. Указатель стека декрементируется на единицу, при каждом занесении командой PUSH данных в стек, и на две единицы при занесении данных в стек подпрограммой CALL и прерыванием.
Указатель стека инкрементируется на единицу, при извлечении данных из стека командой POP, и на две единицы при извлечении данных из стека при возврате из подпрограммы (RET) или возврате из прерывания (IRET).
1.8. Тактирование. Режимы пониженного энергопотребления
1.8.1. Тактовый генератор
Тактовый генератор вырабатывает импульсы для синхронизации работы всех узлов микроконтроллера. Внутренний тактовый генератор AVR может запускаться от нескольких источников опорной частоты (внешний генератор, внешний кварцевый резонатор, внутренняя или внешняя RC-цепочка). Минимальная допустимая частота ничем не ограничена (вплоть до пошагового режима). Максимальная рабочая частота определяется конкретным типом микроконтроллера и указывается Atmel в его характеристиках.
Выводы XTAL1 и XTAL2 являются входом и выходом, соответственно, инвертирующего усилителя, который с использованием кварцевого кристалла или керамического резонатора работает как встроенный генератор, как показано на Рис. 15, При использовании внешнего источника тактовой частоты вывод XTAL2 должен остаться свободным, сигнал подается на вывод XTAL1, как показано на Рис. 16.
Кварцевый кристалл генератора таймера подсоединяется непосредственно к выводам OSC1 и OSC2. Внешние конденсаторы не требуются. Генератор оптимизирован под часовой кварц с частотой 32,768 КГц. Внешний тактовый сигнал, подаваемый на эти выводы, поступает на усилитель с полосой пропускания 256 КГц.


Рис. 15. Подсоединение тактового генератора
Рис. 16. Подсоединение внешнего источника тактового сигнала
Система реального времени (rtc)
RTC реализована во всех микроконтроллерах Megа. Таймер/счетчик RTC имеет отдельный предделитель, который может быть программным способом подключен или к источнику основной тактовой частоты, или к дополнительному асинхронному источнику опорной частоты (кварцевый резонатор или внешний синхросигнал). Для этой цели зарезервированы два вывода микросхемы. Внутренний осциллятор оптимизирован для работы с внешним «часовым» кварцевым резонатором 32,768 кГц.
AVR функционируют при напряжениях питания от 1,8 до 6,0 Вольт. Ток потребления в активном режиме зависит от величины напряжения питания и частоты, на которой работает микроконтроллер, и составляет менее 1 мА для 500 кГц,5 . 6 мА для 5 МГц.
3.8. Стек и указатель стека
Стек необходим для запоминания адресов возврата из процедур обработки прерывания и подпрограмм. Его также можно использовать для временного хранения данных. Регистр указателя стека (SP) постоянно указывает на вершину стека. Он реализован в виде двух 8-битных регистров, доступных в пространстве памяти ввода-вывода. Данные помещаются в стек и извлекаются из него посредством инструкций PUSH и POP. Увеличение стека происходит в направлении от старших ячеек памяти к младшим. Таким образом, при помещении данных в стек содержимое регистра SP уменьшается, а при извлечении данных — увеличивается. После сброса, SP автоматически инициализируется значением, которое равно максимальному адресу внутреннего SRAM. При необходимости изменения SP нужно учитывать, что помещаемый в него адрес должен лежать выше 0x2000, а само изменение нужно выполнить перед вызовом каких-либо подпрограмм или разрешением прерываний.
При вызове подпрограмм или при переходе по вектору прерываний адрес возврата автоматически помещается в стек. Адрес возврата может быть представлен двумя или тремя байтами, что зависит от размера памяти микроконтроллера. У МК с памятью программ 128 кбайт и менее адрес возврата двухбайтный, поэтому, указатель стека декрементируется/инкрементируется на два. У тех же микроконтроллеров, которые оснащены памятью программ размером более 128 кбайт, адрес возврата трехбайтный, а декрементирование/инкрементирование SP выполняется на три. Адрес возврата извлекается из стека при выходе из прерывания по инструкции RETI, а из подпрограммы по инструкции RET.
Если инструкцией PUSH в стек помещаются данные, то SP декрементируется на единицу. Аналогичным образом, при извлечении данных из стека инструкцией POP содержимое SP инкрементируется на единицу.
Чтобы предотвратить сбой в выполнении программы при программном обновлении указателя стека, операция записи в SPL приводит к автоматическому отключению прерываний на время выполнения до четырех инструкций или до следующей операции записи в память ввода-вывода.
Указатель стека — Stack Pointer — SP
Микроконтроллеры AVR оснащены 16-разрядным указателем стека, размещенным в двух регистрах пространства I/O по адресам $3E ($5E) и $3D ($5D). Поскольку микроконтроллеры ATmega603/103 поддерживают объем SRAM до 64 Кбайт, то используются все 16 разрядов указателя стека.
Указатель стека указывает на область в SRAM данных, в которой размещаются стеки подпрограмм и прерываний. Объем стека в SRAM данных должен задаваться программой перед каждым вызовом подпрограммы и обработкой разрешенного прерывания. Указатель стека декрементируется на единицу, при каждом занесении командой PUSH данных в стек, и на две единицы при занесении данных в стек подпрограммой CALL и прерыванием.
Указатель стека инкрементируется на единицу, при извлечении данных из стека командой POP, и на две единицы при извлечении данных из стека при возврате из подпрограммы (RET) или возврате из прерывания (IRET).
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
| SP15 | SP14 | SP13 | SP12 | SP11 | SP10 | SP9 | SP8 |
| SP7 | SP6 | SP5 | SP4 | SP3 | SP2 | SP1 | SP0 |
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W |
| R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7. Виды памяти микроконтроллеров (на примере семейства avr). Стек и его инициализация.
В МК AVR реализована Гарвардская архитектура, в соответствии с которой разделены не только адресные пространства памяти программ и памяти данных, но также и шины доступа к ним.
- Память программ: FLASH;
- Память данных: оперативная память (ОЗУ) SRAM (Static RAM) и энергонезависимая память данных EEPROM.
Адресные пространства указанных видов памяти, как правило, разделены. Способы адресации и доступа к этим областям памяти также различны. Такая структура позволяет центральному процессору работать одновременно как с памятью программ, так и с памятью данных, что существенно увеличивает производительность. Каждая из областей памяти данных (SRAM и EEPROM) также расположена в своем адресном пространстве.
Обобщенная карта памяти AVR микроконтроллеров приведена на рисунке 1.

Рисунок 1 – Структура памяти МК AVR
Память программ
Память программ предназначена для хранения команд, управляющих функционированием микроконтроллера, также используется для хранения таблиц констант, не меняющихся во время работы программы.
Память программ представляет собой электрически стираемое программируемое постоянное запоминающее устройство (ППЗУ, FLASH ПЗУ). Так как длина всех команд кратна одному слову (16 бит), память программы имеет 16-разрядную организацию.
Логическая память программы разделена на две неравные части – область прикладной программы и область загрузчика. В последней может располагаться специальная программа, позволяющая микроконтроллеру самостоятельно управлять загрузкой и выгрузкой прикладных программ.
[Не знаю насколько это нужно писать в билете, но знать стоит…
Если возможность самопрограммирования не используется, то прикладная программа может располагаться и в области загрузчика.
Для адресации памяти программ используется счетчик команд. Размер счетчика команд составляет 12…16 разрядов, в зависимости от объема адресуемой памяти.
По адресу 0х0000 памяти программ находится вектор сброса. После инициализации МК (сброса) выполнение программы начинается с этого адреса. Начиная с адреса 0х0001 или 0х0002 памяти программ, располагается таблица векторов прерываний. Размер этой области зависит от МК.
При возникновении прерывания, после сохранения в стеке текущего значения счетчика команд, происходит выполнение команды, расположенной по адресу соответствующего вектора. Поэтому по данным адресам располагаются команды перехода к подпрограммам обработки прерываний.
Положение вектора сброса и таблицы векторов прерываний может быть перенесено из секции прикладных программ в секцию загрузчика.
В моделях с объемом памяти менее 8 Кбайт в качестве этих команд используются команды относительного перехода (RJMP), а в остальных моделях – команды абсолютного перехода (JMP).
В качестве промежуточных операторов используют 32 ячейки – оперативные регистры общего назначения (РОН). Доступ к этим ячейкам самый быстрый, а число операций с их содержимым наиболее разнообразное.
РОН делятся на три группы:
- Младшие 0 – 15 обычные регистры общего назначения, в некоторым смысле неполноценные. С ними не работают многие команды (загрузка непосредственного числа).
- Старшие 16 – 31 полноценные регистры, работающие со всеми командами.
- Индексные 26 – 31 шесть последних регистров из старшей группы отличаются от остальных. Их можно использовать и как обычные регистры, но также они могут образовывать регистровые пары X(R26:R27), Y(R28:R29), Z(R30:R31), которые используются как указатели при работе с памятью …]
Память данных
Память данных разделена на 3 части:
- регистровая память;
- оперативная память (статическое ОЗУ);
- энергонезависимое EEPROM (ЭСППЗУ – электрически стираемое перепрограммируемое ПЗУ).
Регистровая память включает 32 РОН, объединенных в файл, и служебные регистры ввода/вывода (РВВ – регистры управления мк, регистры состояния). И те и другие расположены в адресном пространстве ОЗУ, но не являются его частью.
В старших моделях мк имеется область дополнительных (Extended) регистров ввода/вывода (ДРВВ). РВВ – 64 байта в памяти, ДРВВ – 160 байт. Введение дополнительных РВВ связано с тем, что для поддержки всех периферийных устройств этих моделей обычных 64 регистров недостаточно.
Оперативная память (ОЗУ), предназначенная для временного хранения переменных. Она есть не везде. Оперативная память представляет собой несколько сотен ячеек для временного хранения данных, от 64 байт до 4 килобайт, в зависимости от модели. В этих ячейках могут храниться любые данные, а доступ к ним осуществляется через команды LOAD и STORE.
Для некоторых микроконтроллеров возможна организация подключения внешнего статического ОЗУ объемом до 64К.
EEPROM-память предназначена для долговременного хранения различной информации, которая может изменяться в процессе функционирования микроконтроллерной системы. Все AVR имеют блок энергонезависимой электрически перезаписываемой памяти данных EEPROM от 512 Байт до 4 КБайт. Эта память расположена в отдельном адресном пространстве, а доступ к ней осуществляется с помощью определенных РВВ.
Этот тип памяти, доступный программе микроконтроллера непосредственно в ходе ее выполнения, удобен для хранения промежуточных данных, различных констант, коэффициентов, серийных номеров, ключей и т.п. EEPROM может быть загружена извне как через SPI интерфейс, так и с помощью обычного программатора. Число циклов стирание/запись — не менее 100 тыс.
Стек представляет собой область памяти, которую ядро МК использует для сохранения и восстановления адресов возврата из подпрограмм и прерываний. Практически у всех микроконтроллеров AVR стек размещается в оперативной памяти.
Для адресации текущего элемента (вершины стека) используется указатель стека SP (Stack Pointer). Это однобайтовый регистр ввода-вывода SPL у моделей с объемом памяти данных до 256 байт, или двухбайтовый SPH:SPL (SPH – старший байт, SPL – младший байт) у старших моделей с большим объемом памяти.
Так как после подачи напряжения питания (или после сброса) в регистрах содержится нулевое значение, в самом начале программы указатель стека необходимо проинициализировать, записав в него значение конечного адреса памяти данных.
Возврат из подпрограммы
1. Адрес команды, стоящей за командой вызова сохраняется в стеке
2. Значение указателя стека уменьшается на 2 байта
1. Адрес извлекается из стека
2. Загружается в счетчик команд
3. Значение указателя стека увеличивается на 2 байта
2 байта, так как для хранения счетчика команд требуется два байта.
То же происходит и во время вызова прерываний.
Схематичное расположение стека в памяти данных представлено на рисунке 2.

Рисунок 2 – Расположение стека в памяти данных
Во всех моделях AVR стек доступен со стороны пользовательской программы и может быть использован в процессе выполнения программы. Для работы со стеком существует всего две команды: занесение в стек (PUSH) и извлечение из стека (POP).
LDI R16, Low (RAMEND); устанавливаем SP = RAMEND
LDI R16, High (RAMEND)
RAMEND – это макроопределение, указывающее на конец ОЗУ для каждого конкретного мк.
Программист должен самостоятельно определить местоположение стека в самом начале программы. С точки зрения максимальной его глубины, вершину стека нужно поместить в самом конце SRAM, как это показано на рисунке 2.
Очень важно предварительно оценить максимальный размер стека (глубину стека). Может случиться так, что вершина стека поднимется слишком высоко и начнет “затирать” пользовательские данные, а это одна из самых сложно-выявляемых ошибок!
Стек AVR, помимо сохранения адресов возврата позволяет сохранять любые данные специально предназначенными для этого командами push Rr (загрузка в стек) и pop Rd (выгрузка из стека).