Разработка схемы микроЭВМ на базе микроконтроллера семейства AVR Classic

Тип работы:
Контрольная
Предмет:
Коммуникации, связь, цифровые приборы и радиоэлектроника


Узнать стоимость

Детальная информация о работе

Выдержка из работы

РОСЖЕЛДОР

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«Ростовский государственный университет путей сообщения»

(ФГБОУ ВПО РГУПС)

Кафедра «Связь на железнодорожном транспорте»

Контрольная работа по дисциплине

«Техника микропроцессорных систем в электросвязи»

Выполнил: студент

заочного факультета

группы МСУ-3−005

шифр 2450, вариант № 5

А. Б. Веретющенков

Проверил: доцент,

кандидат т.н.

В. Н. Трофименко

Ростов-на-Дону

2012

Оглавление

Введение

1. Теоретические сведения о контроллерах

1.1 Микропроцессорные системы

1.2 Микроконтроллеры

1.3 Микроконтроллер семейства AVR Classic

2. Реализация проекта

2.1 Общие сведения об устройстве микроконтроллера

2.1.1 Разработка схемы микроконтроллера

2.2 Разработка программы микроконтроллера

2.2.1 Подготовка к написанию проекта

2.2.2 Разработка программы

2.3 Симуляция проекта в программе Proteus 7

Заключение

Литература

Приложение 1. Текс программы на ассемблере

Введение

В данной контрольной работе разработана схема микро_ЭВМ на базе микроконтроллера семейства AVR Classic с подключёнными к нему двумя кнопками (переключателями), двумя светодиодами и двумя семисегментными индикаторами, включёнными по схеме динамической индикации. Также написана программа на языке низкого уровня ассемблере, реализующая следующий алгоритм: при нажатии кнопок происходит подсвечивание светодиодов и увеличение/уменьшение двухзначного шестнадцатеричного числа, выводимого на семисегментные индикаторы.

1. Теоретические сведения о контроллерах

1.1 Микропроцессорные системы

Микропроцессором (МП) называют построенное на одной или нескольких больших/сверхбольших интегральных схем (БИС/СБИС) программно-управляемое устройство, осуществляющее процесс обработки информации и управление им.

МП — центральный процессорный элемент микропроцессорной системы (МПС или микро-ЭВМ), в которую также входят память и устройства ввода/вывода (внешние устройства).

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

Совокупность БИС/СБИС, пригодных для совместного применения в составе микро-ЭВМ, называют микропроцессорным комплектом БИС/СБИС (МПК).

Понятие МПК задает номенклатуру микросхем с точки зрения возможностей их совместного применения (совместимость по архитектуре, электрическим параметрам, конструктивным признакам и др.). В состав МПК могут входить микросхемы различных серий и схемотехнологических типов при условии их совместимости.

1.2 Микроконтроллеры

Основной особенностью современного этапа развития микропроцессорных систем является завершение перехода от систем, выполненных на основе нескольких БИС, к однокристальным микроконтроллерам (МК). Микроконтроллеры — разновидность МПС, ориентированная на реализацию алгоритмов управления техническими устройствами и технологическими процессами. Первые М К выпущены фирмой Intel в 1976 г (восьмиразрядный МК 8048).

МК реализуют заранее известные несложные алгоритмы, и для размеще-ния программ им требуются меньшей, чем у микро-ЭВМ широкого на-значения, емкости памяти. Набор внешних устройств также существенно сужается, а сами они значительно проще. Это позволяет все модули микро-ЭВМ разместить на одном кристалле.

МК объединяют в одном кристалле все основные элементы МПС: цен-тральный процессор (ЦП), постоянное запоминающее устройство (ПЗУ), оперативное запоминающее устройство (ОЗУ), последовательные и параллельные порты ввода/выводы, таймеры, аналого-цифровые и цифро-аналоговые преобразователи, широтно-импульсные модуляторы и другие узлы вычислительной системы. Поэтому вторым названием МК стало название «однокристальная микро-ЭВМ».

Для большинства приложений упрощенной структуры МК оказывается достаточной. Это и определяет их преобладание в таких областях, как бытовая аппаратура, станкостроение, автомобильная промышленность и т. д.

