Отладочная платформа Arduino Mega 2560

Отладочная платформа Arduino Mega 2560

Общие сведения

Arduino Mega 2560 предназначена для практического овладения принципами построения микроЭВМ, обучения программированию в машинных кодах, а также для отладки программного обеспечения микроконтроллерных систем различного назначения. Платформа имеет 54 цифровых входов/выходов, 16 аналоговых входов, 4 последовательных порта UART, кварцевый генератор 16 МГц, разъёмы: USB, питания, ICSP и кнопка перезагрузки. Для работы необходимо подключить Arduino к компьютеру USB-кабелем или подать внешнее питание через соответствующий разъём.

Краткие характеристики

Микроконтроллер ATmega2560
Рабочее напряжение 5 В
Внешнее напряжение питания 7..12 В
Цифровые входы/выходы
Аналоговые входы
Постоянный ток через вход/выход 40 mA
Постоянный ток для вывода 3,3 В 50 mA
Флеш-память 256 KB (из которых 8 КB используются для загрузчика)
ОЗУ 8 KB
Энергонезависимая память 4 KB
Тактовая частота 16 MHz

Программа, подготовленная к загрузке представляет собой *.hex-файл, сгенерированный в среде разработки AVRStudio из проекта на языке C или Assembler. Она загружается в Arduino через интерфейс USB непосредственно из командной строки. Простейшая программа на языке Assembler для микроконтроллера Atmega2560 выглядит следующим образом:

.include "m2560def.inc"

init:

ldi r16,0b10000000

out DDRB,r16

main:

ldi r16,0b10000000

out PORTB, r16

rjmp main

.include – это директива, которая подключает файл к проекту. Программа из подключенного файла будет выполняться так, как если бы код был написан в текущем файле. В файле *.inc содержатся макроопределения, а также наборы директив *.def (definition), которые присваивают кратким именам адреса периферийных регистров микроконтроллера.

После компиляции команды преобразуются в коды, выполняемые вычислительным ядром контроллера, а также присваиваются адреса расположения команд в памяти программ. Для того, чтобы посмотреть шестнадцатеричный код, который генерируется компилятором, необходимо в процессе пошаговой отладки программы воспользоваться комбинацией горячих клавиш (Alt+8) либо во вкладке Windows нажать пункт Disassembly. В результате проделанных манипуляций над кодом, приведенным выше, откроется окно со следующим содержимым:

@00000000: init

5: ldi r16,0b10000000

+00000000: E800 ldi R16,0x80

6: out DDRB,r16

+00000001: B904 out 0x04,R16

@00000002: main

8: ldi r16,0b10000000

+00000002: E800 ldi R16,0x80

9: out PORTB, r16

+00000003: B905 out 0x05,R16

10: rjmp main

+00000004: CFFD rjmp PC-0x0002

В каждой ячейке памяти программ хранится по два байта, а сам *.hex-файл данного кода, записываемый в микроконтроллер, занимает 63 байта. Как можно посчитать, каждая из вышеприведённых AVR-команд занимает 2 байта, в оставшиеся 53 байта помещаются макроопределения из заголовочного include файла.

Работа со средой разработки AVRStudio

Для написания программ, их отладки и трансляции используется среда “AVRStudio”. Она работает с проектами, аналогично тому, как это реализовано в Microsoft Visual Studio. Проект содержит файлы программы и ориентирован на применяемый микроконтроллер. Файл проекта *.aps содержит сведения о типе процессора, частоте тактового генератора и т.д. Он также содержит описание всех остальных файлов входящих в проект. Текст программы имеет расширение asm. Проект может содержать несколько файлов такого типа, в данном случае один из них будет главным, а другие должны подключаться в главном посредством директивы .include.

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

Интерфейс AVRStudio

На рисунке представлен внешний вид AVRStudio.

Отладочная платформа Arduino Mega 2560 - student2.ru

Рис. AVRStudio.

В левой части имеется древовидный навигатор файлов проекта. Правее него находится окно для редактирования файлов проекта. Ниже находится вспомогательное окно “Build”, в котором отображаются результаты трансляции, сообщения об ошибках и различные предупреждения (Warnings). В правом окне “I/OView” показаны ресурсы МК:

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

· Порты ввода-вывода;

· Таймеры;

· Компараторы;

· АЦП и т.д.

Создание нового проекта

В меню Project→NewProject. В поле ProjectType необходимо выбирать тип будущего проекта Atmel AVR Assembler. В Projectname вводим имя проекта латинскими символами. Под полем находятся два checkbox'а. Create initialize file определяет, нужно ли автоматически создавать главный программный файл. Если такой файл уже есть, то снять галочку, а в созданном проекте просто подключить готовый программный файл. Create folder определяет, нужно ли автоматически создавать отдельный каталог для данного проекта.

