Работа с памятью (1058356)
Текст из файла
Работа с памятью
В МК AVR семейства Mega реализована Гарвардская архитектура – разделены не только адресные пространства памяти программ и памяти данных, но и шины доступа к ним. Это позволяет процессору работать одновременно и с памятью программ, и с памятью данных, что существенно увеличивает производительность.
Память программ
Память программ предназначена для хранения команд. Она также часто используется для хранения констант. Так как длинна всех команд кратна 16 битам, память программ имеет 16-разрядную организацию
По адресу $0000 памяти программ находится вектор сброса. При инициализации МК выполнение программы начинается с этого адреса. Начиная с адреса $0002, в памяти программ располагается таблица векторов прерываний. При возникновении прерывания происходит выполнение команды, расположенной по соответствующему адресу. Если прерывания не используются, основная программа может начинаться непосредственно с адреса $0002. Более подробно вопрос прерываний рассматривается далее.
Хранение данных в памяти программ
Для того, что бы хранить данные в памяти программ, надо, первоначально, определить эти данные в коде программы с помощью директивы «.db» или «.dw». Директива .db резервирует память в памяти программ под 1 байт, но можно зарезервировать больше памяти, если перечислять данные побайтно через запятую:
MYDATA: .db 0b10101010,0b11110000
Здесь мы резервируем два байта памяти программ. Обратите внимание на метку перед директивой – по этому имени мы в дальнейшем сможем обращаться к этим данным.
Директива .dw резервирует одно слово – 2 байта:
MYDATA: .dw 0b1111000010101010
Здесь мы зарезервировали те же данные, но при объявлении изменился порядок байт.
После того, как данные объявлены, их можно загрузить в регистры общего назначения командами lpm и lpm Rd,Z (lpm – Load program memory). При использовании команды lpm адрес, в котором находятся данные, определяется индексным регистром Z, а сами данные после выполнения этой команды загружаются в r0. При этом старшие 15 разрядов регистра Z определяют адрес слова, а младший разряд – какой из байтов будет прочитан: 0 – младший, 1 – страший. Команда lpm Rd,Z аналогична команде lpm, но позволяет указывать регистр назначения и индексный регистр.
Пример чтения из памяти программ
.include "m16def.inc"
ser r16
out DDRA,r16
ldi ZH,High(DATA*2)
ldi ZL,Low(DATA*2)
//ori ZL,0b00000001
lpm r16, Z
out PORTA, r16
DATA:
.db 0b101010101,0b1110000
Обратите внимание, что адрес метки умножается на два – компилятор использует 16-разрядную организацию памяти программ, а адрес для команды lpm указывается в байтах.
Также обратите внимание на закомментированную строчку ori ZL,0b00000001 если её раскомментировать, то в порт а выведется 0b1110000, а если нет - 0b101010101.
Память данных
Структура памяти данных приведена на рисунке 1.
Рис 1. Структура памяти данных.
Память данных разделена на три части: регистровая память, оперативная память и энергонезависимое ПЗУ (EEPROM).
Регистровая память включает 32 регистра общего назначения и служебные регистры ввода/вывода.
Для хранения переменных программы помимо РОН может использоваться также и оперативная память, объем которой составляет 1Кбайт(ATmega16).
Для долговременного хранения различной информации может использоваться EEPROM-память. Эта память расположена в отдельном адресном пространстве, а её объем составляет 512 байт(ATmega16).
Работа с ОЗУ
Для работы с ОЗУ предназначены команды lds(Load direct from SRAM) – прямая выгрузка из память и sts(Store direct to SRAM) – прямая запись в память.
В этих командах можно указывать адреса ячеек памяти:
ldi r16,0b11001100
sts 0x62,r16
nop // делаем что-то очень нужное и важное
nop
nop
lds r17,0x62
out PORTA,r17
Для упрощения можно дать адресам символические имена:
.equ MyDataCell = 0x62
ldi r16,0b11001100
sts MyDataCell,r16
nop // делаем что-то очень нужное и важное
nop
nop
lds r17,MyDataCell
out PORTA,r17
Но эти два подхода сопряжены с большими трудностями: а вдруг по адресу 0x62 МК сам что-то хранит. Можно распечатать структуру памяти данных для каждой модели МК постоянно сверятся с ней, а можно поступить проще: заставить компилятор за вас распределить адреса для ваших ячеек данных. Для этого надо определить в программе сегмент данных, и сегмент кода директивами «.dseg» и «.cseg». Сегмент данных должен определяться раньше сегмента кода. В сегменте данных можно зарезервировать определенный объем памяти директивой .byte:
.include "m16def.inc"
// сегмент данных
.dseg
MyData: .byte 1 // резервируем 1 байт
MyFourData: .byte 4 // резервируем 4 байта
// сегмент кода
.cseg
ser r16
out DDRA, r16
ldi r16,0b11001100
sts MyData,r16
nop // делаем что-то очень нужное и важное
nop
nop
lds r17,MyData
out PORTA,r17
Работа с EEPROM
Для работы с EEPROM используются три регистра в/в: регистр адреса, регистр данных и регистр управления.
Регистр адреса называется EEAR и физически размещается в двух регистрах в/в EEARH:EEARL. В этот регистр загружается адрес ячейки, к которой будет производится обращение. Этот регистр доступен как для записи, так и для чтения.
Регистр данных называется EEDR. В этот регистр записываются данные, которые должны быть записаны в EEPROM, и в него помещаются данные при чтении из EEPROM.
Регистр управления EECR используется для управления доступом к EEPROM-памяти. Формат этого регистра приведен на рисунке 2, а описание разрядов – в таблице 1.
Рисунок 2. Структура регистра EECR.
Таблица 1. Разряды регистра EECR
| Разряд | Название | Описание |
| 7…4 | - | Не используются |
| 3 | EERIE | Разрешение прерываний то EEPROM. Если этот разряд установлен, прерывания разрешены. При сброшенном разряде EEWE прерывание генерируется постоянно. |
| 2 | EEMWE | Управление разрешением записи в EEPROM. Состояние этого разряда определяет функционирование флага разрешения записи EEWE. Если данный разряд установлен, то при записи в разряд EEWE «1» происходит запись данных в EEPROM. После программной установки данный разряд сбрасывается аппаратно через 4 машинных цикла. |
| 1 | EEWE | Разрешение записи в EEPROM. После установки этого разряда в 1 происходит запись данных в EEPROM. |
| 0 | EERE | Разрешение чтения из EEPROM. После установки этого разряда в «1» выполняется чтение из EEPROM. По окончании чтения этот разряд сбрасывается аппаратно. |
Процедура записи одного байта в EEPROM следующая:
-
Дождаться готовности EEPROM к записи данных (ждать пока не сбросится флаг EEWE регистра EECR).
-
Дождаться завершения записи во FLASH-память программ (ждать пока не сбросится флаг SPMEN регистра SPMCR).
-
Загрузить байт данных в регистр EEDR, а требуемый адрес – в регистр EEAR.
-
Установить в «1» флаг EEMWE регистра EECR.
-
Записать в разряд EEWE регистра EECR лог. «1» в течении 4-х машинных циклов. После установки этого разряда процессор пропускает 2 машинных цикла перед выполнением следующей инструкции.
При записи в EEPROM могут возникнуть некоторые проблемы:
-
При возникновении прерывания между 4-м и 5-м этапами, запись в EEPROM будет сорвана, так как за время обработки прерывания флаг EEMWE сбросится в 0.
-
Если в подпрограмме обработки прерывания, возникшего во время записи в EEPROM-память, также происходит обращение к ней, то будет изменено содержимое регистров адреса и данных EEPROM. В результате первая запись будет сорвана.
Для избежания описанных проблем рекомендуется запрещать прерывания на время выполнения пунктов 2-5.
Процедура чтения из EEPROM приведена ниже:
-
Дождаться готовности EEPROM к записи данных (ждать пока не сбросится флаг EEWE регистра EECR).
-
Загрузить требуемый адрес в регистр EEAR.
-
Установить в «1» разряд EERE регистра EECR. После установки этого разряда процессор пропускает 4 машинных цикла перед началом выполнения следующей инструкции.
Функции чтения-записи EEPROM .
EEPROM_Write:
sbic EECR,EEWE
rjmp EEPROM_Write
//cli
out EEARH, r18
out EEARL, r17
out EEDR, r16
sbi EECR, EEMWE
sbi EECR, EEWE
//sei
ret
EEPROM_Read:
sbic EECR,EEWE
rjmp EEPROM_Read
out EEARH, r18
out EEARL, r17
sbi EECR, EERE
in r16, EEDR
ret
Для использования функции EEPROM_Write следует записать в регистр r17 младшую часть адреса, в регистр r18 – старшую часть, а в регистр r16 – данные для записи.
Для использования функции EEPROM_Read следует записать в регистр r17 младшую часть адреса, в регистр r18 – старшую часть. После вызова функции в регистре r16 будут необходимые данные.
Обратите внимание на закомментированные строки в функции записи в EEPROM: они запрещают/разрешают прерывания. Для использования этой функции в программе с прерываниями их нужно раскомментировать.
Также следует обратить внимание на то, что это функции! Следовательно, перед использованием команд rcall или call следует инициализировать стек следующим образом:
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
Регистры SPH и SPL – указатели стека, старший и младший байты.
Характеристики
Тип файла документ
Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.
Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.
Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.















