Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЗ.docx
Скачиваний:
6
Добавлен:
16.05.2015
Размер:
611.52 Кб
Скачать

Работа устройства.

Автоматический сброс микроконтроллера предусмотрен после включения питания. На вход SR подключен конденсатор ёмкостью 1мкФ. При поступлении сигнала «СБРОС» микроконтроллер переходит в исходное состояние:

  • в счётчик команд записывается адрес 0000.

  • устанавливаются регистры портов ввода/вывода.

  • блокируется прерывание от внешних сигналов к таймеру.

  • запрещается выдача синхроимпульсов на выход Т0 и останавливается таймер.

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

Опрос кнопок происходит в главном цикле программы. Проверяются состояния пинов, к которым подключены кнопки и принимается решение о необходимом воздействии. Если нажимается кнопка «плюс», то инкрементируется младший разряд. При его переполнении до 10, происходит его обнуление и инкрементируется старший разряд. При достижении максимального числа (99) происходит обнуление и прибавление времени начинается заново от нуля. Аналогичный алгоритм и с нажатиями на кнопку «минус». Кнопка «Старт» разрешает вести обратный отсчет и блокирует опрос кнопок «минус» и «плюс».

При достижении в процессе обратного отсчета конечного времени «00» происходит запуск таймера 1, который настроен на частоту 1 кГц. В своём алгоритме он инвертирует состояние пина к которому подключен динамик. Так же используется блокировка инверсии через определенные промежутки времени для того чтобы сигнал был прерывистый.

Алгоритм приведен на рисунке 7.

Рис. 7. Основной цикл программы

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

Таймер 0 использует в своем алгоритме подсчет переменной равной 100, для получения времени равному 1 секунде. Аналогично таймер 1 использует переменную, по который он отсчитывает прерывистость в выдаваемом сигнале.

Программа на языке Ассемблер

t_const EQU -10000 ;константа, используемая в таймере 0, равна 10 мс

_1000kgc EQU -1000 ; константа таймера 1, задающая прерывания с частотой 1 кГц

N_indicator EQU 31h ;переменная для хранения номера выводимого индикатора в данный момент

ed EQU 32h ; память для текущий единиц

des EQU 33h ; и десятков

count EQU 35h ;дополнительная задержка для получения 1 секунды

preriv EQU 36h ;переменная отсчета прерывания в выводе сигнала

pause EQU 00h ;бит паузы для получения прерывистого сигнала

timer_status EQU 34h ; статус таймера

org 0

jmp START

org 000Bh ;Прерывание от Т0

jmp i_t0

org 001Bh ;Прерывание от T1

jmp signal

;----------------------------------------------

;Подпрограммы

;----------------------------------------------

i_t0: ;прерывание от таймера 0

push acc ; сохраняем аккумулятор

mov A, timer_status

jb ACC.1, count_next ;пропуск отсчета если закончился

jnb ACC.0, count_next ;или не начался

dec count

mov A, count

cjne A, #0, count_next

mov count, #100

dec ed

mov A, ed

cjne A, #255, count_next

mov ed, #9

dec des

mov A, des

cjne A, #255, count_next

mov timer_status, #2 ; ******************************

setb tr1 ;включение сигнала

mov ed, #10

mov des, #10

count_next:

;Перезапуск таймера

mov th0,#HIGH(t_const)

mov tl0,#LOW (t_const)

;Включаем следующий индикатор

inc N_indicator

mov a,N_indicator

cjne a,#2,no_overflow_N_indicator

mov N_indicator,#0

no_overflow_N_indicator:

mov a,N_indicator

cjne a,#0,no_N0

clr p3.1

setb p3.0

jmp OK_N_indicator

no_N0:

clr p3.0

setb p3.1

OK_N_indicator:

;Выводим информацию на индикатор

mov a,#ed

add a,N_indicator

mov r0,a

mov a,@r0

mov dptr,#Table_Cod_Indicator

movc a,@a+dptr

out_ind:

mov p1,a

pop acc

reti

; Прерывание от таймера 1, вывод сигнала в порт*******

signal:

mov th1,#HIGH(_1000kgc)

mov tl1,#LOW (_1000kgc)

jb pause, no_inv ; если на пузе то не выводим

cpl P3.5

no_inv:

dec preriv

mov A, preriv

cjne A, #0, signal_exit

mov preriv, #250

cpl pause

signal_exit:

reti

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

;Подпрограмма инициализации

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

init:

mov tmod,#00010001b //настройка таймеров

mov th0,#HIGH(t_const)

mov tl0,#LOW (t_const)

mov th1,#HIGH(_1000kgc)

mov tl1,#LOW (_1000kgc)

mov timer_status, #0

mov N_indicator,#0

clr p3.0

clr p3.1

mov ed,#0

mov des,#0

mov count, #100

setb et0

setb et1

setb ea

setb tr0

ret

START:

lcall init

cycle:

jnb P3.4, kn_Start

mov A, timer_status

jb ACC.0, cycle_next

jnb P3.3, kn_Minus

jnb P3.2, kn_Plus

jmp cycle_next

kn_Start:

mov timer_status, #1

jmp cycle_next

kn_Minus:

jb p3.3, Minus

jmp kn_Minus

Minus:

dec ed

mov A, ed

cjne A, #255, cycle_next

mov ed, #9

dec des

mov A, des

cjne A, #255, cycle_next

mov ed, #9

mov des, #9

jmp cycle_next

kn_Plus:

jb p3.2, Plus

jmp kn_Plus

Plus:

inc ed

mov A, ed

cjne A, #10, cycle_next

mov ed, #0

inc des

mov A, des

cjne A, #10, cycle_next

mov ed, #0

mov des, #0

jmp cycle_next

cycle_next:

jmp cycle

;----------------------------------------------

;Таблица кодов семисегментного индикатора

Table_Cod_Indicator:

db 0C0h,0F9h,0A4h,0B0h,99h,92h,82h,0D8h,80h,90h,10111111b, 00001000h

END