Ниже присутствует поле, содержащее имя файла. Без необходимости его лучше оставлять со значением по умолчанию. Последним элементом данного окна является Location, позволяющее указать путь к месту на жёстком диске, где будут храниться файлы проекта.

Отладочная платформа Arduino Mega 2560 - student2.ru

По кнопке Next, откроется следующее окно: Select debug device and platform (Выбор отладочной платы и микроконтроллера). В списке отладочных платформ необходимо выбрать AVRSimulator, а в списке устройств – ATmega2560. Теперь по нажатию Finish будет создан проект в указанном каталоге.

Отладочная платформа Arduino Mega 2560 - student2.ru

Лабораторные работы

Задание на лабораторную работу

Задача 1.1. Написать программу сложения (вычитания) двух 8-разрядных двоичных чисел, одно из которых содержится в регистре R, а второе – в ячейке памяти данных с адресом 02**16. Результат поместить в память данных по адресу 0x03**. Программы проверить на примерах: 1) 88 ± **; 2) 00 ± **; 3) FF ± **.

Задача 1.2. Написать программу сложения (вычитания) двух 16-разрядных двоичных чисел, одно из которых содержится в регистрах R1, R2, а второе – в ячейках памяти данных с адресами 02**16, 02**16 + 1. Результат поместить в ячейки памяти данных с адресами 03**16, 03**16 + 1. Программы проверить на примерах: 1) 8888 ± **АВ; 2) 0000 ± АВ**; 3) FFFF ± А**В.

Задача 1.3. Написать программу умножения 16-разрядного операнда на 8-разрядный операнд. Адрес операнда – ячейки памяти данных, начиная с адреса 02**16, адрес результата – ячейки памяти данных с адресами, начиная с адреса 03**16. Программы проверить на примерах: 1) 8888 ∙ **; 2) 0000 ∙ **; 3) FFFF ∙ **; 4) А**В ∙ **.

Задача 1.4. Написать программу деления операнда на постоянный коэффициент К. Адрес операнда – память данных 02**16, значение коэффициента К= ** + 5. При делении сохранить остаток.

Задача 1.5. Написать программу сложения (вычитания) двухразрядных двоично-десятичных чисел, одно из которых содержится в регистре R, а второе – в ячейке памяти данных с адресом 02**16. Программы проверить на примерах: 1) 4910 ± **10; 2) 0010 ± **10; 3) 9910 ± **10.

Примечание: Имена регистров R, R1, R2 и число ** назначаются преподавателем.
Указание: Операцию деления свести к последовательности сложений и вычитаний. Исследовать возможности сокращения длины и времени выполнения программы. Программы проверить на тестовых примерах.

Примеры решения задач

Задача 1.1. Составим программы сложения (вычитания) двух 8-разрядных двоичных чисел, одно из которых содержится в регистре R16, а второе – в ячейке памяти данных с адресом 020016. Для операции сложения программа состоит из следующих команд:

.include "m2560def.inc"

ldi r16, 0x25 ; в r16 помещается первый операнд

lds r18, 0x0200 ; в r18 помещается второй операнд

add r18, r16 ; сложение r18=r18+r16

sts 0x0300, r18 ; сохранение результата

end: rjmp end ; остановка программы

Для операции вычитания программа имеет вид:

.include "m2560def.inc"

ldi r16, 0x25 ; в r16 помещается заданный операнд

lds r18, 0x0200 ; в r18 помещается второй операнд

sub r18, r16 ; вычитание r18=r18-r16

sts 0x0300, r18 ; сохранение результата

end: rjmp end ; остановка программы

Результаты выполнения тестовых примеров представим в виде таблицы:

1-й операнд 2-й операнд Сложение Вычитание
Сумма C N V S Z Разность C N V S Z
AD
DB
FF DA

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

Задача 1.2. Составим программы сложения (вычитания) 16-разрядных двоичных чисел, одно из которых содержится в регистрах R20, R21, а второе – в ячейках памяти данных с адресами 020016, 020116. Операция сложения таких чисел выполняется в два этапа – сначала складываются младшие байты, а затем старшие (с учётом переноса). Соответствующая программа имеет вид:

.include "m2560def.inc"

ldi r21, 0x88

ldi r20, 0x88

lds r19, 0x0200

lds r18, 0x0201

add r19, r21 ; сложение r19=r19+r21

adc r18, r20 ; сложение с переносом r18=r18+r20+FlagC