Наиболее распространенным представителем семейства МК являются 8-разрядные приборы, широко используемые в промышленности, бытовой и компьютерной технике. Они прошли в своем развитии путь от простейших приборов с относительно слаборазвитой периферией до современных многофункциональных контроллеров, обеспечивающих реализацию сложных алгоритмов управления в реальном масштабе времени. Причиной жизнеспособности 8-разрядных МК является использование их для управления реальными объектами, где применяются, в основном, алгоритмы с преобладанием логических операций, скорость обработки которых практически не зависит от разрядности процессора.

Росту популярности 8-разрядных МК способствует постоянное расширение номенклатуры изделий, выпускаемых такими известными фирмами, как Motorola, Microchip, Intel, Zilog, Atmel и многими другими.

Современные 8-разрядные МК обладают, как правило, рядом отличи-тельных признаков. Перечислим основные из них:

v модульная организация, при которой на базе одного процессорного ядра (центрального процессора) проектируется ряд (линейка) МК, различающихся объемом и типом памяти программ, объемом памяти данных, набором периферийных модулей, частотой синхронизации;

v использование закрытой архитектуры МК, которая характеризуется отсутствием линий магистралей адреса и данных на выводах корпуса МК. Таким образом, МК представляет собой законченную систему обработки данных, наращивание возможностей которой с использованием параллельных магистралей адреса и данных не предполагается;

v использование типовых функциональных периферийных модулей (таймеры, процессоры событий, контроллеры последовательных интерфейсов, аналого-цифровые преобразователи и др.), имеющих незначительные отличия в алгоритмах работы в МК различных произ-водителей;

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

1.3 Микроконтроллер семейства AVR Classic

В1997 г. фирма Atmel представила первые МК семейства AVR. Семейст-во AVR AT90S объединяет мощный гарвардский RISC-процессор с раздельным доступом к памяти программ и данных, 32 регистра общего назначения и развитую систему команд. Последние версии семейства AVR имеют в составе АЛУ аппаратный умножитель. Базовый набор команд AVR содержит 120 инструкций. Большинство команд выполняется за один машинный цикл, производительность ряда моделей составляет 20 MIPS. Периферия AVR включает параллельные порты, таймеры-счетчики, различные последовательные интерфейсы, АЦП, аналоговые компараторы. МК AVR подразделяются на три серии:

v tiny AVR — МК в 8-выводном корпусе низкой стоимости;

v classic AVR — основная линия МК с производительностью до 16 MIPS, Flash память программ объемом до 8 Кбайт и статическим ОЗУ данных 128… 512 байт;

v mega AVR — МК для сложных приложений, требующих большого объема памяти (Flash ПЗУ до 128 Кбайт), ОЗУ до 4 Кбайт, производительно-стью до 16 MIPS.

Приведенная краткая аннотация семейств 8-разрядных МК является далеко не полной, 8-разрядные МК выпускают также фирмы ST-Microelectronics (семейства ST6, ST7 и ST9), National Semiconductor (семейство СОР8), Zilog, NEC, Mitsubishi, Hitachi, Toshiba, Scenix и др. Продукция этих фирм постепенно появляется на российском рынке, но пока не получила широкого распространения.

2. Реализация проекта

2.1 Общие сведения об устройстве микроконтроллера

Схему выполним на контроллере AT90S2313 фирмы «Atmel».

Чтобы понять, как работает контроллер, надо знать, что у него внутри. На рисунке 1 приведена упрощённая структурная схема микроконтроллера.

Рисунок 1 — Структурная схема микроконтроллера

Самый главный элемент любого процессора — арифметико-логический узел (АЛУ — англ. ALU (ariphmetic-logical unit)). В нём происходят логические операции над двоичными

Выбранный контроллер работает с 8-разрядными двоичными числами, то есть он 8-битный. Это значит, что АЛУ может захавать два 8-битных слова, произвести над ними какую то арифметическую или логическую операцию, и выплюнуть ответ — опять же, 8-битное слово.

Чтобы произвести операцию, АЛУ должен взять откуда-то два числа. Выполнив операцию, опять же, должен положить куда-то ответ. Для этих целей служат регистры общего назначения — РОН. В контроллере AT90S2313 их 16. Каждый регистр — это ячейка памяти емкостью 8 бит (1 Байт). Именно в них и хранятся числа, с которыми работает АЛУ.

