Моделирование заданных команд микроконтроллера

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    2,35 Мб
  • Опубликовано:
    2013-06-12
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Моделирование заданных команд микроконтроллера

Министерство образования Российской Федерации

Ульяновский государственный технический университет

Факультет информационных систем и технологий

Кафедра «Вычислительная техника»

Дисциплина «Машинно-ориентированное программирование»








Пояснительная записка к Курсовой работе

Вариант A13


Выполнил:

студент гр. ЭВМд-31

Радаев А. И.

Проверил:

Негода В.Н.




Ульяновск 2011

Техническое задание (Вариант 13)

Задача проекта:

В ходе курсового проектирования необходимо на основе анализа исходных данных выполнить моделирование заданных команд, внутренних функциональных устройств и объектов ввода-вывода микроконтроллера.

Интеграция:

Для доступа к моделируемым программно-доступным компонентам и внутренним регистрам микроконтроллера необходимо использовать файл atmega128.h.

Реализация моделируемых команд должна размещаться в файле a13.cpp

Для каждой моделируемой команды разрабатывается отдельная программная функция, имя которой совпадает с мнемоникой ассемблера этой команды:

ORI X, R

(ST -X, Rr)

Для каждой моделируемой команды необходимо разработать тест по технологии, разработанной интегратором

Модель внешнего устройства:

Необходимо разработать модель внешнего устройства I-8082W

Необходимо дать схему подключения моделируемого устройства и ядра микроконтроллера через порты ввода/вывода

Необходимо разработать программу для демонстрации совместной работы микроконтроллера и моделируемого внешнего устройства

Введение

В настоящее время для решения каких-то задач, связанных с обработкой данных с датчиков или других внешних устройств, широко применяются микроконтроллеры. Каждый микроконтроллер имеет свою систему команд, организацию памяти, обработку портов ввода/вывода. Процесс редактирования-компоновки-сборки происходит на любом доступном персональном компьютере. Далее, полученные данные должны быть загружены в память микроконтроллера для дальнейшей интерпретации. В ходе разработки часто приходится прибегать к отладке кода, которая подразумевает: просмотр значений памяти, просмотр значений стека, пошаговое выполнение программы, просмотр регистров состояния микроконтроллера и так далее. Однако если сразу загрузить программу в память устройства, то будет только одна возможность отладки: просмотр результата выполнения программы, следовательно, скорость разработки резко снизиться. Это является первой из причин создания эмуляторов микроконтроллера. Второй причиной является доступность на текущий момент микроконтроллера и/или дополнительных устройств для проверки выполнения программы. Третей причиной является безопасность сопряженных устройств, которые могут повредиться вследствие выполнения некорректной работы микроконтроллера.

Для решения выше изложенных проблем создают специальные программы «эмуляторы», которые полностью могут заменить реальные устройства на этапе отладки программной части работы микроконтроллера. Требования к этим программам-эмуляторам очень просты: как можно ближе соответствовать выполнению кода на реальном устройстве. То есть эмулятор должен поддерживать все необходимые компоненты устройства, такие как регистры, память, адресация, стек, порты ввода/вывода, цикл команд, прерывания. Можно сказать, что требования могут ограничиваться необходимым уровнем абстракции, который позволит решить поставленную задачу.

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

В данной курсовой записке нет детализированного описания архитектуры семейств эмулируемых устройств ATMega128, так как для этого используется полное руководство по устройству. Изложенный материал касается только тех моментов, которые необходимы для выполнения задания по варианту A13.

Компоненты архитектуры ATMega128

Микроконтроллеры семейства Mega (и ATVega128 в частности) как и все микроконтроллеры AVR фирмы “Atmel” являются 8-разрядными микроконтроллерами предназначенными для встраиваемых приложений. Они изготавливаются по малопотребляющей КМОП-технологии, которая в сочетании с усовершенствованной RISC-архитектурой позволяет достичь наилучшего соотношения быстродействие/энергопотребление. Микроконтроллеры данного семейства являются наиболее развитыми представителями микроконтроллеров AVR.