end: rjmp end ; остановка программы

Аналогично выполняется и операция вычитания – сначала обрабатываются младшие байты, а затем – старшие (с учётом заёма):

.include "m2560def.inc"

ldi r21, 0x88

ldi r20, 0x88

lds r19, 0x0200

lds r18, 0x0201

sub r19, r21

sbc r18, r20

end: rjmp end ; остановка программы

Результаты выполнения тестовых примеров представим в виде таблицы:

1-й операнд 2-й операнд Сложение Вычитание
Сумма C N V S Z Разность C N V S Z
25AB AE33 62DD
AB25 AB25 54DB
FFFF A25B A25A 5DA4

Анализ полученных результатов показывает, что сумма и разность вычисляются правильно, однако флаги Z и N формируются лишь для старшего байта, а не для всего 16-разрядного числа.

Задача 1.3. Составим программу умножения двух восьмиразрядных двоичных чисел, хранящихся в памяти данных с адресами 020016 и 020116. 16-разрядное произведение будем формировать в регистровой паре R1-R0. Результат сохраним по адресам 020016 (младший байт) и 020116 (старший байт).

.include "m2560def.inc"

lds r19, 0x0200

lds r18, 0x0201

mul r18, r19

sts 0x0300, r0

sts 0x0301, r1

end: rjmp end ; остановка программы

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

02 ∙ 25 = 004A; 10 ∙ 25 = 0250; 25 ∙ 25 = 0559,

который подтверждает её корректность.

Задача 1.4. Написать программу деления восьмиразрядных двоичных чисел для следующего распределения регистров: R17 – делимое в начале, остаток в конце, R16 – делитель; R18 – частное.

Алгоритм деления заключается в следующем. Из делимого вычитается делитель, пока делимое не станет меньше делителя. Количество таких вычитаний и будет частным. Для этого используется команда условного ветвления brlo метка, которая анализирует состояние флага переноса C и в зависимости от этого загружает в счётчик команд PC либо адрес метки, либо адрес следующей команды.

Остаток будет в регистре, который вначале хранил делимое. Программа, реализующая описанный алгоритм, имеет вид:

.include "m2560def.inc"

main: cp r17, r16 ; сравнить r16 и r17

brlo end ; перейти, если С=1

sub r17, r16 ; r16 = r17–r16

inc r18 ; формируем частное

cp r17, r16

brsh main ; перейти, если С=0

end: rjmp end ; остановка программы

Проверка программы на примерах даёт:

10 : 02=08(00); 40 : 0F=04(04); FF : 0A=19(05).

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

.include "m2560def.inc"

init:

ldi r17,0x08

ldi r18,0x40

ldi r19,0x0F

ldi r25,0x01

m0:

mov r16, r18

rol r16

mov r18, r16

mov r16, r21

rol r16

sub r16, r19

brcc m1

add r16, r19

m1:

mov r21, r16

in r26,SREG

andi r26, 0x01

eor r26,r25

out SREG,r26

mov r16, r20

rol r16

mov r20, r16

dec r17

brne m0

end: rjmp end ; остановка программы

Задача 1.2. Составим программы сложения (вычитания) двухразрядных десятичных чисел, хранящихся в регистре R19 и ячейке памяти данных с адресом 021016. Результат поместим в ячейку памяти данных 030016.

.include "m2560def.inc"

.def temp =r18

.def six = r19

.def sixteen = r20

summa:

ldi r16, 0b00010010

mov r15, r16

ldi r17, 0b00110011

sts 0x210, r17

lds temp, 0x210

ldi r28, 0b01100110 ; r28=66

ldi six, 0b00000110 ; six=06

ldi sixteen, 0b01100000 ; sixteen=60

neg six

neg sixteen

add r15, r28

add r15, temp

brhc correcth

brcc correctc

adc r2,r3

end: rjmp end ; остановка программы

correcth: ; коррекция, если был полуперенос

adc r2, r3

add r15, six

cpse r2,r3

rjmp end

clc

rjmp correctc

correctc: ; коррекция, если был перенос

adc r2,r3

add r15, sixteen

rjmp end

Операция двоично-десятичного вычитания реализуется путём суммирования с дополнительным кодом, который находится по формуле (9910 – ПрКод) + 1:

Результат выполнения тестовых примеров представим в виде таблицы:

1-й операнд 2-й операнд Сумма Разность

Анализ полученных результатов подтверждает корректность программ двоично-десятичного сложения и вычитания.

Задание на лабораторную работу

Задача 2.1. Написать программу, которая позволяет установить, сбросить, инвертировать i и j биты заданного операнда, находящегося в регистре R. Результат представить в виде таблицы. Программы проверить для операндов: FF16, F016, 0F16, 0016.