Для каждой команды, которую выполняет АЛУ, необходимо назвать те регистры, с которыми он будет в данный момент работать. Например: add R16, R17 — сложить значение регистров R16 и R17 и положить ответ в R16. Ответ всегда помещается в тот регистр, который назван первым, при этом старое содержимое регистра затирается.

Кроме РОН, на схеме присутствует ОЗУ — оперативная память контроллера. Она нужна для того, чтобы хранить данные при выполнении программы. В регистрах хранится, обычно, только те данные, которые будут использоваться непосредственно прямо сейчас. Все остальное удобнее положить в оперативную память.

Также в контроллере существует регистр команд. В этот регистр постепенно выводятся команды той программы, которую выполняет контроллер. Эти команды касаются всего контроллера, а не только АЛУ.

В регистр команд, команды попадают из программной памяти. Программная память — это ПЗУ (постоянное запоминающее устройство), в котором по каждому адресу записана одна команда. Вместе, все эти команды и составляют программу, и записаны в той последовательности, в какой они стоят в программе.

Команды записываются в ячейки в той последовательности, в которой стоят в программе. Поэтому, для того чтобы последовательно выполнять команды, достаточно просто каждый раз прибавлять к адресу единицую Именно этим и занимается счетчик команд. В ответ на запрос счетчика команд ПЗУ выдаёт содержимое ячейки по запрошенному адресу.

Для обмена информацией с внешним миром существуют порты ввода/вывода (ПВВ).

Порт — это пачка однобитных каналов, каждый из которых может быть независимо настроен либо на ввод, либо на вывод.

В контроллере AT90S2313 два ПВВ — PortB и PortD. PortB состоит из 8-ми каналов, PortD — из 7-ми.

Алгоритм работы схемы следующий: при нажатии кнопок происходит подсвечивание светодиодов и увеличение/уменьшение двухзначного шестнадцатеричного числа, выводимого на семисегментные индикаторы

2.1.1 Разработка схемы микроконтроллера

Конфигурация выводов микроконтроллера AT90S2313 из технического описания данного контроллера изображена на рисунке 2.

Рисунок 2 — Конфигурация выводов микроконтроллера

На рисунке 3 представлена разработанная схема проекта

Рисунок 3 — Разработанная схема проекта

Обоснуем выбор номинала резисторов в цепи светодиодов: сила тока, проходящего через диоды составлят в среднем 15 мА, а падение напряжения на них — 1,5 В. При напряжении на выходе контроллера равняется 5 В, сопротивление резистора должно составлять:

В схеме номинал резисторов выбран с запасм — 300 Ом.

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

2.2 Разработка программы микроконтроллера

2.2.1 Подготовка к написанию проекта

Для написания программы на языке ассемблер воспользуемся встроенным в ОС «Windows» текстовым редактором «Блокнот». Трансляцию программы в машинный код произведём при помощи компилятора «avrasm32. exe», устанавливаемого вместе с бесплатным программным продуктом «AVR Studio 4» фирмы «Atmel», который можно скачать с сайта www. atmel. com.

Вначале создадим папку «Проект», в которой будут храниться файлы, относящиеся к проекту. Внутри папки создадим файл «Processor. asm», в котором будет код программы на ассемблере. Для компиляции создадим в этой же папке исполняемый файл «Processor. bat». Запишем в него следующие строки:

avrasm32. exe Processor. asm

pause=null

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

Теперь скопируем в папку проекта сам компилятор «avrasm32. exe», расположенный в директории установки программы «AVR Studio» по адресу:

…AtmelAVR ToolsAvrAssembler.

Там же в папке «. Appnotes» находится заголовочный файл для используемого контроллера «2313def. inc», скопируем и его.

Таким образом, в папке проекта должны быть следующие файлы: «2313def. inc», «avrasm32. exe», «Processor. asm», «Processor. bat». В процессе компиляции будет создан файл «Processor. hex», содержащий машинный код, который будет записываться в программную память контроллера.

2.2.2 Разработка программы

Теперь, когда подготовка окончена, можно приступать к написанию программы. Как указано выше, программу будем писать в файле «Processor. asm».

Первым делом подключаем заголовочный файл с помощью директивы «. include»:

. include «2313def. inc»

