Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MPSU_laboratornye.doc
Скачиваний:
73
Добавлен:
11.05.2015
Размер:
1.26 Mб
Скачать

Лабораторная работа №4. Алгоритмы программного управления. Временные задержки. Таймеры/счётчики

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

Краткие теоретические сведения

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

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

MVI B,133D ; 7 тактов

M0: DCR B ; 5 тактов

JNZ M0 ; 10 тактов

повторяется 133 раза и 2002 такта, что при частоте тактового генератора 2МГц соответствует 0.001 сек (с точностью 0.1%).

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

Основная идея такой задержки загрузить контроллер бессмысленной работой, чтобы нащелкать как можно больше тактов. У каждого такта есть своя длительность, так что длительность задержки можно формировать от микросекунд, до десятков лет.

Вот решение в лоб:1

LDI R16, Delay

Loop: DEC R16

BRNE loop

Процессор потратит примерно Delay*2 тактов на бессмысленные операции. При длительности такта (на 8мгц) 1.25Е-7 секунд максимальная выдержка будет 6.4E-5 секунды. Немного, но, например, хватит на то чтобы дисплей прожевал отданный ему байт и не подавился следующим.

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

Но есть более красивое решение, нежели вложенные циклы – вычитание многобайтного числа с переносом.1

LDI R16,LowByte ; Грузим три байта

LDI R17,MidleByte ; Нашей выдержки

LDI R18,HighByte

loop: SUBI R16,1 ; Вычитаем 1

SBCI R17,0 ; Вычитаем только С

SBCI R18,0 ; Вычитаем только С

BRCC Loop ; Если нет переноса - переход.

В результате, вначале у нас отнимается 1 из первого числа, а перенос возникает только тогда, когда заканчивается очередной байт. Получается, что из R16 отнимают на каждой итерации, из R17 на каждой 256 итерации, а из R18 на каждой 65535 итерации.

А всего на таких трех регистрах можно замутить тупняк на 256*256*256 тактов. И никто не мешает в том же ключе навешать еще регистров, вплоть до R31 =) И длительность задержки будет куда точней, т.к. в отличии от вложенных циклов, команда BRCC всегда будет выполняться за 2 такта и лишь в последнем случае за один.

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

Встроенный таймер/счётчик (Т/С) позволяет аппаратно реализовать интервалы времени (режим таймера) и подсчитать число внешних событий (режим счётчика). Таймер позволяет формировать временные интервалы с дискретностью xx микросекунд и максимальной длительностью 256*80мкс=20.48миллисекунд. Счётчик позволяет подсчитывать до 256 внешних импульсов. Указанные ограничения можно обойти, подсчитывая дополнительно количество переполнений регистра Т/С.

.include "m2560def.inc"

init:

ldi r16, 0xFF

out DDRB, r16

ldi r16, 0x00

out DDRD, r16

main:

clz

cln

in r17, PIND

cpi r17, 0x00

brne delay

rjmp main

delay:

eor r21, r17

out PORTB, r21

clz

ldi r18, 0x05

ldi r19, 0xFF ;FF

ldi r20, 0xFF ;FF

del:

dec r20

brne del

ldi r20, 0xFF

dec r19

brne del

ldi r20, 0xFF

ldi r19, 0xFF

dec r18

brne del

rjmp main

3.1.Написать программу на Assembler, которая по нажатию кнопки 1 мигает красным светодиодом с частотой 0,5Гц; по нажатию двух кнопки 2 мигает зелёным светодиодом с частотой 1Гц. Цикл мигания организовать с помощью программной задержки. Программу проверить на модели в Proteus.

3.2.Написать программу, которая по нажатию двух кнопок (1 и 0), считывает в РОН 8-разрядное двоичное число и выводит результат на линейку светодиодов. Также требуется сделать программный антидребезговй фильтр (без использования прерываний), чтобы корректно читать информацию с кнопок.

3.3.Написать программу, которая будет симулировать работу простого дешифратора 3 на 8 (активным сигналом на выходе является низкий логический уровень):

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]