Примечание: Номера регистров R, R1, R2 и число ** назначаются преподавателем. Номера разрядов i, j, k, l участвующих в операциях, вычисляются как остаток от деления на 8 числа **. Остаток от деления ## = i, ## + 2 = j, ##+4, ##+6 соответственно.

Задача 2.2. Написать программу, обеспечивающую проверку i-го бита заданного операнда, хранящегося в регистре R. Если он равен 0, поместить в ячейку памяти данных 0x0200, 16-ричный эквивалент своего номера варианта в подгруппе. Если “1”, то поместить шестнадцатеричный эквивалент своего номера варианта в подгруппе с инвертированными чётными битами. Программу проверить для следующих операндов: FF16, F016, 0F16, 0016.

Задача 2.3. Написать программу, обеспечивающую выполнение логической операции:

y=xi*xj+xk*NOT(xl),

где i, j, k, l – номера битов числа, содержащегося в регистре R. Результат поместить в память данных по адресу 0x02**. Программу проверить для операндов: 1F16, 2B16, 0C16, A116.

Задача 2.4. Написать программу, обеспечивающую вычисление суммы единиц в массиве чисел, расположенного в памяти программ. Результат поместить в регистры Ri, Rj. Количество элементов в массиве – 1010. Программу протестировать на случайных числах.

Задача 2.5. Написать программы умножения (деления) операнда на 4 с учётом знака числа. Адрес операнда и результата в памяти данных 0x02** и 0x03** соответственно. При делении остаток не сохранять. Программу проверить для операндов F016 и 0F16.

Примеры решения задач

Задача 2.1. Написать программу, которая позволяет установить, сбросить, инвертировать 1 и 3 биты операндов FF16, F016, 0F16, 0016.

Маски для установки, сброса и инвертирования соответственно будут: 0b00001010; 0b11110101; 0b00001010.

.include "m2560def.inc"

init: ldi r16, 0xFF; в r16 помещается заданный операнд

mov r17, r16

mov r18, r16

ldi r19, 0b00001010

main: or r16, r19 ; логическое ИЛИ операнда и маски

eor r18, r19 ; Исключающее ИЛИ операнда и маски

com r19 ; инверсия маски

and r17, r19 ; логическое И операнда и маски

Операнд Результат
Bi,j=1 Bi,j=0 Bi,j=NOT(Bi,j)
FF FF F5 F5
F0 FA F0 FA
0F 0F
0A 0A

Задача 2.2. Написать программу, обеспечивающую проверку i-го бита заданного операнда, хранящегося в регистре R16. Если он равен 0, записать в ячейку памяти данных 0x0200, 16-ричный эквивалент своего номера варианта в подгруппе. Если “1”, то записать шестнадцатеричный эквивалент своего номера варианта в подгруппе с инвертированными чётными битами. Программу проверим для операнда FF16.

.include "m2560def.inc"

init: ldi r16, 0xFF

ldi r17, 0b00001000 ; маска для 3 бита

ldi r18, 0x05 ; пусть задан 5 вариант

ldi r19, 0b00001000 ; для проверки на 1 третьего бита

main: and r16, r17

cp r16, r19

brne equal

ldi r20, 0b01010101

equal: eor r18, r20

sts 0x0200, r18

Задача 2.3. Написать программу, обеспечивающую выполнение логической операции y=x1*x2+x4*NOT(x6) битов числа, содержащегося в регистре R16. Программу проверить для операнда: BB16.

.include "m2560def.inc"

main: ; x1*x2+x4*not(x6)

breq main ; программа зацикливается при установленном флаге Z

ldi r16, 0b10111011 ;0xBB

andi r16, 0b00000110 ;проверка 1 и 2 бита

breq part2 ;переход если флаг Z=1

ldi r16, 0b10111011

andi r16, 0b00000100 ;проверка 2 бита

brne main ; переход если флаг Z=0

part2:

ldi r16, 0b10111011

andi r16, 0b00010000 ;проверка 4 бита

breq main

ldi r16, 0b10111011

ldi r17, 0b01000000

eor r16, r17 ; инверсия 6 бита

andi r16, 0b01000000 ; проверка 6 бита

rjmp main

Результат работы программы отображает флаг Z . Если при возврате в начало подпрограммы main флаг Z=1, то функция y будет равна 0. Если флаг Z сброшен – y=1.

Задача 2.4. Составим программу подсчёта числа единиц в слове, расположенном в памяти программ. Результат из регистра R0 сохраним в памяти данных 020016.