Отличительные особенности

К числу особенностей микроконтроллеров AVR семейства Mega относятся:

• FLASH-память программ объемом 8... 128 Кбайт (число циклов стирания/записи не менее 1000);

• оперативная память (статическое ОЗУ) объемом I...4 Кбайт;

• память данных на основе ЭСППЗУ (EEPROM) объемом 512 байт...4 Кбайт (число циклов стирания/записи не менее 100000);

• возможность защиты от чтения и модификации памяти программ и данных;

• возможность программирования непосредственно в системе через последовательные интерфейсы SPI и JTAG;

• возможность самопрограммирования;

• возможность внутрисхемной отладки в соответствии со стандартом IEEE 1149.1 (JTAG);

• различные способы синхронизации: встроенный АС-генератор с внутренней или внешней времязадающей ЛС-цепочкой или с внешним резонатором (пьезокерамическим или кварцевым); внешний сигнал синхронизации;

• наличие нескольких режимов пониженного энергопотребления;

• наличие детектора снижения напряжения питания (brown-out detector, BOD);

• возможность программного снижения частоты тактового генератора*.

Характеристики процессора:

• полностью статическая архитектура; минимальная тактовая частота равна нулю;

• АЛУ подключено непосредственно к регистрам общего назначения;

• большинство команд выполняются ла один машинный цикл;

• многоуровневая система прерываний; поддержка очереди прерываний. В то же время процессор микроконтроллфов семейства Mega имеет ряд характеристик, присущих именно этому семейству:

• наибольшее число источников прерываний (до 27 источников, из I них до 8 внешних);

• наличие программного стека во всех моделях семейства; I • наличие аппаратного умножителя.

Подсистема ввода/вывод:

• программное конфигурирование и выбор портов ввода/вывода;

• выводы могут быть запрограммированы как входные или как выходные независимо друг от друга;

• входные буферы с триггером Шмитта на всех выводах;

• возможность подключения ко всем входам внутренних подтягивающих резисторов (сопротивление резисторов составляет 35...120кОм)

Архитектура ядра

Ядро микроконтроллеров AVR семейства Mega выполнено по усовершенствованной RISC-архитектуре (enhanced RISC). Арифметико-логическое устройство (АЛУ), выполняющее все вычисления, подключено непосредственно к 32-м рабочим регистрам, объединенным в регистровый файл. Благодаря этому АЛУ выполняет одну операцию (чтение содержимого регистров, выполнение операции и запись результата обратно в регистровый файл) за один машинный цикл. Практически каждая из команд (за исключением команд, у которых одним из операндов является 16-разрядный адрес) занимает одну ячейку памяти программ.

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

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

Организация памяти

Микроконтроллеры AVR семейства Mega являются 8-разрядными микроконтроллерами с RISC-архитектурой. Они имеют электрически стираемую память программ (FLASH) и данных (EEPROM), а также разнообразные периферийные устройства. Следует отметить, что микроконтроллеры семейства Mega имеют самый богатый набор периферийных устройств по сравнению с микроконтроллерами других семейств. Более того, состав этих устройств от модели к модели практически не меняется (меняются только их функциональные возможности). К устройствам, присутствующим не во всех моделях семейства, относятся АЦП, модуль двухпроводного интерфейса TWI (Two Wire Interface, аналог шины 12С), а также модуль интерфейса JTAG.

Структурная схема микроконтроллеров семейства Mega приведена на Рис. На этом рисунке изображена структурная схема наиболее совершенного на сегодняшний день представителя семейства. ATmegal28x. При рассмотрении других моделей, необходимо принимать во внимание присущие им ограничения, такие как наличие тех или иных периферийных устройств и использование контактов ввода/вывода этими устройствами.