Далее, используя директиву «. def», назначим используемым нами регистрам символьные имена:

. def var=r16

. def pressedBtn=r17

. def var1=r18

. def var2=r19

. def ind=r20

. def num=r21

. def i=r24

. def var3=r25

. def ledOn=r26

Теперь при помощи директивы «. cseg» объявим о начале текста программы, а директивой «. org» назначим адрес ПЗУ для первой команды

. cseg

. org 0

Кроме программного сегмента, бывает сегмент данных — «. dseg». В тексте программы сегмент данных прописывается раньше программного сегмента. В нем инициализируется оперативная память, однако, как как в нашей программе не используется оперативная память, то мы его прописывать не будем.

Далее опишем так называемые вектора прерываний. В микроконтроллере AT90S2313 существует 11 событий, по которым можно установить прерывания. В таблице 1 приведена информация о прерываниях из даташита (англ. Data Sheet) к данному контроллеру.

Таблица 1 — Таблица прерываний микроконтроллера

В переводе на русский язык:

1. Reset — прерывание по сбросу (подача 0 на вывод микросхемы «Reset»; или включение питания; или по переполнению сторожевого таймера);

2. INT0 — первое внешнее прерывание (сигнал на вывод микросхемы «INT0»);

3. INT1 — второе внешнее прерывание (сигнал на «INT1»);

4. Timer1_capt1 — прерывание защелки 1-го таймера;

5. Timer1_comp1 — прерывание компаратора 1-го таймера;

6. Timer1_OVF1 — по переполнению 1-го таймера;

7. Timer0_OVF0 — по переполнению 0-го таймера;

8. UART_RX — по окончанию приема пакета по протоколу UART;

9. UART_UDRE — по опустошению регистра данных UART;

10. UART_TX — по окончанию передачи пакета по UART;

11. ANA_COMP — прерывание аналогового компаратора.

Прерывание — это остановка извне выполнения текущей программы на время выполнения некоторой подпрограммы, которая называется «обработчик прерывания». Вектор прерывания — отсылка по нужному адресу с помощью команды «rjmp» (Relative Jump — относительный переход). Данная команда содержит относительный адрес метки, то есть число, на которое нужно увеличить/уменьшить текущий адрес ПЗУ, чтобы оказаться на метке.

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

Вектора прерываний указываются в начале адресного пространства в порядке, указанном в таблице 1. а на месте. Так как в нашей программе используется только два прерывания: прерывание по сбросу и прерывание компаратора 1-го таймера, то достачно было бы описать вектора первых пяти прерываний. Но на случай предотвращения непредвиденных сбоев, опишем все вектора, как того ожидает компилятор, прописывая на месте неиспользуемых команду выхода из обработчика прерывания — «reti» (Interrupt Return — возврат из прерывания):

rjmp Reset

reti

reti

reti

rjmp Timer1_comp1

reti

reti

reti

reti

reti

reti

Текст основной программы начинаем с метки «Reset». Вообще реинициализация микроконтроллера (сброс) может произойти по различным причинам: подача напряжения питания, выход из «спящего» режима, уменьшение напряжения питания ниже минимально допустимого уровня (Brown Out Reset), срабатывание сторожевого таймера, появление на выводе «Reset» логического сигнала низкого уровня.

Для начала определим стек в адресном пространстве ОЗУ. Стек — это область памяти в ОЗУ, хранящей адреса, по которым было приостановлено вполнение основной программы для выполнения подпрограммы. Адрес, по которому была произведена последняя запись в стек, хранится в специальном регистре — указателе стека SP (Stek Pointer). При переходе в подпрограмму его значение уменьшается на единицу, а при возвращении из неё, наоборот, увеличивается. Таким образом, видно, что стек устроен по типу FILO (Firt In Last Out — первый вошёл, последний вышел). Обычно, вначале программы указатель стека ставится на последний адрес ОЗУ.

Так как в контроллере 2313 разрядность адреса ОЗУ не превышает 8 бит, то и указатель стека должен быть 8-битным. Для его хранения, соответственно используется один 8-битный регистр «SPL» (Stack Pointer Low), в который запишем значение константы «RamEnd». Эта константа, инициализируется в файле def. inc и равна значению последнего адреса ОЗУ.