Организуем циклический алгоритм, на каждом шаге которого операнд сдвигается влево с добавлением нуля в младший бит. Затем анализируется флаг переноса C, и если он установлен в единицу, увеличиваем содержимое регистра R1. Операнд из массива чисел предварительно определим через array: .db.

Программа подсчёта числа единиц имеет вид:

.include "m2560def.inc"

.def temp_reg=r0

.def rezult=r1

.cseg

array: .db 0x0F

init: ldi zl, LOW(array)

ldi zh, HIGH(array)

clr rezult ; rezult = 0

lpm temp_reg, z+ ; взять из памяти программ число

main: lsl temp_reg ; сдвиг влево, добавляя справа 0

brcc m1 ; если C = 0 переход на m1

inc rezult ; иначе rezult = rezult + 1

m1: brne main ; конец ?

end: sts 0x0200, rezult; сохранить результат в ОЗУ

Проверка программы для операндов FF, 77, 21 приводит соответственно к результату 8, 6, 2.

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

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

Особенность арифметического сдвига состоит в том, что содержимое старшего (знакового) разряда сохраняется неизменным. Такой сдвиг можно реализовать при помощи следующих операций: циклического сдвига влево минуя флаг переноса, и двукратного циклического сдвига вправо через флаг переноса. После второго сдвига в аккумуляторе восстанавливается исходное число, а во флаге переноса помещается его знак. Третий сдвиг формирует число, соответствующее арифметическому сдвигу вправо.

Программа арифметического сдвига вправо имеет вид:

8200 07 RLC ; сдвиг влево

8201 1F RAR ; сдвиг вправо через С

8202 1F RAR ; сдвиг вправо через С.

8203 E7 RST4

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

8200 07 RLC ; флаг C=0

8201 1F RAR ; сдвиг вправо через C.

8202 E7 RST4

При проверке следующих программ следует учитывать, что арифметический сдвиг вправо осуществляет деление операнда на 2, а арифметический сдвиг влево – умножение на 2. Например, для операнда 24 сдвиг вправо даёт 12, а сдвиг влево - 48.

Написать программы, обеспечивающие умножение (деление) операнда на 4. Адреса операндов 0x0200, 0x0201; адреса результатов – 0x0300, 0x0301. Программу проверить для операндов F016 и 0F16.

.include "m2560def.inc"

/*lds r16, 0x0200

lds r17, 0x0201*/

ldi r16, 0xFF

lsl r16 ;умножение R16 на 2 с сохранением знака

adc r19, r20

lsl r19

lsl r16 ;умножение R16 на 2 с сохранением знака

adc r19, r20

/*asr r17 ;деление R17 на 2 с сохранением знака

asr r17 ;деление R17 на 2 с сохранением знака

sts 0x0300, r16

sts 0x0301, r17*/

Задание на лабораторную работу

Задача 3.1. Написать программу, обеспечивающую отображение состояния i-го и j-го битов операнда на линиях порта B i и j соответственно. Адрес операнда 02** в памяти данных. Собрать модель схемы в Proteus и подключить к выводам порта B i и j светодиоды, отображающие состояние операнда. Программу проверить для операндов FF, 0F, F0, 00.

Задача 3.2. Написать программу, обеспечивающую отображение состояния клавиши, подключенной к линии i порта B, с помощью светодиода, подключенного к линии j порта D (нажато – горит, отжато – не горит). Промоделировать работу схемы в Proteus.

Задача 3.3. Написать программу, обеспечивающую подсчёт нажатий на клавишу, подключенную к линии i порта B. Отобразить десятичный эквивалент количества нажатий на двух семисегментных индикаторах, подключенных к порту D. Сброс в 0 клавишей на линии j порта B. При достижении значения счётчика 99 значение больше не увеличивать. Промоделировать работу схемы в Proteus.

Задача 3.4. Написать программу, обеспечивающую увеличение либо уменьшение десятичного счётчика в зависимости от нажатия клавиш “+” или “-“, подключенных к линиям i и j порта D. Отобразить десятичное значение на двух семисегментных индикаторах, подключенных к порту B. При опросе клавиш задействовать механизм внешнего прерывания. Сброс в 0 клавишей на линии k порта D. При достижении значения счётчика 99 значение больше не увеличивать, а также не уменьшать менее 0. Промоделировать работу схемы в Proteus.

Задача 3.5. Написать программу, обеспечивающую работу энкодера, подключенного к выводам порта D i и j. Отобразить десятичный эквивалент поворота ручки энкодера на двух семисегментных индикаторах, подключенных к порту B. При опросе энкодера задействовать механизм внешнего прерывания. Сброс в 0 клавишей на линии k порта D. При достижении значения счётчика 99 значение больше не увеличивать, а также не уменьшать менее 0. Промоделировать работу схемы в Proteus.