В микроконтроллерах AVR семейства Mega реализована Гарвардская архитектура, в соответствии с которой разделены не только адресные пространства памяти программ и памяти данных, но также и шины доступа к ним. Способы адресации и доступа к этим областям памяти также различны. Такая структура позволяет центральному процессору работать одновременно как с памятью программ, так и с памятью данных, что существенно увеличивает производительность. Каждая из областей памяти данных (ОЗУ и EEPROM) также расположена в своем адресном пространстве.

Регистры общего назначения.


Все регистры общего назначения объединены в регистровый файл быстрого доступа, структура которого показана на Рис. В микроконтроллерах AVR все 32 РОН непосредственно доступны АЛУ, в отличие от микроконтроллеров других фирм, в которых имеется только один такой регистр - рабочий регистр W (аккумулятор). Благодаря этому любой РОН может использоваться практически во всех командах и как операнд-источник и как операнд-приемник. Такое решение (в сочетании с конвейерной обработкой) позволяет АЛУ выполнять одну операцию (извлечение операндов из регистрового файла выполнение команды и запись обратно в регистровый файл) за один машинный цикл.


Последние 6 регистров файла (R26-R31) могут также объединяться в три 16-разрядных регистра X, Y, Z, используемых в качестве указателей при косвенной адресации памяти данных.

Регистры ввода/вывода

Все регистры ввода/вывода условно можно разделить на две группы - служебные регистры микроконтроллера и регистры, относящиеся к конкретным периферийным устройствам (в т. ч. регистры портов ввода/вывода).

Во всех микроконтроллерах семейства Mega регистры ввода/вывода располагаются в так называемом пространстве ввода/вывода размером 64 байта. В моделях ATmegal62x, ATmega64x и ATmegal28x, кроме того, имеется пространство дополнительных регистров ввода/вывода размером 160 байт. Введение дополнительных РВВ связано с тем, что для поддержки всех периферийных устройств этих моделей обычных 64-х РВВ недостаточно.

К РВВ, расположенным в основном пространстве ввода/вывода, можц0 напрямую обратиться с помощью команд IN и OUT, выполняющих пересылку данных между одним из 32-х РОН и пространством ввода/вывода, в системе команд имеется также четыре команды поразрядного доступа, использующие в качестве операндов регистры ввода/вывода: команды установки/сброса отдельного бита (SBI и CBI) и команды проверки состояния отдельного бита (SBIS и SBIC). К сожалению, эти команды могут обращаться только к 1-й половине основных регистров ввода/вывода (адреса $00...$1F).

Помимо непосредственной адресации (с помощью команд IN и OUT), к РВВ можно обращаться и как к ячейкам ОЗУ с помощью соответствующих команд ST/SD/SDD и LD/LDS/LDD (для дополнительных РВВ этот способ является единственно возможным).

В первом случае используются адреса РВВ, принадлежащие основному пространству ввода/вывода ($00...$3F). Во втором случае адрес РВВ необходимо увеличить на $20.

Регистр состояния

Среди всех РВВ есть один регистр, используемый наиболее часто в процессе выполнения программ. Этим регистром является регистр состояния SREG. Он располагается по адресу $3F ($5F) и содержит набор флагов, показывающих текущее состояние микроконтроллера. Большинство флагов автоматически устанавливаются в «1» или сбрасываются в «0» при наступлении определенных событий (в соответствии с результатом выполнения команд). Все разряды этого регистра доступны как для чтения, так и для записи; после сброса микроконтроллера все разряды регистра сбрасываются в «0». Формат этого регистра показан на Рис


Команды для эмуляции

Команда ORI - выполнить логическое OR с непосредственным значением

Описание:

Команда выполняет логическое OR между содержимым регистра Rd и константой и размещает результат в регистре назначения Rd.

Операция:

(i)

Rd <-- Rd v K

 

Синтаксис

Операнды:

Счетчик программ:

(i)

ORI Rd,K

16 < d < 31,0 < K <255

PC <- PC + 1


16-разрядный код операции:

0110

KKKK

dddd

KKKK


S:

NV, Для проверок со знаком

V:

0 Очищен

N:

R7 Устанавливается если в результате установлен MSB, в ином случае очищается

Z:

Rd7*R6*R5*R4*R3*R2*R1*R0 Устанавливается если результат $00, в ином случае очищается

R:

(Результат)соответствует Rd после выполнения команды


Команда CPI - cравнить c константой

Описание:

Команда выполняет сравнение содержимого регистра Rd с константой. Содержимое регистра не изменяется. После этой команды можно выполнять любые условные переходы.

Операция:

(i)

Rd = K

 

Синтаксис

Операнды:

Счетчик программ:

(i)

CPI Rd, K

16 =< d =< 31, 0 < K <255

PC <- PC + 1


16-разрядный код операции:

0011

KKKK

dddd

KKKK


H:

Rd3*K3+K3*R3+R3*Rd3 Устанавливается если есть заем из бита 3, в ином случае очищается

S:

NV, Для проверок со знаком

V:

Rd7*K7*R7+ Rd7*K7*R7 Устанавливается если в результате операции образуется переполнение дополнения до двух, в ином случае очищается

N:

R7 Устанавливается если в результате установлен MSB, в ином случае очищается

Z:

R7*R6*R5*R4*R3*R2*R1*R0 Устанавливается если результат $00, в ином случае очищается

C:

Rd7*K7+K7*R7+R7*Rd7 Устанавливается если абсолютное значение K больше абсолютного значения Rd, в ином случае очищается

Команда BRPL - Перейти если плюс

Описание:

Условный относительный переход. Тестируется бит флага отрицательного значения (N) регистра статуса и, если бит очищен, выполняется переход относительно состояния счетчика программ. Данная команда выполняет переход в любом направлении относительно состояния счетчика программ (PC-64 < назначение < PC+63). Параметр k является смещением относительно состояния счетчика программ и представлен в форме дополнения до двух. (Команда эквивалентна BRBC 2,k <#"655973.files/image006.gif">




Устройство I-8082W

Устройство I-8082W представляет собой 8 канальный частотный счетчик или 8 канальный частотомер. Это устройство детектирует отрицательные импульсы, обработка сигнала производится в момент прихода спада (перехода из 1 в 0).

Временная диаграмма


Так как документацию для данного устройства не была найдена, то за основу был взято устройство I-8080. Так как в моем курсовом проекте 8-канальный частотомер(I-8082W), то реализация будет сводится к реализации одного режима работы устройства I-8080.

На каждом канале стоит свой собственный 32 битный счетчик.

Внешний вид устройства:


Частотомер считает количество импульсов поданных за определенный промежуток времени на вход A или B независимо, т. е. каждый вход становится каналом со своим собственным счетчиком. Время измерения (относительно которого считается частота) по умолчанию равна 0.33 секунды. Это время можно задавать.


Анализ базовой программы моделирования

моделирование команда контроллер архитектура

В качестве базовой программы взял не первоначальные исходные тексты выдававшиеся вместе с заданием, а уже переработанный интегратором вариант. Главное изменение внесенное интегратором(Михайлов) - надстройка графического интерфейса пользователя (GUI). Архитектура же самой программы осталась почти без изменений, не считая добавленных заглушек на все команды и их распознавания с выведением информации в лог.

Первоначальный проект включал в себя следующее:.h - Маски операций команд для их определения, коды операций и макросы для работы с флагами SREG- макросы для работы с регистрами ввода вывода. Адреса в макросах считаются относительно пространства ввода/вывода.h, Core.cpp - модель ядра микроконтроллера. Здесь определяются переменные, такие как Счетчик тактов, Память команд и т.п., общие для всех вариантов. Определяются функции заглушки всех моделируемых операций. Реализуется инициализация и, на мой взгляд, не совсем уместная в ядре функция записи в лог..h, OutsideCore.cpp - основной функционал модели. Запуск модели, распознавание ассемблерных операций из HEX кода и их запуск на выполнение, работа с памятью программ, данных, регистрами и т.п. в частности их вывод (формирование строк на вывод). Здесь же реализована работа с файлами, содержащими исходный код моделируемой программы в HEX формате.

Form1.h - GUI использующий Windows Forms.

Разработка и описание программы моделирования

Алгоритмы моделирования команд

Для реализации заданных по варианту команд был создан файл a13.cpp, в котором были реализованы исправные макросы работы с регистром состояния, реализованы макросы для выделения переменных из кода операции (Код команды) и определялись соответствующие методы класса OCore:

void brpl();ori();cpi();movw();bst();set();ldx1();stx3();

Блок-схемы

Команда ORI

Команда CPI

Команда BRPL


Команда MOVW

Команда LD Rd, X


Команда ST -X, Rr


Команда BST


Команда SET


Реализация модели внешнего устройства

Реализация модели внешнего устройства предполагает соответствие модели реальному поведению устройства.

Так как I-8082W представляет 8 счетчиков, то были смоделированы все 8 каналов.

Для моделирования потока входящих в устройство данных - импульсов напряжения - принято решение использовать 1 и 0 как сигнал высокого и низкого уровня соответственно. Данные подаются строкой символов через текстовое поле GUI. Например, модель поданного на вход напряжения высокого уровня с 2 импульсами будет выглядеть как:

Счетчик данного устройства 32 битный, а порты используемые для ввода данных в avr - 8 битные. Следовательно нужно либо использовать управляющие сигналы, либо забивать все 4 порта МК. В итоге использовался первый метод, так как 32 бита это только на одном канале, а если понадобится использовать другие каналы, то на них нужно будет переключаться и желательно уметь это делать программно. В итоге 1 порт(PORTA) был выбран для передачи через него входного сигнала, а второй порт(PORTB) как управляющий для передачи управляющих сигналов на устройство сопряжения.

Модель устройства представлена в файлах I_8082W.h и I_8082W.cpp и пользовательским интерфейсом в файле I_8082W_Form.h

Байт используемого порта был использован следующим образом:

Первые 3 бита были выделены под канал.

Соответственно:

1 канал

000

2 канал

001

3 канал

010

4 канал

011

5 канал

100

6 канал

101

7 канал

110

8 канал

111


Если 4-й бит установлен в «1», то происходит запись в регистр периода, иначе если «0», то считывание.

и 6 биты: Передаваемый в А байт счетчика

-й бит: Сброс

Для работы с портами были написаны следующие макросы:

#define CHANNEL(v) (v & 0x07)

#define READ_WRITE(v)((v & 0x08) >> 3)

#define BYTE(v) ((v & 0x30) >> 4)

#define RESET(v) ((v & 0x40) >> 6)

Класс I_8082W содержит следующие члены:

//Ссылка на ядро МК*_avr;

//Каналы устройства. В данном устройстве их 8.*channels;

Класс channel содержит следующие члены:

//Текущий символ на входе_curA;

//Предыдущий поданный на вход символ_prevA;

//Период в количестве подаваемых символов, в течение которого считается частотаlong _period;

//счетчики импульсов для частотомераint _impulseCount0;

//сколько времени длятся текущий период измерения частоты

unsigned int _stepsCount;

//Счетчик каналаlong _count0;

Внешний вид GUI:


Модель работает следующим образом: При нажатии на кнопку «Шаг» производится один такт микроконтроллера, он соответственно выполняет свою программу, а в модели I-8082W левый символ «съедается» моделью и подается в обработку в метод I_8082W::step().

В этом методе: Здесь обрабатывается один шаг каждого канала. Каждый такт подсчитывается и каждый переход от 1 к 0(потом это значение отображается на форме). После достижения на счетчике значения _period - посчитанные импульсы заносятся в счетчик. И подсчет начинается сначала.

При нажатии на кнопку «Автомат» данные и периоды будут загружены из файла file.txt , который расположен в корне проекта.

Данные в файле располагаются следующим образом:


Т.е входной сигнал и период для каждого канала находятся на одной строке, разделенные пробелом. Нажмем на кнопку «Автомат» и посмотрим, какие данные у нас загрузились:


Так же предусмотрен ручной режим заполнения данных! Пользователь может ввести нужные ему данные и проверить работоспособность устройства. Для этого нужно поставить галочку «Ручной».

Контрольный пример

Исходный файл TEST.asm:

ori r17,2r18,$E7plusr19,3:r16,r0r4,x-x,r3r1,2

set

Исходное состояние памяти данных и флагов:

Флаги:

C

Z

N

V

S

H

T

I

0

0

0

0

0

0

0

0


Память данных


1)Первая команда, которая будет выполнена - команда ORI(логическое ИЛИ между регистром и константой):r17, 2