В ассемблере нельзя напрямую записать константу в регистр, не являющийся РОН (регистром общего назначения). Для этого нужно сначала при помощи оператора «ldi» присвоить значение константы РОН, а затем, ииспользуя оператор «out» — вывести значение из РОНа в нужный регистр.

Итак, инициализируем стэк

ldi var, RamEnd

out SPL, var

Теперь займёмся настройкой портов. Каждый канал порта ввода-вывода (ПВВ) может быть настроен на вход или на выход.

Программно, порты устроены следующим образом. Для работы с любым портом используется три регистра:

v PortX;

v PinX;

v DDRX.

Где X — буква порта, например PortB, PinD и т. д.

Устройство ПВВ изображено на рисунке 4.

Рисунок 4 — Устройство портов ввода-вывода

микроконтроллер порт программа сигнал

PortX содержит информацию, предназначенную для вывода.

PinX содержит вводимую информацию

DDRX содержит информацию о том, какой канал настроен на ввод, какой — на вывод.

То есть, DDRX определяет, какая ножка микросхемы будет подключена к PinX, какая — к PortX: 0 — ввод; 1 — вывод.

В схеме проекта устройства ввода/вывода подключены к следующим выводам микроконтроллера:

v выводы сегментов семисегментных индикаторов — к PB0 — PB6;

v кнопки — к PD0, PD1;

v светодиоды — к PD2, PD3

v общие выводы семисегментных индикаторов — к PD4, PD5

Программно реализуем это следующим образом:

ldi var, 0b11111111

out DDRB, var

ldi var, 0b11111100

out DDRD, var

Теперь необходимо настроить таймер, используемый для реализации динамической индикации.

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

Общий вид и схема семисегментного индикатора приведены на рисунке 5.

Рисунок 5 — Общий вид и схема семисегментного индикатора

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

Тактовая частота контроллера составляет:

.

Тогда период контроллера составляет:

Максимальное значение таймера составляет, т. о., используемый контроллер досчитает до 65 535 за

Согласно заданию, частота динамической индикации должна составлять, то есть период составляет.

Наша задача — подобрать такую тактовую частоту таймера, чтобы он считал до 65 535 немного меньше, чем за 33 мс.

Чтобы увеличить период, за который досчитает до конца таймер, нужно воспользоваться предделителем частоты. Он может сформировать четыре кратные частоты:, ,, .

Уменьшая частоту в 8 раз, период увеличится в 8 раз и составит:

.

Следовательно, нам подойдёт этот предделитель. Теперь рассчитаем количество тактовых импульсов, которое пройдёт через после начала отсчёта при таком периоде:

В шестнадцатеричной системе имеем: 0x2FBA.

В микроконтроллере AT90S2313 имеется два таймера. Они называются: «Timer-Counter 0» и «Timer-Counter 1», причём у последнего имеется прерывание компаратора (от англ. to compare — сравнивать). Оно-то нам и нужно. Для его активизации запишем в 6-й бит регисра «TIMSK» логическую единицу:

ldi var, 0b01000000

out TIMSK, var

Теперь, для установки предделителя частоты в требуемое положение (CK/8), запишем во 2-й, 1-й и 0-й биты регистра «TIMSK» 0, 1 и 0 соответственно:

ldi var, 0b00000010

out TCCR1B, var

Далее необходимо рассчитанное шестнадцатеричное число, с которым компаратор будет сравнивать состояние таймера, записать в регистр «OCR1A». Однако следует помнить, что данный регистр является составным, то есть состоит из двух 8-битных регистров. Поэтому старший и младший байты числа 0x2FBA числа запишем в регистры «OCR1AH» и «OCR1AL» соответственно:

ldi var, 0x2F

out OCR1AH, var

ldi var, 0xBA

out OCR1AL, var

Тепреь обнулим таймер:

ldi var, 0

out TCNT1H, var

out TCNT1L, var

На этом инициализация таймера окончена.

Сейчас определим переменные, необходимые в процессе работы программы. Обнулим переменную «pressedBtn», в которую записывается, какая кнопка нажата в настоящий момент.

ldi pressedBtn, 0

В переменной «ind» записываем в четвёртый бит логическую единицу. Это делается для того, чтобы в первый момент вывод осуществлялся на второй индикатор.