Примеры решения задач

Задача 3.1. Составим программу, обеспечивающую отображение состояния нулевого бита операнда на нулевой линии порта B. Собрать модель схемы в Proteus и подключить к нулевому выводу порта B светодиод, отображающий состояние нулевого бита операнда. Программу проверить для операндов FF и 00.

Соответствующая программа имеет вид:

.include "m2560def.inc"

init: ldi r16, 0x01 ; настройка на вывод линии 0 порта B

out DDRB, r16

ldi r16, 0xFF ; операнд

ldi r17, 0x01 ; маска для проверки на 1 бита 0

main: and r16, r17 ; выделить нулевой бит

brne on ; переход по ненулю

ldi r16, 0x00 ; вывод на линию 0 порта B "0"

out PORTB, r16

rjmp end ; обход включения линии порта

on: ldi r16, 0x01 ; вывод на линию 0 порта B "1"

out PORTB, r16

end: rjmp end ; остановка программы

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Отладочная платформа Arduino Mega 2560 - student2.ru

Светодиод подключен катодом к минусовому проводу ”земли“, поэтому включается подачей логической ”1“ с порта B. Резистор необходим для согласования уровня напряжения на выходе Arduino (5 вольт) с напряжением включения светодиода (3 вольта).

Эмуляция работы устройства показывает, что при значении операнда FF светодиод включен, а при значении 00 – выключен.

Задача 3.2. Составим программу, обеспечивающую отображение состояния клавиши, подключенной к линии 0 порта B, с помощью светодиода, подключенного к линии 0 порта D (нажато – горит, отжато – не горит). Промоделировать работу схемы в Proteus.

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

При опросе кнопки необходимо учитывать, что она работает в инверсной логике, т.е. её нажатие вызывает появление логического нуля в соответствующем разряде порта B. Соответствующая программа имеет вид:

.include "m2560def.inc"

init: ldi r16, 0b00000000 ; настройка на ввод линии 0 порта B

out DDRB, r16

ldi r16, 0b00000001 ; настройка на вывод линии 0 порта D

out DDRD, r16

ldi r19, 0b00000001 ; маска для инверсии 0 бита

main: in r16, PINB

eor r16, r19 ; инвертирование 0 бита

out PORTD,r16 ; вывод на линию 0 состояния бита 0 r16

rjmp main ; организация бесконечного цикла

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Отладочная платформа Arduino Mega 2560 - student2.ru

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

Задача 3.3. Составим программу, обеспечивающую подсчёт нажатий на клавишу, подключенную к линии 0 порта B. Отобразить десятичный эквивалент количества нажатий на семисегментном светодиодном индикаторе, подключенному к четырём младшим линиям порта D. Сброс в 0 клавишей на линии 1 порта B. При достижении значения счётчика 9 значение больше не увеличивать. Промоделировать работу схемы в Proteus.

.include "m2560def.inc"

init: ldi r16, 0b00000000 ; настройка на ввод линий 0,1 порта B

out DDRB, r16

ldi r16, 0b00001111 ; настройка на вывод линий 0-3 порта D

out DDRD, r16

clr r17 ; сброс счётчика

bclr 6 ; разрешить увеличение счёта b6SREG=0

main: sbis PINB, 1 ; проверить кнопку RESET

clr r17 ; если нажата, то сброс счётчика

sbic PINB, 0 ; проверить кнопку +

rjmp off ; переход если не нажато

brbs 6, nozero ; можно увеличить счёт?

inc r17

nozero:bset 6 ; запретить увеличение счёта b6SREG=1

rjmp end ; обход разрешения

off: bclr 6 ; разрешить увеличение счёта

end: cpi r17, 0x0A ; сравнить r17 с числом A

brne indic ; перейти, если r16 /= A

dec r17

indic: out PORTD,r17 ; вывод

rjmp main ; организация бесконечного цикла

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

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Отладочная платформа Arduino Mega 2560 - student2.ru

Задача 3.4. Составим программу, увеличивающую либо уменьшающую десятичный счётчик по нажатию клавиш “+” или “-“. Подключим их к линиям 0 и 1 порта D. Отобразим десятичное значение на семисегментном индикаторе, подключенном к порту B. При опросе клавиш используем внешнее прерывание. Сброс в 0 клавишей на линии 2 порта D. Промоделируем работу схемы в Proteus.

