MSP430 - учебный курс. Часть 3 - ядро, память и режимы адресации.
План на сегодня таков: 1. Ядро — краткий обзор. 2. Словный и байтный формат команд. 3. Структура памяти. 4. Режимы адресации.
Кстати, пришел заказанный MSP430F247 — ура! Ну а пока я к нему привыкаю, рассмотрим мой любимый MSP430F149.
Это старшая модель в семействе MSP430x1xx — лапы и периферия по максимуму. Кратенько характеристики: — Тактовая частота — до 8 МГц. — Три источника тактирования — один внутренний и два внешних. — 64 ноги (в корпусе QFP c шагом 0.5 мм). — ОЗУ — 2Кб. — ПЗУ (типа FLASH) — 60 Кб. — ЭСППЗУ (EEPROM) — 256 б. — 6 групп портов ввода/вывода (43 порта) — пять по 8 и один 3 линии. — 16-ти битные таймеры (2 штуки, но очень хитрые). — 12 бит АЦП, компаратор. — SPI, USART. — JTAG. — Аппаратный умножитель (нет специальной команды умножения).
Вот внутренняя структура семейства:
Внутренний источник тактирования DCO (Digital Controlled Oscillator) построен на RC-цепочке и имеет частоту около 750 кГц (сильно зависит от температуры). Внешние источники: LFXT1 — работает в двух режимах: высокочастотном (450 кГц… 8 МГц) и низкочастотном (оптимизирован под часовой кварц 32768 Гц). XT2 — высокочастотный — 450 кГц… 8 МГц. Выбор источника тактирования осуществляется программно. При этом, по умолчанию запускается на встроенном. Если мы пытаемся подключить внешний источник и нам это не удалось, контроллер вернётся к работе на встроенный и не зависнет.
Основное о ядре: — 16-ти битная шина адреса (адресует до 64 Кб памяти). — 16-ти битная шина данных. — Ортогональная архитектура (любой режим адресации пригоден для команды, правда есть заморочки для второго операнда). — 16 регистров (4 РСН и 12 РОН) — все могут быть указателями. — Прямой обмен «память -> память». — 51 команда: 27 команд ядра (аппаратных) и 24 эмулированных (псевдонимы). — Байтный и словный формат команд. — Генератор констант, сокращающий код в определённых случаях.
Регистры кратко. R0 — PC (program counter) — счётчик команд. R1 — SP (stack pointer) — указатель стека. Не забудьте инициализировать! R2 — SR (status register) — регистр состояния и управления. Содержит основные флаги состояния, а также флаги управления режимами работы. R3 — CG (constant generator) — генератор констант. R4..R15 — просто регистры общего назначения.
Эмулированные команды — это фикция компилятора. В конечном итоге они будут заменены на какую-либо команду с определённой комбинацией операндов. К примеру «NOP» заменяется на «MOV #0, R3». О генераторе констант поговорим подробнее позже.
2. Словный и байтный формат команд.
Все команды, кроме переходов, поддерживают как побайтное обращение к операндам, так и пословное (2 байта). При написании команды ставится признак типа обращения. Например:
Здесь мы копируем содержимое регистра R4 в R5. В последнем случае, в младший байт R5 будет помещен младший байт R4, а в старший байт R5 будет помещен 0. Обращение к байтам — как по чётным, так и по нечётным адресам. К словам — только по чётным.
3. Структура памяти.
Распределение памяти в контроллере интересное. Т.к. Архитектура Фон-Неймана, то всё находиться в едином адресном пространстве памяти (если кто знаком с x86, тот знает, что там есть ещё одна адресная ось — регистры ввода/вывода, в MSP430 этого нет). Полюбуйтесь:
Внимание! На картинке показано не всё (без BSL и ЭСППЗУ), см. описание ниже.
Диапазон адресов — 0000h..000Fh. В самом низу — регистры специального назначения (не путать с регистрами в ядре!). Их состав зависит от конкретной модели микроконтроллера и предназначены они для работы с некоторыми функциями периферии. Обращение — побайтное.
Диапазон адресов — 0010h..00FFh. Здесь находятся восьмиразрядные регистры модулей периферии. Обращение — побайтное.
Диапазон адресов — 0100h..01FFh. Здесь находятся шестнадцатиразрядные регистры модулей периферии. Обращение — побайтное и пословное.
Первые три области памяти в IAR отображаются как тип SFR вместе — будьте внимательны.
Диапазон адресов — 0200h..09FFh. ОЗУ. Начальный адрес фиксирован (0200h). Конечный адрес зависит от объёма памяти в микроконтроллере. Я указал для 2Кб. Обращение — побайтное и пословное.
Диапазон адресов — 0C00h..0FFFh. Область BSL (Bootstrap Loader). Предустановленный загрузчик, работает через USART. Пока трогать не будем.
Диапазон адресов — 1000h..10FFh. ЭСППЗУ (EEPROM). Тут всё понятно.
Диапазон адресов — 1100h..FFFFh. ПЗУ. Конечный адрес фиксирован (FFFFh), начальный зависит от модели микроконтроллера (по объёму ПЗУ). Я привёл для 60 Кб. Старшие 16 слов ПЗУ отведены под вектора прерывания. Самый последний всегда RESET, остальное зависит от модели. Обращение — побайтное и пословное.
Размещение слова в памяти — младшая часть по меньшему адресу, старшая часть по большему адресу (little-endian, совпадает с принятым в архитектуре x86).
4. Режимы адресации. Вот тут самое интересное место. У MSP430 семь режимов адресации (в реальности меньше, некоторые являются модификациями).
1. Регистровый. Пересылка из/в регистр. Например:
Применим к источнику и приёмнику.
2. Индексный. Пересылка с применением регистра в качестве указателя и смещением.
Смещение(я) идет после кода команды, посему может быть 0..65535. Применим к источнику и приёмнику.
3. Символьный режим. Пересылка с исчислением смещения от PC.
Зверюка похитрее, но на самом деле оказывается модификацией индексного режима. Т.е. данная команда эквивалентна
Где Х = Dest-PC, т.е. разнице содержимого программного счетчика и адреса Dest. Аналогично, для второй Y = Src — PC. Но! Тут кроется большущий подводный камень. Нельзя указывать в операнде значение адреса цифрами, только символьное имя метки. Вернее не совсем нельзя, просто иначе компилятор творит чудеса и вы не получите ожидаемый результат.
Val1 у меня расположен по адресу 200h. Данный режим, чаще всего, используется для создания перемещаемого кода, исполняемого в ОЗУ. Применим к источнику и приёмнику.
4. Абсолютный режим. Пересылка по адресу, указываемому в коде команды. Адрес должен быть известен на момент компиляции.
Вроде бы операции такие же, как и в примере к предыдущему режиму, но адрес не вычисляется, а берется непосредственный. Поэтому здесь можно указывать адрес цифрами.
Применим к источнику и приёмнику.
5. Косвенный регистровый режим. Пересылка по адресу, указанному в регистре (здесь без смещения).
Применим только к источнику.
6. Косвенный регистровый режим с автоинкрементом. Пересылка по адресу, указанному в регистре (здесь без смещения).
Применим только к источнику.
7. Непосредственный режим. Пересылка значения.
Применим только к источнику. Относительно последней строчки примера — так нужно делать для call, но не для jmp.
Ну всё, я спать, а на следующем уроке рассмотрим генератор констант и систему тактирования. А для затравки пример по режимам адресации.
Некоторые замечания по материалу (так сказать вдогонку).
Замечание 1. По режимам адресации. Т.к. регистры ядра не имеют физического адреса, выражаемого числом, то к ним неприменимы следующие режимы адресации: — символьный; — абсолютный; — непосредственный.
Замечание2. По байтному и словному доступу. В словном режиме недопустимо обращение по нечётным адресам памяти! При обмене «регистр -> память»: — при словном режиме младшая часть регистра помещается по меньшему (чётному) адресу, старшая по следующему (+1). — при байтном режиме по адресу обращения помещается младшая часть, старшая игнорируется.
При обмене «память -> регистр»: — при словном режиме в младшую часть регистра помещается значение из меньшего (чётного) адреса, в старшую из следующего (+1). — при байтном режиме в младшую часть регистра помещается значение из ячейки по адресу обращения, в старшую заносится 0.
Замечание 3. Регистр PC (aka R0). Инкремент счетчика команд (только на число, кратное 2!) происходит в момент предшествующий дешифрации команды, после выборки. Это значит, что на момент исполнения команды, счётчик команд указывает на следующую команду. Т.е. код:
даст нам в R4 указатель не на эту команду, а на следующую (в данном случае +2).