Выбор имитации цифрового устройства обусловлен тем, что микроконтроллер в основном предназначен для применения в устройствах управления. А для синтеза устройств управления используются принципы синтеза цифровых устройств, да и сами устройства управления чаще всего являются именно цифровыми устройствами. Кроме того, реализация цифровых устройств на аппаратном уровне рассматривалась в предыдущих курсах и студенты хорошо знакомы с принципами их построения и работы.
Работу любого цифрового устройства можно описать с помощью таблицы истинности, аналитического выражения или словесного описания. Алгоритм реализации функционирования во всех трех случаях будет различным. Основное время в программировании практических задач занимает разработка алгоритма. Это в большой мере творческий процесс. Написание программы по готовому алгоритму, сводится к чисто технической задаче, где используются наработанные приемы и готовые библиотечные программы.
В первом приближении алгоритм можно составлять, не привязывая его к конкретному языку программирования. Но реализация отдельных блоков алгоритма уже требует использования конкретного языка программирования. Наиболее рациональная программа получается, когда уже на начальной стадии разработки алгоритма учитывается язык программирования.
Программы для микроконтроллера AVR предполагается писать на ассемблере. Хотя можно писать и на языке высокого уровня, например на С++. Известно, что на языках высокого уровня программировать проще, чем на ассемблере, хотя сам язык высокого уровня сложнее и изучать его дольше. Программирование микроконтроллера на ассемблере выбрано из тех соображений, что он проще языка высокого уровня, время на его изучение требуется меньше. Это позволяет уже через короткое время написать несложную программу и проверить ее работу. При программировании на ассемблере необходимо хорошо знать структуру микроконтроллера, что тоже является задачей дисциплины. Кроме того, программирование на языке С++ изучается в другом курсе, и после окончания института выпускник сам решит на каком языке при необходимости осуществлять программирование микроконтроллера.
Все микроконтроллеры серии AVR программно совместимы. Программа для микроконтроллеров серии AVR состоит из последовательно написанных строк.
Строка программы может быть в одной из четырёх форм:
[ Метка:] директива [операнды] ;[Текст комментария]
[ Метка:] команда [операнды] ;[Текст комментария]
;[Текст комментария]
Пустая строка
В квадратных скобках представлены необязательные компоненты строки, и они могут отсутствовать. Строка не должна быть длиннее 120 символов.
Метка является алфавитно-цифровой последовательностью символов (словом), заканчивающейся двоеточием. Она используются, как указание для команды безусловного перехода и команд условного перехода. Применение меток облегчает программирование, поскольку метка не привязана к определенному адресу, а физический адрес перехода определяется в процессе трансляции программы. В качестве метки нельзя использовать имена команд или директив.
Компилятор не требует, чтобы метки, директивы, команды или комментарии находились в определённой колонке строки
Операнд - это целое число, над которым производится действие. Операнды можно задавать в различных форматах:
десятичный (по умолчанию), например, 12;
шестнадцатеричный, например, $0а (или 0´0а);
двоичный, например, 0b00001010, 0b11111111;
Форма представления значения не имеет и определяется соображениями рациональности и пристрастиями программиста.
Команда определяет действие над операндами. Операндов в команде обычно два или один. Существуют команды и не содержащие операнды.
Директивы не транслируются непосредственно в коды операции. Они используются для облегчения программирования, чтобы корректировать местоположение программы в памяти, определять макрокоманды, инициализировать память и так далее. То есть это указания самому ассемблеру.
Комментарий пишется после символа “ ; ”. Любой текст после символа “ ; ” игнорируется ассемблером и имеет значение только для пользователя.
Пустая строка никак не воспринимается компилятором, но учитывается при общей нумерации строк в процессе компиляции.
Команды, директивы, операнды и метки можно писать и строчными, и прописными буквами.
Система команд микроконтроллеров ATMEL семейства AVR очень большая (порядка 130 команд) и в то же время эффективная. Правда, некоторые команды дублируют друг друга. Одной из отличительных особенностей микроконтроллеров AVR по сравнению с другими является то, что почти все команды выполняются за 1 тактовый цикл. Исключение составляют команды перехода. Это существенно увеличивает производительность микроконтроллера даже при относительно невысокой тактовой частоте.
Команды можно классифицировать следующим образом:
1. арифметические команды;
2. логические команды;
3. команды операций с битами;
4. команды пересылки данных;
5. команды перехода;
6. прочие команды.
При выполнении данных лабораторных работ для упрощения запоминания команд и написания программ не предполагается использовать весь набор директив и команд, тем более что многие команды дублируют друг друга. Полный набор команд и директив приведен в приложении. Предлагаемый набор команд представлен в таблицах 6.1…6.6.
Таблица 6.1. Арифметические команды
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
ADD |
Rd,Rr 0≤ d ≤31 0≤ r ≤31 |
Сложить без переноса |
Rd <- Rd + Rr |
Z, C, N, V, H |
1 |
ADIW |
Rd,K d{24,26,28,30} 0≤K≤63 |
Сложить непосредственное значение со словом |
Rdh:Rdl <- <- Rdh:Rdl + К |
Z, C, N, V |
2 |
SUB |
Rd,Rr 0≤ d ≤31 0≤ r ≤31 |
Вычесть без заема |
Rd <- Rd – Rr |
Z, C, N, V, H |
1 |
INC |
Rd 0≤ d ≤31 |
Инкрементировать (увеличить на 1) |
Rd <- Rd + 1 |
Z, N,V |
1 |
DEC |
Rd 0 ≤d ≤31 |
Декрементировать (уменьшить на 1) |
Rd <- Rd - 1 |
Z, N,V |
1 |
Таблица 6.2. Логические команды
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
AND |
Rd, Rr 0≤ d ≤31 0≤ r ≤31 |
Выполнить логическое И |
Rd <- Rd • Rr |
Z, N, V |
1 |
ANDI |
Rd, К 16≤d≤31 0≤k≤255 |
Выполнить логическое И с константой |
Rd <- Rd • К |
Z, N, V |
1 |
OR |
Rd, Rr 0≤ d ≤ 31 0≤ r ≤31 |
Выполнить логическое ИЛИ |
Rd <- Rd v Rr |
Z, N, V |
1 |
ORI |
Rd, К 16≤ d≤31 0≤K≤255 |
Выполнить логическое ИЛИ с константой |
Rd <- Rd v К |
Z, N, V |
1 |
EOR |
Rd, Rr 0≤ d ≤31 0≤ г ≤31 |
Выполнить исключающее ИЛИ |
Rd <- Rd (+) Rr |
Z, N, V |
1 |
СОМ |
Rd 0≤ d ≤31 |
Выполнить инверсию всех битов регистра |
Rd<- $FF - Rd |
Z, C, N, V |
1 |
CLR |
Rd 0≤ d ≤31 |
Очистить (обнулить) регистр |
Rd <- 0 |
Z, N, V |
1 |
SER |
Rd 16≤ d≤31 |
Установить все биты регистра в 1 |
Rd <- $FF |
нет |
1 |
CP |
Rd, Rr 0≤ d ≤31 0≤ r ≤31 |
Сравнить регистры |
Rd - Rr |
Z, C, N, V, H |
1 |
CPI |
Rd, К 16≤d≤31 0≤K≤255 |
Сравнить регистр с константой |
Rd - K |
Z, C, N, V, H |
1 |
Таблица 6.3. Команды операций с битами
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
Сдвиги |
|||||
LSL |
Rd 0≤ d ≤31 |
Логически сдвинуть влево |
Rd(n+1)<- Rd(n), Rd(0)<- 0, C <- Rd(7) |
Z,C,N,V, H |
1 |
LSR |
Rd 0≤ d ≤31 |
Логически сдвинуть вправо |
Rd(n)<- Rd(n+1), Rd(7) <- 0, C <- Rd(0) |
Z,C,N,V |
1 |
ROL |
Rd 0≤ d ≤31 |
Сдвинуть влево через перенос |
Rd(0) <- C, Rd(n+1)<- Rd(n), C <- Rd(7) |
Z,C,N,V, H |
1 |
ROR |
Rd 0≤ d ≤31 |
Сдвинуть вправо через перенос |
Rd(7) <- C, Rd(n)<- Rd(n+1), C <- Rd(0) |
Z,C,N,V |
1 |
Работа с битами в портах I/O |
|||||
SBI |
P, b 0≤ P ≤31 0≤ b ≤7 |
Установить бит в регистре I/O |
(P,b) <- 1 |
Нет |
2 |
CBI |
P, b 0≤ P ≤31 0≤ b ≤7 |
Очистить бит в регистре I/O |
(P,b) <- 0 |
Нет |
2 |
BSET |
s 0≤ s ≤7 |
Установить флаг в регистре статуса |
SREG(s) <- 1 |
SREG(s) |
1 |
BCLR |
s 0≤ s ≤7 |
Очистить флаг в регистре статуса |
SREG(s) <- 0 |
SREG(s) |
1 |
SEI |
Установить флаг глобального прерывания |
I <- 1 |
I |
1 |
|
CLI |
Очистить флаг глобального прерывания |
I <- 0 |
I |
1 |
|
Перемещение бита |
|||||
BST |
Rd, b 0≤ d ≤31 0≤ b ≤7 |
Переписать бит из регистра в флаг Т |
Т <- Rd(b) |
Т |
1 |
BLD |
Rd, b 0≤ d ≤31 0≤ b ≤7 |
Переписать флаг Т в бит регистра |
Rd(b) <- Т |
Нет |
1 |
Таблица 6.4. Команды пересылки данных
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
Прямая адресация |
|||||
MOV |
Rd, Rr 0≤ d ≤31 0≤ r ≤31 |
Переслать данные из регистра в регистр |
Rd <- Rr |
Нет |
1 |
LDI |
Rd, K 16≤ d ≤31 0≤ k ≤ 255 |
Записать константу в регистр |
Rd <- K |
Нет |
1 |
LDS |
Rd, k 0≤ d ≤31 0≤k≤65535 |
Переслать данные из ОЗУ по адресу k в регистр |
Rd <- (k) |
Нет |
3 |
STS |
k, Rr 0≤ d ≤31 0≤k≤65535 |
Переслать данные из регистра в ОЗУ по адресу k |
(k) <- Rr |
Нет |
3 |
IN |
Rd, P 0≤ d ≤31 0 ≤ P ≤63 |
Переслать данные из порта I/O в регистр |
Rd <- P |
Нет |
1 |
OUT |
P,Rr 0≤ r ≤31 0≤ P ≤63 |
Переслать данные из регистра в порт I/O |
P <- Rr |
Нет |
1 |
PUSH |
Rr 0≤ r ≤31 |
Сохранить регистр в стеке |
STACK <- Rr |
Нет |
2 |
POP |
Rd 0≤ d ≤31 |
Извлечь регистр из стека |
Rd <- STACK |
Нет |
2 |
Косвенная адресация |
|||||
LD |
Rd,X (Y,Z) 0≤ d ≤31 |
Переслать данные из ОЗУ в регистр Rd. Адрес, данных находится в регистре X (Y,Z). |
Rd <- (X) (Y,Z) |
Нет |
2 |
ST |
X (Y,Z),Rr 0≤ r ≤31 |
Переслать данные из регистра Rr в ОЗУ Адрес, данных находится в регистре X (Y,Z). |
(X) (Y,Z) <- Rr |
Нет |
2 |
Таблица 6.5. Команды переходов
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
Безусловные переходы |
|||||
RJMP |
k -2K<k<2K |
Перейти относительно на метку |
PC <- PC + k + 1 |
Нет |
2 |
RCALL |
k -2K≤k≤2K |
Вызвать подпрограмму относительно по метке |
PC <- PC + k + 1 |
Нет |
3 |
RET |
Вернуться из подпрограммы |
PC <- STACK |
Нет |
4 |
|
RETI |
Вернуться из прерывания |
PC <- STACK |
I |
4 |
|
Пропуск одной команды при выполнении условия |
|||||
CPSE |
Rd,Rr 0≤ d ≤31, 0≤ r ≤31 |
Сравнить и пропустить, если значения регистров равны |
if Rd = Rr then PC <- PC + 2 (or 3) |
Нет |
1/2/3 |
SBRC |
Rr,b 0≤ r ≤31 0≤ b ≤7 |
Пропустить, если бит b в регистре равен 0 |
if Rr(b) = 0 then PC <- PC + 2 (or 3) |
Нет |
1/2/3 |
SBRS |
Rr,b 0≤ r ≤31 0 ≤b≤ 7 |
Пропустить, если бит b в регистре равен 1 |
if Rr(b) = 1 then PC <- PC + 2 (or 3) |
Нет |
1/2/3 |
SBIC |
P,b 0≤ P ≤31 0≤ b ≤7 |
Пропустить, если бит b в регистре I/O равен 0 |
if I/O P(b) = 0 then PC <- PC + 2 (or 3) |
Нет |
1/2/3 |
SBIS |
P,b 0≤ r ≤31 0≤ b ≤7 |
Пропустить, если бит b в регистре I/O равен 1 |
if I/O P(b) = 1 then PC <- PC + 2 (or 3) |
Нет |
1/2/3 |
Переход на метку (относительный адрес) при выполнении условия |
|||||
BREQ |
k -64≤k≤+63 |
Перейти на метку, если содержимое регистров равно |
if Rd= Rr (Z=1) then PC <- PC + k + 1 |
Нет |
1/2 |
BRNE |
k -64≤k≤+63 |
Перейти на метку, если содержимое регистров не равно |
if Rd ¹ Rr(Z=0) then PC <- PC + k + 1 |
Нет |
1/2 |
BRSH |
k -64≤k≤+63 |
Перейти, если равно или больше (без знака) |
if Rd≥Rr(C = 0) then PC<- PC+ k + 1 |
Нет |
1/2 |
BRLO |
k -64≤k≤+63 |
Перейти, если меньше (без знака) |
if Rd<Rr (C=1) then PC <-PC + k + 1 |
Нет |
1/2 |
BRBS |
s , k 0≤ s ≤7 -64≤k≤+63 |
Перейти, если бит s в регистре статуса равен 1 |
if SREG(s) = 1 then PC <- PC + k + 1 |
Нет |
1/2 |
BRBC |
s, k 0≤ s ≤7 -64≤k≤+63 |
Перейти, если бит s в регистре статуса равен 0 |
if SREG(s)=0 then PC <- PC + k + 1 |
Нет |
1/2 |
Таблица 6.6. Прочие команды
Мнемоника |
Операнды |
Описание |
Операция |
Флаги |
Кол-во циклов |
NOP |
Выполнить холостую команду |
Нет |
1 |
В таблице применяются следующие обозначения:
Rr – регистр общего назначении источник данных;
Rd – регистр общего назначении приемник данных;
r,d – номера регистров общего назначения;
Р – порт ввода/вывода (I/O);
К – целое число (диапазон указан в таблице после обозначения команды);
b – номер бита (диапазон 0…7);
s - номер бита в регистре SREG (диапазон 0…7);
k – метка или относительный адрес перехода
0 … 31 – диапазон возможных численных значений;
X (Y,Z) – один из регистров косвенной адресации.
Предлагаемые для использования директивы:
CSEG - сегмент кодов (Codesegment).
Директива CSEG указывает на начало сегмента кодов (программы). Ассемблируемый файл может иметь несколько кодовых сегментов, которые будут объединены в один при ассемблировании. Директива не имеет параметров.
Синтаксис: .CSEG
ORG - установить адрес начала программы или подпрограмм прерывания.
Директива ORG устанавливает начальный адрес сегментов данных и кода (программы). По этому адресу обычно размещается команда безусловного перехода, указывающая на адрес начала программы или подпрограммы прерывания. Используется только совместно с директивами .CSEG, .DSEG, .ESEG.
Синтаксис: .ORG физический адрес
Например: .ORG $06
rjmp reset
DEF – присвоить имя регистру
Директива DEF позволяет присвоить символическое имя регистрам общего назначения и регистрам ввода/вывода (I/O). Один и тот же регистр может иметь несколько символических имен.
Синтаксис: .DEF имя = регистр
Например: .DEF temp = R16
INCLUDE – вставить другой файл
Директива INCLUDE указывает ассемблеру подключить этот файл к компилируемой программе. Ассемблер будет компилировать этот файл до конца или до директивы EXIT. Подключаемый файл может сам включать директивы INCLUDE.
Синтаксис: .INCLUDE "имя файла"
Например: .INCLUDE "8535def.inc "
Для первой программы предлагается упрощенная структура (шаблон) построения программы, в которой представлены обязательный минимальный набор команд и директив. Полный шаблон приведен в конспекте лекций.
;*******************************************
; название программы,
; краткое описание, необходимые пояснения
;*******************************************
.include “8535def.inc” ; файл описания AT90S8535.
;******сегмент кодов
.cseg
;****** вектор прерываний
.org $00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
;*******начало основной программы
nacalo:
… ; программирование портов I/O и других устройств
… ; микроконтроллера
programma:
… ; текст основной программы
…
rjmp programma: ; переход на начало текста основной программы.
; конец программы (никак не обозначается).
Если провести аналогию с языками высокого уровня, где используется понятие «переменная», то в ассемблере для микроконтроллера переменной является любой регистр общего назначения, любой регистр ввода/вывода и любая ячейка памяти ОЗУ. Содержимое их может изменяться. В общем случае при программировании для регистров общего назначения и регистров ввода/вывода используются стандартные имена, но любому из этих элементов, в том числе ячейкам ОЗУ, можно присвоить индивидуальное имя. Константа является числом и не может изменяться, хотя и ей тоже можно присвоить индивидуальное имя.
Программа микроконтроллера выполняется последовательно команда за командой. После выполнения последней команды, программа начинает выполняться с самого начала автоматически. Для того чтобы программа выполнялась с нужного места, необходимо использовать команду безусловного перехода.
Программа, в которой команды выполняются последовательно одна за другой, встречается редко. В подавляющем числе программ используется ветвление по тем или иным условиям. Ассемблер для микроконтроллеров имеет большое разнообразие переходов по условию. По условию возможен переход к какой-нибудь команде или пропуск следующей одной команды. Переход или пропуск команды осуществляется, если условие выполняется. Переход возможен, как вперед (максимум через 63 команды), так и назад (максимум через 64) команды.
Переход может быть осуществлен:
а) по результату сравнения двух регистров общего назначения или регистра общего назначения с константой. Возможные варианты сравнения: Rd = Rr (Rd = K), Rd ¹ Rr (Rd ¹ K), Rd < Rr (Rd < K), Rd ≥ Rr (Rd ≥ K);
б) по значению одного из битов (установлен или сброшен) в регистре статуса (SREG).
Пропуск команды может быть осуществлен:
а) при равенстве двух регистров общего назначения (Rd = Rr);
б) по значению одного из битов (установлен или сброшен) в регистрах общего назначения (РОН)
в) по значению одного из битов (установлен или сброшен) в 32 младших регистрах I/O.
Во многих программах возникает необходимость повторять одно и тоже действие несколько раз. Для этого в языках высокого уровня предусмотрены специальные команды цикла. В ассемблере для микроконтроллеров такой специальной команды нет, и поэтому цикл приходится организовывать самостоятельно. Вариантов организации цикла много. Ниже предлагается один из них.
Количество повторений цикла известно.
…
LDI R16,К ; установка счетчика циклов.
CIKL: ; метка начала цикла.
… ; начало тела цикла.
… ; конец тела цикла.
DEC R16 ; уменьшение счетчика циклов на 1.
CPI R16,0 ; проверка числа выполненных циклов.
BRNE CIKL ; переход на метку CIKL, если заданное число циклов не выполнено, т.е результат сравнения не 0. Если результат сравнения 0,то выход из цикла и выполнение следующей команды.
Значение К может лежать в диапазоне 1…255. Если необходимое число повторений больше 255, то можно организовать повторение самого цикла. В этом случае цикл может иметь вид:
…
LDI R17,К ; установка внешнего счетчика циклов.
LDI R16,К ; установка внутреннего счетчика циклов.
CIKL2: ; метка начала внешнего цикла.
CIKL1: ; метка начала внутреннего цикла.
… ; начало тела цикла.
… ; конец тела цикла.
DEC R16 ; уменьшение счетчика внутренних циклов на 1.
CPI R16,0 ; проверка числа выполненных внутренних циклов.
BRNE CIKL1 ; переход на мет CIKL1, если заданное число внутренних циклов не выполнено.
DEC R17 ; уменьшение счетчика внешних циклов на 1.
CPI R17,0 ; проверка числа выполненных внешних циклов.
BRNE CIKL2 ; переход на мет CIKL, если заданное число внешних циклов не выполнено, т.е результат сравнения не 0.
; Если результат сравнения 0,то выход из цикла и выполнение следующей команды.
При необходимости изменения числа повторения цикла в процессе выполнения программы, например, задания числа повторения с внешних устройств через порт А, вместо команды LDI R17,К используется команда IN R17,PINA.
Если число повторений цикла заранее не известно, и он выполняется до момента соблюдения некоторого условия можно предложить следующий вариант выполнения такого цикла (например, при равенстве двух регистров):
…
CIKL: ; начало цикла.
CP R1,R2 ; проверка соблюдения условия выхода из цикла.
BREQ WYX ; переход на метку WYX, выход из цикла при соблюдении условия.
… ; начало тела цикла.
… ; конец тела цикла.
RJMP CIKL ; переход на начало цикла.
WYX: ; метка перехода из цикла при соблюдении условия.
…
В таком варианте проверка соблюдения условия выхода из цикла осуществляется до выполнения цикла, и если условие соблюдается сразу, то цикл не будет выполнен вообще.
Ниже приведен вариант цикла, в котором соблюдение условия выхода из цикла проверяется после выполнения цикла. В этом случае при любых условиях цикл будет выполнен хотя бы один раз.
…
CIKL: ; начало цикла.
… ; начало тела цикла.
… ; конец тела цикла.
CP R1,R2 ; проверка соблюдения условия выхода из цикла.
BREQ WYX ; переход на метку WYX, выход из цикла при соблюдении условия.
RJMP CIKL ; переход на начало цикла.
WYX: ; метка перехода из цикла при соблюдении условия.
…
Пример организации цикла при тестировании бита (в данном случае второго в регистре общего назначения R1):
…
CIKL: ; начало цикла.
SBRC R1,2 ; проверка соблюдения условия выхода из цикла (тест бита).
RJMP WYX ; переход на метку WYX, выход из цикла при соблюдении условия (бит равен 1).
… ; начало тела цикла.
… ; конец тела цикла.
RJMP CIKL ; переход на начало цикла.
WYX: ; метка перехода из цикла при соблюдении условия.
…
Пока значение второго бита регистра общего назначения R1 остается равным 0, будет пропускаться команда RJMP WYX и выполняться цикл. Как только значение этого бита станет равным 1, будет выполнена команда RJMP WYX, и осуществится выход из цикла на метку WYX.
В некоторых случаях требуется выполнение каких-то действий не в процессе непрерывного цикла, а однократно при изменении входного сигнала с 0 на 1 или с 1 на 0 (например, при динамической синхронизации). При построении таких программ наиболее рационально использовать внешнее прерывание. Но если по каким-либо причинам это невозможно, можно предложить следующий алгоритм. Само действие оформлено в виде подпрограммы, а основная (фоновая) программа выполняет опрос входного сигнала. Если входной сигнал 0, то опрос повторяется вновь до тех пор, пока на входе не появится 1. После этого однократно выполняется подпрограмма и снова начинается опрос входного сигнала, только теперь опрос повторяется до тех пор, пока на входе не появится 0. После появления 0 осуществляется переход на начало основной программы и цикл начинается снова. Таким образом, подпрограмма выполняется при появлении перепада с 0 на 1.
Пример текста такой программы:
; начало основной (фоновой) программы
OPROS0:
SBIS PIND,2 ; тестирование бита 2 порта D и пропуск следующей команды, если он равен 1
RJIMP OPROS0 ; переход на начало опроса, если бит 2 порта D равен 0
RCALL PROGROMMA ; переход к выполнению подпрограммы
OPROS1:
SBIC PIND,2 ; тестирование бита 2 порта D и пропуск следующей команды, если он равен 0
RJIMP OPROS1 ; переход на начало опроса, если бит 2 порта D равен 1
RJIMP OPROS0 ; переход на начало основной (фоновой) программы, если бит 2 порта D равен 0
PROGROMMA:
… ; начало подпрограммы
…
RET ; конец подпрограммы
Если необходимо выполнение подпрограммы при появлении перепада с 1 на 0, то изменяется только порядок опроса.
Работу цифрового устройства можно описать различными способами: словесно, таблицей истинности, аналитическим выражением. В каждом случае алгоритм реализации будет различным.
В первом случае можно разработать несколько разных алгоритмов. Эти алгоритмы будут наиболее «человечными» из перечисленных.
Во втором случае предполагается реализация таблицы истинности. Таблицу истинности можно рассматривать, как массив входных переменных и массив функций (выходного кода), где каждому элементу массива входных переменных однозначно соответствует элемент массива функций (выходного кода). Алгоритм реализации в этом случае будет одинаковым для всех цифровых устройств. Различие будет только в размерах массивов.
В третьем случае предполагается реализация аналитического выражения, которое и представляет собственно алгоритм. Здесь предполагается в основном использовать группу логических команд. Определенную трудность здесь представляет реализация динамических схем.
Рассмотрим два примера программной реализации цифровых устройств.
Пусть необходимо реализовать классический полный шифратор 4 в 2. Входы шифратора соответствуют выводам (портам) микроконтроллера: 0 – А0, 1 – А1, 2 – В3, 3 – В5. Выходы шифратора соответствуют выводам (портам) микроконтроллера: 1 – С0, 2 – С1.
Как известно, полный шифратор имеет n выходов и 2 n входов. Алгоритм работы шифратора следующий: на выходе устанавливается комбинация, выражающая в двоичном коде номер входа, на который подан активный уровень. Пусть в данном случае активный уровень 1. Нумерация входов начинается с нуля. Условное графическое обозначение такого шифратора показано на рисунке 6.1. На нем обозначены номера входов и соответствующие им номера портов микроконтроллера, а также весовые коэффициенты выходов.
Рисунок 6.1
Таблица 6.7. Таблица истинности шифратора
№ |
Входные переменные |
Функции выхода |
||||
I3 |
I2 |
I1 |
I0 |
A2 |
A1 |
|
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
2 |
0 |
1 |
0 |
0 |
1 |
0 |
3 |
1 |
0 |
0 |
0 |
1 |
1 |
Аналитическое выражение, полученное из таблицы истинности:
После минимизации:
или или
Рисунок 6.2 Блок-схема алгоритма первого варианта программы
Словесное описание шифратора можно реализовать с помощью нескольких алгоритмов.
Самый прямолинейный и, естественно, не самый рациональный следующий. Входная комбинация сначала сравнивается с комбинацией № 0 (0001). Если они равны, то на выходе устанавливается 00 и программа завершает работу, если не равны, то на выходе ничего не устанавливается, а входная комбинация сравнивается с комбинацией № 1 (0010) и т. д. Чем больше возможное число комбинаций входных переменных, тем длиннее становится программа. Но при малом числе входных комбинаций такой способ построения алгоритма может оказаться и рациональным. Кроме того, этот принцип построения алгоритма одинаков для разных цифровых устройств.
Блок-схема алгоритма такой прямолинейной программы показана на рисунке 6.2.
Программирование портов I/O было подробно рассмотрено в предыдущей лабораторной работе и комментариев не требует.
Для снятия неопределенности выходной комбинации и предотвращения возможных сбоев до первого ее определения программой, значение начальной выходной комбинации необходимо задать предварительно.
Опрос портов заключается в переносе информации из входного регистра PIN в один из регистров общего назначения. Это обусловлено тем, что проводить анализ и выполнять операции непосредственно в регистрах порта I/O нельзя (кроме операций над отдельными битами). Кроме того, если в процессе выполнения программы входная информация изменятся, то это может привести к сбою программы или неправильной ее работе.
Компоновка входной информации из отдельных битов в один байт нужна в случае подачи входной информации на линии различных портов. В практике этого в большинстве случаев удается избежать и использовать соседние линии одного порта ( например, для входов шифратора использовать линии А0, А1, А2, А3 ). В данном задании так сделано специально, чтобы рассмотреть наиболее общий возможный вариант.
Переход в конце программы сделан не к блоку программирования портов, а к блоку опроса портов для того, чтобы программирование портов I/O происходило только один раз при начальном пуске программы, а не повторялось при каждом новом цикле работы. Это ускоряет работу программы.
Текст программы, составленный по этой блок-схеме алгоритма:
;*******************************************
; классический шифратор 4 в 2. Прямолинейное решение с тестированием
; байтов
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org$30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; начальная выходная комбинация
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;******************* компоновка входной информации в один байт
BST R17,3 ; перемещение бита В3 в бит 2 регистра R16
BLD R16,2 ; через флаг Т регистра статуса
BST R17,5 ; перемещение бита В5 в бит 3 регистра R16
BLD R16,3 ; через флаг Т регистра статуса
ANDI R16,$0F ; обнуление четырех старших бит регистра R16
;***************** первое сравнение
CPI R16,$01 ; сравнить входную комбинацию с кодом 0001
BRNE SLED1 ; если нет равенства перейти на метку SLED1 для дальнейшего сравнения
;************* отправка комбинации 00 на выход
LDI R18,$00
OUT PORTC,R18 ; отправить комбинацию 00 на выход, если есть равенство
RJMP PROGRAMMA ; перейти на метку PROGRAMMA для нового опроса входа
;************** второе сравнение
SLED1:
CPI R16,$02
BRNE SLED2
;************* отправка комбинации 01 на выход
LDI R18,$01
OUT PORTC,R18
RJMP PROGRAMMA
;*************** третье сравнение
SLED2:
CPI R16,$04
BRNE SLED3
;************* отправка комбинации 10 на выход
LDI R18,$02
OUT PORTC,R18
RJMP PROGRAMMA
;*************** четвертое сравнение
SLED3:
CPI R16,$08
BRNE PROGRAMMA ; если нет равенства, перейти на метку
;PROGRAMMA для нового опроса входа
;************* отправка комбинации 11 на выход
LDI R18,$03
OUT PORTC,R18
RJMP PROGRAMMA ; переход на начало цикла опроса входа
Рисунок 6.3 Блок-схема алгоритма второго варианта программы
Более рациональный способ построения алгоритма основывается на особенностях, присущих программируемому цифровому устройству.
Особенность шифратора в том, что во входной комбинации единица присутствует всегда только в одном разряде, а выходная комбинация - это числа в двоичном коде. Поэтому можно тестировать отдельные биты входной комбинации, а не всю входную комбинацию. Это исключает операции компоновки входной информации. В остальном алгоритм работы остается прежним.
Блок-схема алгоритма такой программы показана на рисунке 6.3.
Текст программы, составленный по этой блок-схеме алгоритма:
;*******************************************
; классический шифратор 4 в 2. Прямолинейное решение с тестированием
; отдельных битов. Вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; начальная выходная комбинация
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
PROGRAMMA:
;***************** опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;***************** первое тестирование
SBRC R16,0 ; тестирование бита А0 на нулевое значение
RJMP SLED0 ; если значение 1, то перейти на метку SLED0
; если 0, то выполнить следующую команду
;***************** второе тестирование
SBRC R16,1 ; тестирование бита А1 на нулевое значение
RJMP SLED1
;***************** третье тестирование
SBRC R17,3 ; тестирование бита В3 на нулевое значение
RJMP SLED2
;***************** четвертое тестирование
SBRC R17,5 ; тестирование бита В5 на нулевое значение
RJMP SLED3
RJMP PROGRAMMA
;************* отправка комбинации 00 на выход
SLED0:
LDI R18,$00
OUT PORTC,R18 ; отправить комбинацию 00 на выход
RJMP PROGRAMMA ; перейти на метку PROGRAMMA для нового опроса входа
;************* отправка комбинации 01 на выход
SLED1:
LDI R18,$01
OUT PORTC,R18
RJMP PROGRAMMA
;************* отправка комбинации 10 на выход
SLED2:
LDI R18,$02
OUT PORTC,R18
RJMP PROGRAMMA
;************* отправка комбинации 11 на выход
SLED3:
LDI R18,$03
OUT PORTC,R18
RJMP PROGRAMMA
Из анализа приведенных программ видно, что одна и та же последовательность команд выполняется четыре раза. Если удастся применить цикл, то программа будет короче. Ассемблер микроконтроллера AVR не позволяет использовать бит в качестве переменной и перебор битов в цикле напрямую организовать нельзя. Но если использовать команды сдвига и тестировать только один фиксированный бит, то цикл организовать возможно.
Блок-схема алгоритма программы с циклом показана на рисунке 6.4.
Первые три блока алгоритма программы с циклом аналогичны блокам программы прямолинейного решения с тестированием байтов (первая программа).
В блоке задания числа циклов и первой выходной комбинации выбирается регистр для счетчика циклов и задается число циклов, в данном случае 4.
Цикл организован следующим образом. Производится опрос нулевого бита регистра общего назначения R16. Если его значение 0, то осуществляется сдвиг регистра R16 на один разряд вправо (в сторону младших разрядов). Если его значение 1, то на выход подается подготовленная перед началом цикла комбинация или комбинация, подготовленная в предыдущем цикле, и только после этого осуществляется сдвиг регистра R16 на один разряд вправо (в сторону младших разрядов). После этого осуществляется подготовка следующей выходной комбинации вне зависимости от результатов сравнения. Затем осуществляется процедура определения окончания цикла. Если были проверены все четыре возможные комбинации, то происходит выход из цикла и переход к новому опросу портов I/O.
Рисунок 6.4 Блок-схема алгоритма третьего варианта программы
В данном алгоритме предполагается, что на вход будут подаваться только корректные комбинации. В случае подачи некорректной комбинации (например 0110) программа может выдать неправильный результат. Студентам предлагается самостоятельно разобраться, какой это будет результат и что надо сделать, чтобы программа работала правильно.
Текст программы, составленный по этой блок-схеме алгоритма:
;*******************************************
; классический шифратор 4 в 2. Решение с помощью организацией цикла
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,0
OUT PORTC,R16 ; установка начальной выходной комбинации
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;******************* компоновка входной информации в один байт
BST R17,3 ; перемещение бита В3 в бит 2 регистра R16
BLD R16,2 ; через флаг Т регистра статуса
BST R17,5 ; перемещение бита В5 в бит 3 регистра R16
BLD R16,3 ; через флаг Т регистра статуса
;******************* задание начальной комбинации счетчика циклов
LDI R19,0 ; первая выходная комбинация
LDI R18, 4 ; установка счетчика циклов
;****************** цикл
CIKL:
SBRC R16,0 ; тестирование бита 0 регистра R16 и пропуск следующей команды, если он равен 0
OUT PORTC,R19 ; вывод выходной комбинации
LSR R16 ; сдвиг вправо для подготовки теста следующего бита
INC R19 ; формирование следующей выходной комбинации
DEC R18 ; уменьшение счетчика циклов на 1.
CPI R18,0 ; проверка числа выполненных циклов.
BRNE CIKL ; переход на начало цикла, если заданное число циклов не выполнено
RJMP PROGRAMMA ; переход для нового опроса входа
Рисунок 6.5 Блок-схема алгоритма четвертого варианта программы
Программная реализация цифрового устройства, заданного таблицей истинности возможна различными методами. Рассмотренный прямолинейный метод построения программы работы шифратора по сути и основан на реализации таблицы истинности. Более рационально программа реализации таблицы истинности в общем случае может быть построена, если использовать способ косвенной адресации.
Блок-схема алгоритма программы с использованием массива и косвенной адресации показана на рисунке 6.5.
Программирование портов I/O осуществляется аналогично предыдущем программам.
Массив входных переменных и массив выходных кодов формируется в ОЗУ в соответствии с таблицей 6.7. Физический адрес начала ОЗУ $60, поэтому начальный адрес массивов должен быть старше. Начальный адрес массива входных переменных принят 100 ($64), начальный адрес массива выходных кодов принят 104 ($68).
Опрос портов I/O и компоновка входной информации из отдельных битов в один байт в регистре R16 аналогична предыдущим программ.
В блоке задания начальных адресов массивов в ОЗУ в регистр косвенной адресации Х (R27,R26) заносится адрес первого элемента массива входных переменных.
Цикл организован следующим образом. Первый элемент массива входных переменных пересылается в регистр R17 и сравнивается с текущей входной комбинацией, которая находится в регистре R16. Если эти значения равны, то в порт I/O отправляется из массива выходной код, адрес которого вычисляется в регистре косвенной адресации Х. Адрес элемента массива входных переменных и адрес соответствующего ему элемента массива выходных кодов смещены относительно друг друга на 4 адреса. Поэтому вычисление производится путем прибавления числа 4 к содержимому регистра Х (R26). Если значения регистров R16 и R17 не равны, то в регистре X устанавливаются следующий по порядку адрес элемента массива входных переменных и цикл сравнения повторяется.
Текст программы, составленный по этой блок-схеме алгоритма:
;*******************************************
; классический шифратор 4 в 2. Использование организации массива
; в ОЗУ и косвенной адресации.
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; начальная выходная комбинация
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
;******************** задание массива входных переменных
LDI R16,1
STS 100,R16
LDI R16,2
STS 101,R16
LDI R16,4
STS 102,R16
LDI R16,8
STS 103,R16
;******************** задание массива выходных кодов
LDI R16,0
STS 104,R16
LDI R16,1
STS 105,R16
LDI R16,2
STS 106,R16
LDI R16,3
STS 107,R16
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;******************* компоновка входной информации в один байт
BST R17,3 ; перемещение бита В3 в бит 2 регистра R16
BLD R16,2 ; через флаг Т регистра статуса
BST R17,5 ; перемещение бита В5 в бит 3 регистра R16
BLD R16,3 ; через флаг Т регистра статуса
ANDI R16,$0F ; обнуление четырех старших бит регистра R16
;***************** задание начального адреса массивов в ОЗУ
LDI R27,0 ; начальный адрес массива входных переменных
LDI R26,100
;***************** обработка массива входных переменных
CIKL:
LD R17,X ; загрузка в R17 элемента массива входных переменных
CP R16,R17 ; сравнение входной комбинации и элемента массива
BREQ VYVOD ; переход на метку вывода информации, если они равны
INC R26 ; установка адреса следующего элемента массива входных переменных
RJMP CIKL ; переход к новому циклу сравнения
VYVOD:
ADIW R26,4 ; вычисление адреса элемента выходного кода
LD R18, X ; поместить в R18 выбранный элемент массива выходных кодов
OUT PORTC,R18 ; отправить выходной код на выход
RJMP PROGRAMMA ; перейти на метку PROGRAMMA для нового опроса входа
Программа получилась более длинной, чем прямолинейная программа. Но собственно программа, которая выполняется циклически, получилась короче. Так произошло потому, что использовался не весь набор возможных команд и директив.
Если использовать полный набор команд, то текст программы будет более коротким. Ниже рассмотрен пример такой программы.
Общий массив входных переменных и выходных кодов здесь находится не в ОЗУ, а в программной памяти. Он задается директивой DB и организуется в процессе компиляции. Начальный адрес этого массива определяется путем подсчета команд, которые выполняются перед директивой DB. В данном случае это команда rjmp, которая занимает два байта и находится по адресу $000. Поэтому начальный адрес массива 0 + 2 = 2, т. е. $002. В этом общем массиве комбинация входных переменных и соответствующий ей выходной код смещены относительно друг друга на 4 адреса (байта памяти).
Программа приведена в качестве демонстрации и может не рассматриваться, не браться в качестве образца и подробно не анализироваться при выполнении данной лабораторной работы.
;*******************************************
; классический шифратор 4 в 2. Использование организации массива
; в памяти программ и косвенной адресации.
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org $00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
MASSIV:
.DB 1, 2, 4, 8, 0, 1, 2, 3 ; задание в памяти программ общего массива
; входных переменных и выходных кодов
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; начальная выходная комбинация
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;******************* компоновка входной информации в один байт
BST R17,3 ; перемещение бита В3 в бит 2 регистра R16
BLD R16,2 ; через флаг Т регистра статуса
BST R17,5 ; перемещение бита В5 в бит 3 регистра R16
BLD R16,3 ; через флаг Т регистра статуса
ANDI R16,$0F ; обнуление четырех старших бит регистра R16
;***************** задание начального адреса общего массива входных переменных и выходных кодов
LDI R31,0 ; старший байт регистра Z
LDI R30,2 ; младший байт регистра Z
;******************обработка массивов
CIKL:
LPM ; извлечение из памяти программ в регистр R0 элемента массива входных переменных
CP R16,R0 ; сравнение элемента массива входных переменных с входной комбинацией
BREQ VYVOD ; переход на метку вывода элемента массива, если он равен входной комбинации
INC R30 ; установка адреса следующего элемента массива
RJMP CIKL ; переход к новому циклу сравнения
VYVOD:
ADIW R30,4 ; вычисление адреса выводимого элемента массива выходных кодов
LPM ; извлечение из памяти программ в регистр R0 элемента массива входных переменных
OUT PORTC,R0 ; отправить выходной код на выход
RJMP PROGRAMMA ; перейти на метку для нового опроса входа
Программа во всех отношениях оказалась короче предыдущей.
Для цифрового устройства, работа которого задана аналитическим выражением, какого-то особого алгоритма составлять не требуется, т. к. аналитическое выражение уже само по себе является алгоритмом. Нужно только правильно подготовить входные данные и правильно сформировать выходной код.
Программирование портов I/O аналогичное предыдущим программам.
Входная информация компонуется в регистрах R16 и R17 в двух младших разрядах с помощью сдвига и переноса значений битов в нужные места через флаг Т регистра статуса.
Значение битов С1 и С0 определяется одновременно с помощью побитной операции ИЛИ формируется в регистре R16 и отправляется на выход.
Блок-схема алгоритма программы, реализующее аналитическое выражение работы шифратора, показана на рисунке 6.6.
Рисунок 6.6 Блок-схема алгоритма пятого варианта программы
Текст программы, составленный по этой блок-схеме алгоритма:
;*******************************************
; классический шифратор 4 в 2. Использование напрямую аналитического
; выражения
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; установка начальной выходной комбинации
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;*******************компоновка входной информации в R16 и R17
BST R17,5 ; перемещение бита 5 (В5) в
BLD R17,0 ; в бит 0 регистра R17 через флаг Т регистра статуса
BLD R17,1 ; в бит 1 регистра R17 через флаг Т регистра статуса
LSR R16 ; перемещение бита 1 (А1) регистра R16 в бит 0 R16
BST R17,3 ; перемещение бита 3 (В3) в
BLD R16,1 ; в бит 1 регистра R16 через флаг Т регистра статуса
;******************формирование выходного кода
OR R16,R17 ; вычисление выходного кода
ANDI R16, $03 ; обнуление битов 2…7 выходного кода
OUT PORTC,R16 ; отправить выходной код на выход
RJMP PROGRAMMA ; переход на метку PROGRAMMA для нового опроса входа
В заключении следует рассмотреть пример построения программы динамического цифрового устройства на примере шифратора. В этом случае обработка входных данных и вывод результата осуществляется не в процессе непрерывного цикла, а однократно при возникновении перепада сигнала на управляющем входе с 1 на 0 (или с 0 на 1).
Наиболее рациональное построение такой программы с использованием внешнего прерывания будет рассмотрено в следующей лабораторной работе. Здесь же рассмотрен способ построения с помощью непрерывного опроса синхронизирующего входа. Синхронизирующим входом выбран порт D2 микроконтроллера. Активный перепад с 0 на 1.
Кроме того, в данной программе рассмотрен пример использования подпрограммы. В качестве подпрограммы используется программа реализации шифратора с использованием цикла.
После блока программирования портов I/O предусмотрен блок организации стека. Стек необходим при использовании подпрограмм. Подробно стек и его организация будет рассмотрен в следующей лабораторной работе.
Основная (фоновая) программа начинается с тестирования (опроса состояния) бита 2 порта D (регистр PIND) на единичное значение. Если бит равен 0, то опрос повторяется снова до тех пор, пока бит не примет значение 1. Когда бит равен 1, осуществляется вызов подпрограммы и ее выполнение. После выполнения подпрограммы происходит возврат в основную программу и снова начинается опрос состояния бита 2 порта D. Только теперь тестирование происходит на нулевое значение и опрос повторяется до тех пор, пока бит не примет значение 0. Когда бит равен 0, осуществляется переход к блоку тестирование бита 2 порта D на единичное значение. Весь цикл повторяется сначала.
Блок-схема алгоритма программы работы шифратора для этого случая показана на рисунке 6.7.
Рисунок 6.7 Блок-схема алгоритма шестого варианта программы
Собственно шифратор реализует подпрограмма. Она ничем не отличается от третьего варианта (реализация с использованием цикла). Блок-схема алгоритма подпрограммы, имитирующей шифратор показана на рисунке 6.8.
Рисунок 6.8 Блок-схема алгоритма подпрограммы, имитирующей шифратор
Текст программы, составленный по блок-схемам алгоритмов, показанных на рисунках 6.7 и 6.8:
;*******************************************
; классический шифратор 4 в 2 с входом синхронизации
; вход В5, В3, А1, А0, выход С1, С0.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTC,R16 ; установка начальной выходной комбинации
OUT DDRA,R16 ; программирование порта А на вход
OUT DDRB,R16 ; программирование порта В на вход
OUT DDRD,R16 ; программирование порта D на вход
LDI R17,$FF
OUT DDRC, R17 ; программирование порта С на выход
;******************* организация стека
LDI R16,$00
OUT SPL, R16 ; запись адреса в младший байт указателя стека
LDI R17,$02 ; запись адреса в старший байт указателя стека
OUT SPH, R17 ; итоговый физический адрес $0200 (512)
;******************* основная (фоновая) программа
OPROS0:
SBIS PIND,2 ; тестирование бита 2 порта D и пропуск следующей команды, если он равен 1
RJMP OPROS0 ; переход на начало опроса, если бит 2 порта D равен 0
RCALL PROGRAMMA ; переход к выполнению подпрограммы
OPROS1:
SBIC PIND,2 ; тестирование бита 2 порта D и пропуск следующей команды, если он равен 0
RJMP OPROS1 ; переход на начало опроса, если бит 2 порта D равен 1
RJMP OPROS0 ; переход на начало основной (фоновой) программы, если бит 2 порта D равен 0
;******************** подпрограмма
PROGRAMMA:
;******************* опрос портов I/O
IN R16,PINA ; поместить входные данные из порта А в R16
IN R17,PINB ; поместить входные данные из порта В в R17
;******************* компоновка входной информации в один байт
BST R17,3 ; перемещение бита В3 в бит 2 регистра R16
BLD R16,2 ; через флаг Т регистра статуса
BST R17,5 ; перемещение бита В5 в бит 3 регистра R16
BLD R16,3 ; через флаг Т регистра статуса
;******************* задание начальной комбинации счетчика циклов
LDI R19,0 ; первая выходная комбинация
LDI R18, 4 ; установка счетчика циклов
;****************** цикл
CIKL:
SBRC R16,0 ; тестирование бита 0 регистра R16 и пропуск следующей команды, если он равен 0
OUT PORTC,R19 ;
LSR R16 ; сдвиг вправо для подготовки теста следующего бита
INC R19
DEC R18 ; уменьшение счетчика циклов на 1.
CPI R18,0 ; проверка числа выполненных циклов.
BRNE CIKL ; переход на начало цикла, если заданное число циклов не выполнено
RET ; выход из подпрограммы
В результате анализа представленных программ реализации одного и того же устройства можно сделать следующие выводы.
Если исключить подготовительные процедуры (программирование портов, задание массивов и т. д.), то самыми длинными оказалась программы, использующие прямолинейный алгоритм. Причем их размер будет расти с увеличением числа входов шифратора.
Самой короткой оказалась программа, реализующая аналитическое выражение. Но это потому, что аналитическое выражение оказалось простым, и размер этой программы тоже будет расти с увеличением входов шифратора.
Программы с использованием циклов (при использовании массива тоже организуется цикл) оказались несколько длиннее программы, реализующей аналитическое выражение, но значительно короче программ, использующих прямолинейный алгоритм. Причем при увеличении числа входов шифратора размер этих программ останется прежнем. Таким образом, эти программы являются наиболее рациональными.
Анализ с точки зрения времени выполнения каждой программы предлагается провести студентам самостоятельно.
Следует отметить, что во всех программах, кроме первой, при некорректной входной комбинации результат работы программы может не соответствовать правильной работе шифратора. Студентам предлагается самостоятельно скорректировать программы для устранения этого недостатка.
В качестве второго примера предлагается рассмотреть программу для управления устройством автоматического поддержания уровня воды в резервуаре в заданных пределах. Такие системы поддержания определенного параметра (жидкости, давления, температуры и т. д.) в заданных пределах встречаются часто. В резервуаре имеется два датчика: датчик нижнего уровня и датчик верхнего уровня. Оба датчика устанавливаются в 1, если находятся вводе, и в 0, если в воде не находятся. Вода в резервуар подается при включении насоса.
Процесс поддержания уровня воды должен происходить следующим образом. При включении насоса вода начинает поступать в резервуар. Когда уровень воды достигнет верхнего допустимого уровня, датчик верхнего уровня Н установится в 1, и насос должен быть выключен. После выключения насоса уровень воды начнет понижаться. Когда уровень воды достигнет нижнего допустимого уровня, датчик нижнего уровня L установится в 0, и насос должен быть включен. При включении насоса вода начинает поступать в резервуар, и описанный цикл будет повторяться снова.
Подробно синтез управляющего устройства (автомата) для подобных систем рассматривался раньше, поэтому получение таблицы истинности и аналитического выражения здесь не приводится.
Алгоритм, основанный на словесном описании процесса работы следующий. Сначала производится опрос датчика нижнего уровня L. Если значение L= 0, то выдается сигнал на включение насоса и вновь производится опрос датчика L, если значение L=1, то осуществляется переход к опросу датчика верхнего уровня H. Если значение H=1, то выдается сигнал на выключение насоса и осуществляется переход к опросу датчика нижнего уровня L, если значение Н=0, то сразу осуществляется переход к опросу датчика нижнего уровня L.
Датчик нижнего уровня L подключен к линии А0 порта А, датчик верхнего уровня H подключен к линии А1 порта А, насос управляется по линии А2 порта А.
Блок-схема алгоритма программы работы этого автомата показана на рисунке 6.9.
Рисунок 6.9 Блок-схема алгоритма подпрограммы автомата
Текст программы, составленный по блок-схемам алгоритма, показанного на рисунке 6.9:
;*******************************************
; Автомат поддержание уровня воды в резервуаре в заданном диапазоне
; входы А1, А0, выход А2.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org $30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTA,R16 ; установка начальной выходной комбинации
LDI R16,$04 ; программирование линий порта А
OUT DDRA, R16 ; на вход А1 и А0, А2 на выход
;******************* программа
OPROS_L:
SBIC PINA,0 ; опрос датчика нижнего уровня (бита 0 порта А)
; и пропуск следующей команды, если он равен 0
RJMP OPROS_H ; переход на опрос датчика верхнего уровня (Н),
; если датчик нижнего уровня равен 1
SBI PORTA,2 ; включение насоса
RJMP OPROS_L ; переход на опрос датчика нижнего уровня (L),
OPROS_H:
SBIS PINA,1 ; опрос датчика верхнего уровня (бита 1 порта А)
; и пропуск следующей команды, если он равен 1
RJMP OPROS_L ; переход на опрос датчика нижнего уровня (L)
CBI PORTA,2 ; выключение насоса
RJMP OPROS_L ; переход на опрос датчика нижнего уровня (L)
Таблица 6.8. Таблица истинности разрабатываемого автомата
№ |
Входные переменные |
Функция выхода |
||
Q |
H |
L |
Q + |
|
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
2 |
0 |
0 |
1 |
0 |
3 |
1 |
0 |
1 |
1 |
4 |
0 |
1 |
1 |
0 |
5 |
1 |
1 |
1 |
0 |
Принцип разработки программы по этой таблице принципиально ничем не отличается от разработки программы работы шифратора по таблице 6.7. Надо только учесть, что в цифровом автомате (последовательном устройстве) функция (в данном случае Q+) зависит не только от комбинации входных переменных, но и от предыдущего состояния самой функции (в данном случае Q). Поэтому должен осуществляться опрос не только входов, но и выходов.
Рисунок 6.10 Блок-схема алгоритма подпрограммы автомата
Аналитическое выражение, полученное из данной таблицы истинности после минимизации:
или
Блок-схема алгоритма программы работы этого автомата показана на рисунке 6.10. После опроса датчиков и состояния выхода входная информация перемещается в регистр R17 для получения инверсных значений переменных H и L. Результаты вычислений формируются в бите 2 регистра R16. Переменные H и L перемещаются в бит 2 путем сдвига регистра R17 влево. После вычислений содержимое регистра R16 отправляется на выход.
В обеих программах не предусмотрено появление некорректной ситуации, когда значение датчика нижнего уровня 0, а значение датчика верхнего уровня 1. Студентам предлагается самостоятельно переработать программы таким образом, чтобы исключить неправильное действие автомата в таком случае.
Текст программы, составленный по блок-схемам алгоритма, показанного на рисунке 6.9:
;*******************************************
; Автомат поддержание уровня воды в резервуаре в заданном диапазоне
; входы А1, А0, выход А2.
;*******************************************
.include “8535def.inc” ; файл описанияAT90S8535.
.cseg
.org$00 ; адрес начала программы в памяти программ.
rjmp nacalo ; прерывание по сбросу и включению питания.
.org$30 ; адрес начала основной программы в памяти программ.
nacalo: ;начало основной программы
;******************** программирование портов I/O
LDI R16,$00
OUT PORTA,R16 ; установка начальной выходной комбинации
LDI R16,$04 ; программирование линий порта А
OUT DDRA, R16 ; на вход А1 и А0, А2 на выход
PROGRAMMA:
;******************* опрос порта I/O
IN R16,PINA ; поместить входные данные из порта А в R16
;******************формирование выходной функции
MOV R17,R16 ; переместить данные в R17 для промежуточных
; преобразований
COM R17 ; получение инверсных значений H и L
LSL R17 ; подготовка к выполнению операции
AND R16, R17 ; выполнение операции
LSL R17 ; подготовка к выполнению операции
OR R16,R17 ; выполнение операции
ANDI R16, $04 ; обнуление битов 0…1 и 3…7 выходного кода
OUT PORTA,R16 ; отправить значение функции на выход
RJMP PROGRAMMA ; переход на метку PROGRAMMA для нового опроса входа
Похожие материалы
... правило, выполняется в виде одной «большой» ИМС. Схемотехника является частью микроэлектроники, предметом которой являются методы построения устройств различного назначения на микросхемах широкого применения. Предметом же цифровой схемотехники являются методы построения (проектирования) устройств только на цифровых ИМС. Особенностью цифровой схемотехники является широкое применение для описания ...
... показана на рисунке 8.4 Величина резистора R выбирается из условия [12] 240 Ом < R < 1,5 кОм.(8.5) Рисунок 8.4 Период генерируемых импульсов (8.6) 9. ФУНКЦИОНАЛЬНЫЕ УСТРОЙСТВА КОМПЬЮТЕРНОЙ (ЦИФРОВОЙ) ЭЛЕКТРОНИКИ 9.1 Комбинационные цифровые устройства (КЦУ) Логические устройства, выходные сигналы которых однозначно определяются комбинацией входных логических ...
... ТРЕБОВАНИЙ И ПОСТАНОВКА ЗАДАЧ ПРОЕКТИРОВАНИЯ 1.1 Расчеты основных параметров электромеханической системы привода В данном курсовом проекте разрабатывается привод подач токарного станка. Для перемещения по координате предусмотрен свой привод. Поэтому разработку производим для одного контура управления. Применение ЦСУ позволяет значительно повысить точность и качество обработки, упростить ...
... y n – 2. Коэффициенты b1i , a1i , b2i , a2i определяют характеристики фильтра. При значениях коэффициентов b 20 = 0.958;b 21 = 1;b 22 = 0; a 21 = 0;a 22 = 0.958 фильтр имеет АЧХ фазового звена. В z-плоскости свойства цифрового фильтра описывает передаточная функция H(z), которая при двухкаскадной структуре и для приведенного выше разностного уравнения имеет вид: При z = e jwT = ...
... AVR Studio запомнит расположение окон и использует эти установки при следующем запуске проекта. 3.2. Анализ методики реализации разработки программного обеспечения 3.2.1. Классификация вариантов заданий Цель заданий – практическое освоение методики программирования на ассемблере микроконтроллеров ATMEL семейства AVR, отладка программы на симуляторе AVR Studio и программирование кристалла с помощью ...
0 комментариев