Для работы с прерываниями необходимо описать таблицу векторов для данного типа МК через директивы ассемблера .org. Из документации на МК ATmega2560 следует, что внешние прерывания INTx имеют диапазон адресов $0002.. $0010. При этом INT0 принимается с линии порта PD0 микроконтроллера, а INT1 – c PD1 соответственно. Для желаемых INTx по заданным адресам записывается команда перехода на обработчик rjmp Ext_INT. Подпрограмма-обработчик должна быть как можно короче и обязательно заканчиваться командой reti. Основная программа начинается с метки Reset, где настраивается указатель стека и внешние прерывания разрешаются локально (регистр EIMSK), а также условие срабатывания по спаду входного сигнала в регистре EICRA (адрес в пространстве ввода/вывода 0x69).

.include "m2560def.inc"

.cseg

.org $0000 rjmp Reset ; (Reset)

.org $0002 rjmp Ext_INT0 ; (INT0) External Interrupt Request 0

.org $0004 rjmp Ext_INT1 ; (INT1) External Interrupt Request 1

.org $0006 reti ; (INT2) External Interrupt Request 2

.org $0008 reti ; (INT3) External Interrupt Request 3

.org $000A reti ; (INT4) External Interrupt Request 4

.org $000C reti ; (INT5) External Interrupt Request 5

.org $000E reti ; (INT6) External Interrupt Request 6

.org $0010 reti ; (INT7) External Interrupt Request 7

.org $0012 reti ; (PCINT0) Pin Change Interrupt Request 0

.org $0014 reti ; (PCINT1) Pin Change Interrupt Request 1

.org $0016 reti ; (PCINT2) Pin Change Interrupt Request 2

.org $0018 reti ; (WDT) Watchdog Time-out Interrupt

.org $001A reti ; (TIMER2_COMPA) Timer/Counter2 Compare Match A

.org $001C reti ; (TIMER2_COMPB) Timer/Counter2 Compare Match B

.org $001E reti ; (TIMER2_OVF) Timer/Counter2 Overflow

.org $0020 reti ; (TIMER1_CAPT) Timer/Counter1 Capture Event

.org $0022 reti ; (TIMER1_COMPA) Timer/Counter1 Compare Match A

.org $0024 reti ; (TIMER1_COMPB) Timer/Counter1 Compare Match B

.org $0026 reti ; (TIMER1_COMPC) Timer/Counter1 Compare Match C

.org $0028 reti ; (TIMER1_OVF) Timer/Counter1 Overflow

.org $002A reti ; (TIMER0_COMPA) Timer/Counter0 Compare Match A

.org $002C reti ; (TIMER0_COMPB) Timer/Counter0 Compare Match B

.org $002E reti ; (TIMER0_OVF) Timer/Counter0 Overflow

.org $0030 reti ; (SPI_STC) Serial Transfer Complete

.org $0032 reti ; (USART0_RX) USART0 Rx Complete

.org $0034 reti ; (USART0_UDRE) USART0 Data Register Empty

.org $0036 reti ; (USART0_TX) USART0 Tx Complete

.org $0038 reti ; (ANALOG_COMP) Analog Comparator

.org $003A reti ; (ADC) ADC Conversion Complete

.org $003C reti ; (EE_READY) EEPROM Ready

.org $003E reti ; (TIMER3_CAPT) Timer/Counter3 Capture Event

.org $0040 reti ; (TIMER3_COMPA) Timer/Counter3 Compare Match A

.org $0042 reti ; (TIMER3_COMPB) Timer/Counter3 Compare Match B

.org $0044 reti ; (TIMER3_COMPC) Timer/Counter3 Compare Match C

.org $0046 reti ; (TIMER3_OVF) Timer/Counter3 Overflow

.org $0048 reti ; (USART1_RX) USART1 Rx Complete

.org $004A reti ; (USART1_UDRE) USART1 Data Register Empty

.org $004C reti ; (USART1_TX) USART1 Tx Complete

.org $004E reti ; (TWI) 2-wire Serial Interface

.org $0050 reti ; (SPM_RDY) Store Program Memory Ready

.org $0052 reti ; (TIMER4_CAPT) Timer/Counter4 Capture Event

.org $0054 reti ; (TIMER4_COMPA) Timer/Counter4 Compare Match A

.org $0056 reti ; (TIMER4_COMPB) Timer/Counter4 Compare Match B

.org $0058 reti ; (TIMER4_COMPC) Timer/Counter4 Compare Match C

.org $005A reti ; (TIMER4_OVF) Timer/Counter4 Overflow

.org $005C reti ; (TIMER5_CAPT) Timer/Counter5 Capture Event

.org $005E reti ; (TIMER5_COMPA) Timer/Counter5 Compare Match A