Регистр: r17 = 0xC0

Константа: 2= r17 | 2 = 0xC0 | 2 = 0xC2

Вычисленный результат запишется в регистр r17.

Состояние памяти данных и флагов после выполнения команды:

Флаги:

C

Z

N

V

S

H

T

I

0

0

1

0

0

0

0

0


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

Память данных


Видно, что теперь в регистре r17 значение изменилось и равно 0xС2

) 2 команда cpi r18,$E7.

После выполнения этой команды содержимое регистра не изменится, а будут изменяться только лишь флаги.= 0x13; K = $E7;

Результат сравнения: Rez = 0x13 -0xE7 = 0x2C = 44 = 0010 1100

Флаги:

C

Z

N

V

H

T

1

0

0

0

0

0


Так как результат получится положительный и ненулевой, флаг N = 0 и Z = 0. Так как получится переполнение, то С установится в «1». Флаг «Т» не изменяется.

3) brpl plusr19,3:

Переход к метке будет осуществлен если значение регистра «N» равно «0». Так как сейчас значение регистра N = 0, то переход к метке «plus» будет осуществлен и команда ori r19,3 не выполнится.

Флаги не изменяются!

) movw r16,r0.

Копируем содержимое регистровой пары r0:r1 в r16:17.

Значения регистров до выполнения:

r0

r1

r16

r17

0xC

0xC0

0x14

0xC2


Значения регистров после выполнения:

r0r1r16r17




0xC

0xC0

0xC

0xC0


) ld r4, x - Косвенное считывание из памяти в регистр

Индексный регистр «Х» располагается в 26 и 27 регистре, но там старшая и младшая часть располагаются как :

Младшая часть

Старшая часть


Поэтому нужно их сначала поменять местами. Для этого мы делаем : short X = ((short)reg[27] << 8) | reg[26];

Получаем Х = 0х2411. И потом записываем в r4 значение dmem[11].

Флаги не изменяются!

)st -x,r3 - Косвенная запись в память данных с преддекрементом

Х = 0х2411; = 0xC0;

//В память по адресу Х записываем регистр Rr[X] = Rr;

Флаги не изменяются!

)bst r1, 2

Устанавливаем 2 бит регистра r1 во флаг Т. = 0xc0 = 1100000 => r1[2] = 0. Отсюда следует что во флаг Т будет записан ноль.

)set

Устанавливаем флаг Т в единицу._T(1);

Список литературы

Предко М. Руководство по микроконтроллерам. Том 2, Москва: Постмаркет, 2001 - 488с.

Евстифеев А.В. Микроконтроллеры AVR семейств Tiny и Mega фирмы “Atmel” - М.: Додэка-XXI, 2004 -560c.

Instruction Set Nomenclature. Atmel

Интернет

Исходный код

а13.cpp

// Модели команд для варианта A13

////--------------------------------------------------------------

//// Код команды ORI: 0110 kkkk dddd kkkk

////--------------------------------------------------------------

#define REG_D_ORI ((cmd & 0x00F0) >> 4)

#define K_ORI((cmd & 0x000F) + ((cmd & 0x0F00) >> 4))

////--------------------------------------------------------------

//// Код команды CPI: 0011 kkkk dddd kkkk

////--------------------------------------------------------------

#define REG_D_CPI ((cmd & 0x00F0) >> 4)

