Автор работы: Пользователь скрыл имя, 11 Мая 2013 в 10:38, курсовая работа
В режиме счёта на дисплей терминала выводится текущее время в формате hh:mm:ss, где , , ;
В режиме счёта возможен запуск и установка времени при нажатии на кнопки матричной клавиатуры “3” и ”6” соответственно.
В режиме установки времени выполняется последовательный ввод значений двузначных регистров, начиная с ss, причём в каждом регистре сначала задаётся значение десятков, а затем единиц. На этапе ввода значений регистров должна производиться проверка корректности задаваемых чисел и, в случае их выхода за пределы допустимого для регистра диапазона значений, — коррекция до верных значений.
Аннотация 2
1. Техническое задание 4
Техническое задание 4
2.Анализ технического задания 4
3. Устройства ввода 4
4. Алгоритм основной программы 7
5. Алгоритмы обработчиков прерываний 8
5.1 Алгоритм обработчика com порта 8
5.2 Алгоритм обработчика прерываний от таймера T0 9
5.3 Алгоритм обработчика прерываний от порта P1 10
6. Исходный код 11
7. Выводы 19
8. Список литературы: 19
Московский государственный институт электроники и математики
Кафедра ИКТ
Курсовая работа
по дисциплине “Микропроцессорные системы”
(Вариант 15)
Выполнили: студенты группы С-85
Козловский И. А.
Угрозов А. В.
Проверил:
Гудков Ю. И.
Москва 2008
В курсовой работе описывается программная реализация электронных часов с использованием прерываний от последовательного порта, порта P1 и таймера.
Оглавление
Разработать программу для микроконтроллера на базе микроконтроллера 80С552, реализующую работу шестнадцатиричных электронных часов и имеющую следующие особенности:
а) режим счёта
b) режим установки времени;
В режиме счёта на дисплей терминала выводится текущее время в формате hh:mm:ss, где , , ;
В режиме счёта возможен запуск и установка времени при нажатии на кнопки матричной клавиатуры “3” и ”6” соответственно.
В режиме установки времени выполняется последовательный ввод значений двузначных регистров, начиная с ss, причём в каждом регистре сначала задаётся значение десятков, а затем единиц. На этапе ввода значений регистров должна производиться проверка корректности задаваемых чисел и, в случае их выхода за пределы допустимого для регистра диапазона значений, — коррекция до верных значений.
Переход в режим установки времени необходимо осуществлять нажатием кнопки ’9’ матричной клавиатуры. Выход из режима установки времени должен происходить автоматически по окончании ввода значений всех регистров, т.е. сразу после задания числа единиц регистра hh.
Для ввода данных используется стандартная шестнадцатикнопочная клавиатура, подключаемая к параллельному порту (P1). Она имеет следующий вид:
Чтобы определить, нажата или нет какая-либо клавиша-ключ, сначала нужно выставить на линии регистра-защёлки P1, которые соединяет клавиша, разные логические значения. Затем необходимо считать из регистра значения этих линий: если оба бита стали равными «0», то значит, проверяемая клавиша была нажата.
Для сокращения процедуры опроса клавиатуры будем делать опрос по «строкам»:
|
Чтобы просто зафиксировать факт нажатия любой из цифровых клавиш, достаточно выставить в регистр P1 слово #00001111b и ожидать на P1 значение #0000x1xxb, где xÎ{0;1}.
Особенностью данной клавиатуры, которую
надо учитывать при
;;;; ОПИСАНИЕ ПЕРЕМЕННЫХ: ;;;;
;R0 - итерация для режима установки времени; для удобства
;R1 - адрес для косвенно-регистровой адресации, указывающий на регистры R2-R4
;регистры R2 - секунды (ss) in [0..3Bh]
;регистры R3 - минуты (mm) in [0..3Bh]
;регистры R4 - часы (hh) in [0..17h]
;регистры R5,R6 - для разных промежуточных значений
;регистр R7 - буфер для хранения значения нажатой клавиши [#0..#9] или
; значения #FFh, если клавиша не нажата
CR equ 0Dh; "возврат каретки"
LF equ 0Ah; "перевод строки"
ESC equ 1Bh; "конец сообщения"
TimerRepeat equ 30h; число полных циклов таймера, через которое нужно
; обрабатывать прерывание по переполнению
fMode equ 20h.0; текущий режим:
; "0" - режим счёта
; "1" - режим установки времени
; ******************************
; ******************************
; ОПИСАНИЕ ТОЧЕК ВХОДА ОСНОВНОЙ ПРОГРАММЫ и ПОДПРОГРАММ ПРЕРЫВАНИЙ
ORG 8000h; - точка входа в основную программу
jmp lbMain
ORG 800Bh; - прерывание по переполнению таймера (по биту TF0)
jmp intTF0
;;Далее по каждому биту назначаем одно прерывание и по фронту, и по срезу:
ORG 8033h; - прерывание по биту P1.0 (по любому фронту)
jmp intP1
ORG 803Bh; - прерывание по биту P1.1 (по любому фронту)
jmp intP1
ORG 804Bh; - прерывание по биту P1.3 (по любому фронту)
jmp intP1
ORG 8023h ; - прерывание по послед порту
jmp intRi
; ******************************
; ******************************
; ОСНОВНАЯ ПРОГРАММА
lbMain:
clr RI
; конфигурируем таймер T0:
anl TMOD, #0F0h; обнуляем младшую тетраду
orl TMOD, #01h; младшую тетраду приводим к виду "0001"
clr TR0; остановка таймера T0 (таймер - не считает)
; настраиваем систему
mov IP, #00000010b; (IP0) все прерывания (пока) - с одинаковым низким уровнем
; приоритета
mov 0F8h, #00000000b; (IP1)
mov IE, #10000010b; IEN0: выставили биты EA(7),ET0(1)
mov 0E8h, #00001011b; IEN1: выставили биты 0,1,3
mov P1, #00001111b
mov 0EBh,#11111111b; (CTCON) разрешаем прерывания по битам P1 по фронту и срезу
;задаём начальное время:
mov R2, #12h; секунды
mov R3, #00h; минуты
mov R4, #05h; часы
clr fMode; изначально - в режим счёта
;I. РЕЖИМ СЧЁТА:
lbCountMode:
clr IE.7
mov DPTR, #msgShowTimeMode
call prShowMessage; вывод сообщения msgShowTimeMode
; настраиваем таймер T0:
mov TH0, #0
mov TL0, #0
mov TimerRepeat, #13
mov P1, #00001111b
setb IE.7
clr IE.4
setb TR0; запускаем таймер (таймер - считает). Пошло инкрементирование T0
lbCountMode_Loop:
; проверяем бит режима, и выполняем соответствующий переход:
jb fMode, lbSetTimeMode
jmp lbCountMode_Loop
;II. РЕЖИМ УСТАНОВКИ ВРЕМЕНИ:
lbSetTimeMode:
clr IE.7
clr TR0; остановка таймера T0 (таймер - не считает)
mov DPTR, #msgSetTimeMode
call prShowMessage; вывод сообщения msgSetTimeMode
mov R0, #04h; задаём начальное значение; всего будет семь итераций
mov P1, #00001111b
setb IE.7 ; возможность прерывания от SBUF
setb IE.4
mov 0E8h, #00000000b ; запрет прерываний от P1
lbSetTimeMode_Loop:
;проверяем бит режима, и выполняем соответствующий переход:
jnb fMode, lbCountMode
jmp lbSetTimeMode_Loop
; ******************************
; ******************************
; ПОДПРОГРАММЫ_ОСНОВНЫЕ
; ||||||||||||||||||||||||||||||
;; процедура intTF0:
intTF0:
clr IE.7
clr TF0; сбрасываем бит переполнения ВРУЧНУЮ!
djnz TimerRepeat, lbTF0_End;
; реализация собственно "хода" часов:
inc R2
cjne R2, #3Ch, lbTF0_Next1
mov R2, #0h
inc R3
cjne R3, #3Ch, lbTF0_Next1
mov R3, #0h
inc R4
cjne R4, #18h, lbTF0_Next1
mov R4, #0
lbTF0_Next1: mov TimerRepeat, #13
lbTF0_End: call prDisplay
setb IE.7
reti
; ||||||||||||||||||||||||||||||
;; процедура prDisplay:
clr IE.4
lbDrawSeparator:
call prWaitFor_TI
mov SBUF, #3Ah
lbDrawElement:
mov B, #10h
div AB
call A_check
call prWaitFor_TI
mov SBUF, A
mov A, B
call A_check
call prWaitFor_TI
mov SBUF, A
ret
prDisplay:
call prWaitFor_TI
mov SBUF, #CR
mov A, R4
call lbDrawElement
mov A, R3
call lbDrawSeparator
mov A, R2
call lbDrawSeparator
call prWaitFor_TI
setb TI
setb IE.4
ret
; ******************************
;Обработчик прерываеий intRi
; записываем символ, введённый с клавиатуры
;**********************
intRi:
jnb RI, RET_COM
clr IE.4
mov A, SBUF
clr RI
call B_check
mov R6, A
call prSetTimeMode_Iteration
call prSmartDelay
setb IE.4
RET_COM:
reti
;; обработчик прерывания intP1:
;; проверяет, нажата ли
клавиша входа в режим
;; Такой клавишей явл. '0' на маленькой клавиатуре
intP1:
; Запрещаем прерывания на время выполнения:
clr IE.7
call prSmartDelay
mov P1, #00DFh
mov A, P1
cjne A, #00D7h, stop_check
setb fmode
stop_check:
mov P1, #00EFh
mov A, P1
cjne A, #00E7h, play_check
clr TR0
play_check:
mov P1, #007Fh
mov A, P1
cjne A, #0077h, lbNot_SetTime_Mode
setb TR0
lbNot_SetTime_Mode:
call prSmartDelay
mov P1, #00001111b
setb IE.7
reti
prSetTimeMode_Iteration:
clr IE.4
mov A, R0
mov B, #2
div AB; в А - целая часть, в В - остаток
mov R1, A
mov A, B
cjne A, #0, lbSetTimeMode_Iteration_LO
;;Загружаем десятки в регистр:
mov A, R6
mov B, #10h
mul AB
mov @R1, A
jmp lbSetTimeMode_Iteration_
lbSetTimeMode_Iteration_LO: ;;Загружаем единицы в этот же регистр:
mov A, @R1
add A, R6
mov @R1, A
call prCorrect_SS; корректируем секунды (R2)
call prCorrect_MM; корректируем минуты (R3)
call prCorrect_HH; корректируем часы (R4)
lbSetTimeMode_Iteration_
call prDisplay; выводим вводимое время на экран
inc R0; увеличили указатель на регистры
cjne R0, #10, lbSetTimeMode_Iteration_End
clr fMode; - устанавливаем режим счёта
lbSetTimeMode_Iteration_End: ret
; ||||||||||||||||||||||||||||||
;; процедура prShowMessage:
;; выводит на экран текстовое сообщение; символ ESC - признак конца сообщения
prShowMessage:
clr A
movc A, @A + DPTR
lbNextSymbol:
call prWaitFor_TI
mov SBUF, A
inc DPTR
clr A
movc A, @A + DPTR
cjne A, #ESC, lbNextSymbol
ret
; ******************************
; ******************************
; ПОДПРОГРАММЫ_ВСПОМОГАТЕЛЬНЫЕ
; //////////////////////////////
;; процедуры prCorrect_SS, prCorrect_MM, prCorrect_HH:
;; проверяют соответствующие
регистры на корректность