.org $0060 reti ; (TIMER5_COMPB) Timer/Counter5 Compare Match B

.org $0062 reti ; (TIMER5_COMPC) Timer/Counter5 Compare Match C

.org $0064 reti ; (TIMER5_OVF) Timer/Counter5 Overflow

.org $0066 reti ; (USART2_RX) USART2 Rx Complete

.org $0068 reti ; (USART2_UDRE) USART2 Data Register Empty

.org $006A reti ; (USART2_TX) USART2 Tx Complete

.org $006C reti ; (USART3_RX) USART3 Rx Complete

.org $006E reti ; (USART3_UDRE) USART3 Data Register Empty

.org $0070 reti ; (USART3_TX) USART3 Tx Complete

.org INT_VECTORS_SIZE ; Конец таблицы прерываний

Ext_INT0: ; обработчик прерывания по входу INT0

inc r17 ; счётчик++

cpi r17, 0x0A ; сравнить r17 с числом A

brne ret0 ; перейти, если r17 /= A

dec r17

ret0: reti ; выход из обработчика прерывания

Ext_INT1: ; обработчик прерывания по входу INT1

dec r17 ; счётчик--

cpi r17, 0xFF ; сравнить r17 с числом FF

brne ret1 ; перейти, если r17 /= FF

inc r17 ; счётчик++

ret1: reti ; выход из обработчика прерывания

Reset: ldi r16,Low(RAMEND) ; Старт программы

out SPL,r16 ; Обязательная инициализация стека

ldi r16,High(RAMEND); Указатель стека устанавливается на конец ОЗУ

out SPH,r16

ldi r16,0b00000011 ; Разрешаем прерывания INT0 и INT1 локально

out EIMSK,r16

ldi r16,0b00001010 ; Настройка условия генерации прерывания

sts EICRA,r16 ; по спаду входного сигнала

sei ; Разрешаем прерывания глобально

ldi r16,0b00000000 ; настройка на ввод линий 0,1,2 порта D

out DDRD,r16

ldi r16,0b00001111 ; настройка на вывод линий 0-3 порта B

out DDRB,r16

clr r17 ; сброс счётчика

main: sbis PIND,2 ; проверить кнопку RESET

clr r17 ; если нажата, то сброс счётчика

out PORTB,r17 ; вывод

rjmp main

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Отладочная платформа Arduino Mega 2560 - student2.ru

Задача 3.5. Составим программу, увеличивающую либо уменьшающую десятичный счётчик при воздействии на энкодер, подключенный к линиям 0 и 1 порта D. Отобразим десятичное значение на семисегментном индикаторе, подключенном к порту B. При опросе энкодер задействуем механизм внешнего прерывания. Сброс в 0 клавишей на линии 2 порта D. Промоделируем работу схемы в Proteus.

Энкодер – это датчик положения движущихся частей, который имеет две контактные пары, формирующие при вращении его ротора две импульсные последовательности, сдвинутые на 90°. По этому сдвигу можно судить о направлении вращения энкодера.

Отладочная платформа Arduino Mega 2560 - student2.ru

На диаграмме показана зависимость выходов А и В друг от друга при вращении энкодера по часовой или против часовой стрелки.

Всякий раз, когда по прерыванию INT0 сигнал А переходит от нуля к положительному уровню, необходимо считывать значение выхода В. Если B в этот момент находится в положительном состоянии, значит энкодер вращается по часовой стрелке, иначе – против часовой стрелки. В зависимости от полученного результата увеличивается или уменьшается значение счётчика.

.include "m2560def.inc"

.cseg

.org $0000 rjmp Reset ; (Reset)

.org $0002 rjmp Ext_INT0 ; (INT0) External Interrupt Request 0

.org INT_VECTORS_SIZE ; Конец таблицы прерываний

Ext_INT0: ; обработчик прерывания по входу INT0

inc r17 ; счётчик++

cpi r17, 0x0A ; сравнить r17 с числом A

brne ret0 ; перейти, если r17 /= A

dec r17

ret0: reti ; выход из обработчика прерывания

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

1. Создаем устройства на микроконтроллерах, А.В. Белов 2007 г

Заочное

Введение

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

Целью курса является получение навыков аппаратно-программной реализации типовых алгоритмов контроля и управления, а также знакомство с современным состоянием микропроцессорной техники.

В результате изучения дисциплины студенты должны:

· знать характеристики наиболее распространённых микроконтроллеров;

· уметь выбрать рациональную архитектуру системы управления;

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

В соответствии со спецификой специальности "Информационные технологии и управление в технических системах" основное вним

Наши рекомендации