#define K_CPI ((cmd & 0x000F) + ((cmd & 0x0F00) >> 4))

////--------------------------------------------------------------

//// Код команды BRPL: 1111 01kk kkkk k010

////--------------------------------------------------------------

#define K_BRPL (((cmd & 0x03F8) >> 3))

////--------------------------------------------------------------

//// Код команды LDX1: 1001 000d dddd 1100

////--------------------------------------------------------------

#define REG_D_LDX1 ((cmd & 0x01F0) >> 4)

////--------------------------------------------------------------

//// Код команды STX3: 1001 001r rrrr 1110

////--------------------------------------------------------------

#define REG_R_STX3 ((cmd & 0x01F0) >> 4)

////--------------------------------------------------------------

//// Код команды MOVW: 0000 0001 dddd rrrr

////--------------------------------------------------------------

#define REG_D_MOVW ((cmd & 0x00F0) >> 4)

#define REG_R_MOVW (cmd & 0x000F)

////--------------------------------------------------------------

//// Код команды BST: 1111 101d dddd 0bbb

////--------------------------------------------------------------

#define REG_D_BST ((cmd & 0x01F0) >> 4)

#define B_BST (cmd & 0x0007)

//-------------------------------------------------

//--- Логическое ИЛИ между регистром и константой и помещение результата в регистр назначения Rd

//--- Команда: ORI Rd, K

//--- Флаги: Z, N, V

//--- Циклов: 1

//-------------------------------------------------OCore::ori(){

//Считываем Rd

USC Rd = reg[REG_D_ORI + 16];

//Считываем константу К

signed short K = K_ORI;

Rez = Rd | K;

//Устанавливаем флаги

(Rez == 0) ? SET_Z(1) : SET_Z(0);//Z - Флаг нуля

SET_N((Rez & 0x0080) >> 7);//N - Флаг отрицательного результата_V(0);//V - Флаг переполнения в дополнительном коде

//запись результата в регистр данных[REG_D_ORI + 16] = Rez;

++;("ori");

}

//-------------------------------------------------

//--- Сравнение регистра с константой

//--- Команда: CPI Rd, K

//--- Флаги: Z, N, V, C, H

//--- Циклов: 1

//-------------------------------------------------OCore::cpi(){

//Считываем Rd

USC Rd = reg[REG_D_CPI + 16];

//Считываем константу КK = K_CPI;

//Вычисляем разницу между регистром и константой

signed short Rez = Rd - K;

/* Установка флагов */

(Rez == 0) ? SET_Z(1) : SET_Z(0);

SET_N((Rez & 0x80) >> 7);_V((Rez < - 128) || (Rez > 127));_H((Rd & 0x0F) - (K & 0x0F) < 0);_C((K > Rd) ? 1 : 0);

++;

outLog("cpi");

}

//-------------------------------------------------

//--- Переход, если плюс

//--- Команда: BRPL K

//--- Флаги: Нет

//--- Циклов: 1 / 2

//-------------------------------------------------OCore::brpl(){

signed short k = K_BRPL;(SREG_N == 0) {+= k;+= 2;

}

{++;

}("brpl");

}

//-------------------------------------------------

//--- Перезапись слова между регистрами

//--- Команда: MOVW Rd, Rr

//--- Флаги: Нет

//--- Циклов: 1

//-------------------------------------------------OCore::movw(){

USC Rr0 = reg[REG_R_MOVW];Rr1 = reg[REG_R_MOVW + 1];

[REG_D_MOVW << 1] = Rr0;[(REG_D_MOVW << 1)+ 1] = Rr1;

clock += 1;("movw");

}

//-------------------------------------------------

//--- Косвенное считывание из памяти в регистр

//--- Команда: LD Rd, X

//--- Флаги: Нет

//--- Циклов: 2

//-------------------------------------------------OCore::ldx1(){X = ((short)reg[27] << 8) | reg[26];[REG_D_LDX1] = dmem[X];