ldi ind, 0b00010000

Теперь обнуленим переменную «i», значение которой выводится на 7-сегментные индикаторы

ldi i, 0

Ни одно прерывание не начнет работать, пока в тексте программы не встретится команда глобального разрешения прерываний «sei» (global interrupt enable), так что далее укажем её:

sei

Для глобального запрета прерываний используется команда «cli» (global interrupt disable).

Вся функциональная часть программы содержится в обработчиках прерываний, и чтобы работа микроконтроллера продолжилась в промежутках между прерываниями компаратора, напишем пустой цикл:

Stop:

rjmp Stop

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

v cp (ComPare register with register) — сравнить регистр с регистром. В случае равенства результат операции считается нулевым;

v cpi (ComPare register with Immediate) — сравнить регистр с константой;

v mov — оператор копирования;

v andi — произвести операцию «И» между регистром и константой;

v or — произвести операцию «ИЛИ» между двумя регистрами;

v brne (Branch if Not Equal) — переход к метке, если результат предыдущего действия — не ноль;

v breq (Branch if Equal) — переход, если результат предыдущего действие — ноль;

v inc (Increment) — увеличение значения РОН на 1 (инкремент);

v dec (Decrement) — уменьшение значения РОН на 1 (декремент);

v rcall (Relative Call) — вызов подпрограммы;

v ret — выход из подпрограммы. При этом продолжится выполнение программы, вызвавшей данную подпрограмму, с места вызова. Т. е., с команды, следующей за командой rcall;

v lsr (Logical Shift Right) — логический сдвиг вправо;

v in — считывание информации из регистра PinX в РОН используется команда «in», при этом первым указывается РОН.

Стоит отметитить, что если операция производится над двумя регистрами, то ответ всегда помещается в тот регистр, который назван первым, а если учавствуют регистр и константа, то константа указывается на втором месте.

Остаётся только преобразовать двоичное число в код семисегментного индикатора. Для этого применим массив, в котором будут хранится код, выводимые на индикатор, соответствующие шестнадцатеричным числам от «0» до «F». Ассемблер позволяет задавать линейные массивы как в программной памяти (ПЗУ), так и в оперативной (ОЗУ). Соответственно, массив на ПЗУ можно только читать, массив на ОЗУ можно и читать и писать. Нам достаточно первого варианта.

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

MyArray:

. db 1,15,4,9,12,145,67,90

Это есть массив «MyArray» состоящий из 8 элементов. Массив размещается в ПЗУ начиная с адреса, на котором стоит метка (MyArray). То есть, адресу метки соответствует 0-й элемент массива.

Чтобы получить доступ к 1-му, 2-му, 3-му и т. д. элементу, нужно прочитать ячейку ПЗУ по адресу, который больше адреса метки соответственно на 1, 2, 3, …

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

В контроллере AT90S2313 три регистровые пары: X, Y и Z. Они принадлежат к РОН, и состоят из шести последних регистров — R26… R31:

X — R26, R27

Y — R28, R29

Z — R30, R31

Регистровые пары нужны для работы с 16-битными числами, к которым относится, в частности, адрес ПЗУ. Однако мы можем не использовать данные пары, а распоряжаться выделенными для них регистрами так же, как и обычными. При работе с регистровыми парами, младшая и старшая часть обрабатываются по отдельности. Соответственно они называются L и H (от слов Low и High). Например, ZH и ZL.

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

v add — сложить два регистра

v adc (Add with Carry) — сложить два регистра с учетом переполнения предыдущей операции (если результат предыдущей операции > 255).

v lpm (Load Program Memory) — загрузить данные из программной памяти (ПЗУ) по адресу из регистровой пары Z в регистр R0.

В процедуре декодировки следует обратить внимание на следующие моменты. Во-первых, командой

ldi ZH, High (DcMatrix*2)

мы загружаем в старшую часть пары Z (ZH), старшую часть адреса по метке DcMatrix. Разясним, что значит «*2».

Дело в том, что каждая команда содержит два байта информации и занимает, таким образом, две ячейки ПЗУ. Поэтому, счетчик команд считает 2 адреса как один. Метка содержит именно данные для счетчика команд. Чтобы получить реальный адрес ПЗУ, необходимо увеличить адрес метки в 2 раза. Что мы и делаем.

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