clock += 2;("ldx1");

}

//-------------------------------------------------

//--- Предварительный декремент и косвенная запись

//--- Команда: ST -X, Rr

//--- Флаги: Нет

//--- Циклов: 2

//-------------------------------------------------OCore::stx3(){X = ((short)reg[27] << 8) | reg[26];Rr = reg[REG_R_STX3];-;[X] = Rr;+= 2;

outLog("stx3");

}

//-------------------------------------------------

//--- Запись бита регистра в T

//--- Команда: BST Rr, b

//--- Флаги: Т

//--- Циклов: 1

//-------------------------------------------------OCore::bst(){Rr = reg[REG_D_BST];B = B_BST;_T((Rr >> B) & 0x0001);

clock++;("bst");

}

//-------------------------------------------------

//--- Установка флага T в регистре SREG

//--- Команда: SET

//--- Флаги: Т

//--- Циклов: 1

//-------------------------------------------------OCore::set(){_T(1);++;("set");

}

W.h

#ifndef I_8082W_H

//#define I_8082W_H

#pragma once

#include "OutsideCore.h"

#include "IODef.h"

#include "channel.h"

#define CHANNEL(v) (v & 0x07)

#define READ_WRITE(v)((v & 0x08) >> 3)

#define BYTE(v) ((v & 0x30) >> 4)

#define RESET(v) ((v & 0x40) >> 6)

class I_8082W

{reset();connectToAVRPorts();

:

//Ссылка на ядро МК*_avr;

//Каналы устройства*channels;

_8082W(OCore *avr);step();run(char *A);

};

#endif

W.cpp

#include "StdAfx.h"

#include "I_8082W.h"

//Инициализация_8082W::I_8082W(OCore *avr)

{

_avr = avr;= new channel[8];

reset();

}

//Выполнение одного шагаI_8082W::step()

{

_avr->step();(int i = 0; i < 8; i++)

{();[i].step(channels[i]._curA);

}

}

//ЗапускI_8082W::run(char *A)

{

}

//Сброс всех каналовI_8082W::reset()

{(int i = 0; i < 8; i++) {[i].reset();

}

}

I_8082W::connectToAVRPorts()

{char portA = _avr->regIO[PORTA];char portB = _avr->regIO[PORTB];

(RESET(portB))

{();

_avr->regIO[PORTB] &= 0xBF;;

}(READ_WRITE(portB))

{

//Запись[CHANNEL(portB)]._period &= !(0xFF << BYTE(portB));[CHANNEL(portB)]._period |= portA << BYTE(portB);

}

{

//Считывание

_avr->regIO[portA] = (channels[CHANNEL(portB)]._count0 >> (8 * BYTE(portB))) & 0xFF;

}

}

.h

#pragma oncechannel

{:

//Текущий символ на входе_curA;

//Предыдущий поданный на вход символ_prevA;

//Период в количестве подаваемых символов,

//в течение которого считается частотаlong _period;

//счетчики импульсов для частотомераint _impulseCount0;

//сколько времени длятся текущий период измерения

//частотыint _stepsCount;

//Счетчик каналаlong _count0;

(void);

set_period(unsigned long period);long get_period();step(char A);reset();frequency(char A);

};.cpp

#include "StdAfx.h"

#include "channel.h"

channel::channel(void)

{();

}

channel::set_period(unsigned long period)

{

_period = period;

}

long channel::get_period()

{_period;

}

channel::step(char A)

{(A);

_prevA = _curA;

}channel::reset()

{

_period = 0;

_impulseCount0 = 0;

_stepsCount = 0;

_count0 = 0;

_prevA = '0';

_curA = '0';

}

channel::frequency(char A)

{(_stepsCount >= _period)

{

_stepsCount = 0;

_count0 = _impulseCount0;

_impulseCount0 = 0;

}((A == '0') && (_prevA == '1'))

{

_impulseCount0++;

}

_stepsCount++;

}

Похожие работы на - Моделирование заданных команд микроконтроллера

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!