Все необходимое для написания программы отмечено. С полным текстом программы можно ознакомится в приложении 1.

2.3 Симуляция проекта в программе Proteus 7

Для проверки работоспособности разработанной схемы и программы произведём симуляции проекта на компьютере в программе «Proteus 7 Professional» фирмы «Labcenter Electronics».

Собранная схема изображена на рисунке 6.

Рисунок 6 — Собранная схема в программе «Proteus 7 Professional»

В схеме, реализованной на «Proteus 7 Professional» имеются некоторые особенности. Во-первых, вместо двух 7-сегментных индикаторов в схеме установлен один спаренный. Во-вторых, установлено минимальное количесво элементов (отсутствуют резисторы и конденсаторы), только необходимое для функционирования, т. к. программа полноценно симулирует работу и так. Тактовая частота процессора устанавливается в его свойствах, а выводымикроконтроллера, к которым подключается питаения и общий провод отсутствуют (считается, что они уже подключены).

Сейчас нам нужно откомпилировать программу, которую мы будем загружать в процессор. Для этого перейдём в папку с проектом и запустим файл «Processor. bat» (описанная в прошлом раделе программа должна быть сохранена в файле «Processor. asm»). Компиляция прошла без ошибок (рисунок 7).

Рисунок 7 — Диалоговое окно компилятора по окончанию компиляции

Теперь нужно настроить микроконтроллер. Переходим обратно в программу «Proteus 7 Professional», открываем свойства контроллера, для чего нужно два раза кликнуть на нём левой кнопкой мыши. В открывшемся окне указываем имя HEX файла скомпилированной прошивки для процессора в поле Program File. Частоту кварцевого резонатора (тактовую частоту процессора), указанную в поле Clock Frequency оставляем без изменений: 3 МГц. Настройка окончена, переходим к симуляции схемы.

Для запуска процесса симуляции нажимаем сочетание клавиш «Ctrl + F12» (рисунок 8).

Рисунок 8 — Симоляция собранной схемы в программе «Proteus 7 Professional» (1)

Теперь нужно убедиться, что всё работает так, как задумано. Зажмём верхнюю кнопку (рисунок 9).

Рисунок 9 — Симоляция собранной схемы (2)

Далее дважды нажмём нижнюю кнопкку (рисунок 10).

Рисунок 10 — Симоляция собранной схемы (3)

Сейчас выставим произвольное число на индикаторе (рисунок 11).

Рисунок 11 — Симуляция собранной схемы (4)

Итак, из рисунков 6 — 9 видно, что программа написана так, как и задумывалось в соответствии с заданием. Выполнение контрольного задания окончено.

Заключение

В процессе выполнения данной контрольной работы:

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

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

ь усвоены базовые принципы языка низкого уровня ассемблер (структура программы, работа с памятью и регистрами, условные и безусловные переходы, работа с матрицами).

Литература

1. Ефстифеев А. В. Микроконтроллеры AVR семейства Classic фирмы «Atmel». М.: Издатель-ский дом «Додека — XXI», 2002. — 288 с.: ил. ;

2. Таран В. Н., Трофименко В. Н. Трофименко Е.Н. Техника микропроцессорных систем в электросвязи: Исследования микроконтроллеров. Методические указания к лабораторным работам. Ростов-на-Дону.: Ргупс. 2008. 81 с. ;

3. Рерич Ю. В. Практическое программирование микроконтроллеров AVR на языке ассемблера. — 2-е изд., испр. — Спб. :БХВ-Петербург, 2011. — 352 с.: ил. — (электроника)

Интернет ресурсы:

4. Раздел обучения сайта www. radiokot. ru.

Приложение 1. Текс программы на ассемблере

; ***************************************;

; Подключение внешних файлов;

; ***************************************;

. include «2313def. inc»

; ***************************************;

; Определение переменных;

; ***************************************;

. def var=r16; Назначение регистрам символьного имени

. def pressedBtn=r17

. def var1=r18

. def var2=r19

. def ind=r20

. def num=r21

. def i=r24

. def var3=r25

. def ledOn=r26

; ***************************************;

; Тело программы;

; ***************************************;

. cseg; Начало программного сегмента

. org 0; Установка адреса ПЗУ для первой команды

rjmp Reset

reti; rjmp INT0

reti; rjmp INT1

reti; rjmp Timer1_capt1

rjmp Timer1_comp1

reti; rjmp Timer1_OVF1

reti; rjmp Timer0_OVF0

reti; rjmp UART_RX

reti; rjmp UART_UDRE

reti; rjmp UART_TX

reti; rjmp ANA_COMP

Reset:

ldi var, RamEnd; Оператор присвоения константы РОН

out SPL, var; Инициализация стека

ldi var, 0b11111111

out DDRB, var; Настройка порта B на вывод

ldi var, 0b11111100

out DDRD, var; Настройка порта D на вывод

ldi var, 0b01000000

out TIMSK, var; Разрешение прерываний компаратора

ldi var, 0b00000010; Тактовый сигнал = CK/8

out TCCR1B, var

ldi var, 0x2 °F; Инициализация компаратора

out OCR1AH, var

ldi var, 0xBA

out OCR1AL, var

ldi var, 0; Обнуление таймера

out TCNT1H, var

out TCNT1L, var

ldi pressedBtn, 0; Обнуление регистра состояния кнопок

ldi ind, 0b00010000

ldi i, 0; Обнуление числа, выводимого на индикаторы

sei; Глобальное разрешение прерываний

; ***************************************;

; Бесконечный цикл;

; ***************************************;

Stop:

rjmp Stop

; ***************************************;

; Прерывание таймера;

; ***************************************;

Timer1_comp1:

ldi var, 0; Обнуление таймера

out TCNT1H, var

out TCNT1L, var

rcall ListenBtn; Обработка событий кнопок

in var, PIND; Смена активного табло

andi var, 0b00001100

cpi ind, 0b00010000

breq Tablo2

rjmp Tablo1

OutNumber:; Вывод числа на активное табло

or var, ind

out PORTD, var

rcall Decoder

out PORTB, num

reti

; ***************************************;

; Подпрограммы и функции;

; ***************************************;

ListenBtn:; Проверка, изменилось ли состояние кнопок

in var, PIND

andi var, 0b00000011

cp pressedBtn, var

brne EventBtn

ret

EventBtn:; Обработка события изменения состояния кнопок

mov pressedBtn, var

cpi pressedBtn, 0b00000001

breq PressBtn1

cpi pressedBtn, 0b00000010

breq PressBtn2

ldi ledOn, 0; Выключение светодиодов в случае отпускакия кнопки

OutLed:; Включение/выключение светодиодов

in var, PIND

andi var, 0b00110000

or ledOn, var

out PORTD, ledOn

ret

PressBtn1:; При нажатии кнопки, подключённой к каналу PD0

ldi ledOn, 0b00000100

inc i; Увеличение числа, выводимого на индикаторы

rjmp OutLed

PressBtn2:; При нажатии кнопки, подключённой к каналу PD1

ldi ledOn, 0b00001000

dec i; Уменьшение числа, выводимого на индикаторы

rjmp OutLed

Tablo1:; Подготовка числа для вывода на левый индикатор

ldi ind, 0b00010000; (разряд десятков)

mov num, i

andi num, 0b11110000

lsr num

lsr num

lsr num

lsr num

rjmp OutNumber

Tablo2:; Подготовка числа для вывода на правый индикатор

ldi ind, 0b00100000; (разряд единиц)

mov num, i

andi num, 0b00001111

rjmp OutNumber

Decoder:; Декодирование числа для вывода на индкаторы

ldi ZL, Low (DcMatrix*2); Загрузка начального адреса массива

ldi ZH, High (DcMatrix*2)

ldi var, 0

add ZL, num

adc ZH, var

lpm

mov num, r0

ret

DcMatrix:; Матрица кодов 7-сегментного индикатора

; hgfedcba hgfedcba

. db 0b00111111,0b00000110; 0,1

. db 0b01011011,0b01001111; 2,3

. db 0b01100110,0b01101101; 4,5

. db 0b01111101,0b00000111; 6,7

. db 0b01111111,0b01101111; 8,9

. db 0b01110111,0b01111100; A, B

. db 0b00111001,0b01011110; C, D

. db 0b01111001,0b01110001; E, F

ПоказатьСвернуть
Заполнить форму текущей работой