Министерство образования и науки Российской Федерации

Московский государственный институт электроники и математики

Кафедра ЭВА

Курсовая работа

по дисциплине «Микропроцессорные системы»
на тему «Цифровые часы с установкой»

Выполнили студенты группы С-85:

Руководитель:

Москва 2007

Техническое задание. 3

Блок-схема. 5

Листинг. 6

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

Техническое задание

Разработать программу для микроконтроллера на базе МП Intel 8051, реализующую функциональность электронных часов и имеющую следующие особенности:

- поддержка двух режимов работы программы: а) режим счёта; б) режим установки времени;

- в режиме счёта на дисплей терминала выводится текущее время в формате hh:mm:ss, где , , ;

- в режиме установки времени выполняется последовательный ввод значений двузначных регистров, начиная с ss, причём в каждом регистре сначала задаётся значение десятков, а затем единиц. На этапе ввода значений регистров должна производиться проверка корректности задаваемых чисел и, в случае их выхода за пределы допустимого для регистра диапазона значений, — коррекция до верных значений.

Ввод необходимо осуществлять с помощью стандартной шестнадцатикнопочной терминальной клавиатуры.

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

Особенности выполнения курсового проекта

Ввод цифр для настройки часов производится с матричной 16-ти кнопочной клавиатуры.

НЕ нашли? Не то? Что вы ищете?

Все сигналы матричной клавиатуры приходят на порт P 1, имеющий адрес 90H.

Программа начинается с глобального разрешения прерываний, далее идет выполнение зацикленной процедуры хода часов. По возникновению прерывания от порта P1 осуществляется переход к подпрограмме проверки нажатия клавиши входа в режим установки времени. Подпрограмма работает в фоновом режиме. При нажатии клавиши перехода к режиму установки выполняется установка флага fMode в 1 (0 – режим счета, 1 – режим установки), подпрограмма установки и коррекции введенных данных, при этом таймер T0, отвечающий за ход часов, останавливается.

Опрос клавиатуры осуществляется после возникновения прерывания (по биту P1.0, P1.1 или P1.3), сначала определяется в каком столбце осуществляется нажатие клавиши, далее определяется сама клавиша. Вывод осуществляется записью в буфер кода ASCII соответствующего данному значению.

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

Блок-схема.
Листинг

;13.05.2007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Требуется: выводить на экран время в формате "hh:mm:ss". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ;;;; ОПИСАНИЕ ПЕРЕМЕННЫХ: ;;;;   ;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" - режим установки времени   fIntP1 equ 20h.1; было активировано прерывание по P1; ; надо выставить этот флаг, подождать немного, а затем убрать флаг. ; Причём следующее прерывание можно обрабатывать ТОЛЬКО ПОСЛЕ снятия этого флага.   ; ***** ; ***** ; ОПИСАНИЕ ТОЧЕК ВХОДА ОСНОВНОЙ ПРОГРАММЫ и ПОДПРОГРАММ ПРЕРЫВАНИЙ   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     ; ***** ; ***** ; ОСНОВНАЯ ПРОГРАММА ; выполняет функции: ; - настройку прерывания и таймера ; - настройку таймера и установку начальных ; значений (b(H) b(L)) ; - останавливает таймер   lbMain:   ; конфигурируем таймер T0: anl TMOD, #0F0h; обнуляем младшую тетраду orl TMOD, #01h; младшую тетраду приводим к виду "0001" ;mov TMOD, #b; - то же самое clr TR0; остановка таймера T0 (таймер - не считает)   ; настраиваем систему прерываний: mov IP, #0; (IP0) все прерывания (пока) - с одинаковым низким уровнем приоритета mov 0F8h, #0; (IP1) mov IE, #b; IEN0: выставили биты EA(7),ES(4),ET0(1) mov 0E8h, #b; IEN1: выставили биты 0,1,3 mov P1, #b mov 0EBh,#b; (CTCON) разрешаем прерывания по битам P1 по фронту и срезу ;задаём начальное время: mov R2, #00; секунды mov R3, #00; минуты mov R4, #00; часы   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, #b setb IE.7   setb TR0; запускаем таймер (таймер - считает). Пошло инкрементирование T0   lbCountMode_Loop: nop; если не добавить пустой оператор, то будет "каша"   ; проверяем бит режима, и выполняем соответствующий переход: 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, #b setb IE.7   lbSetTimeMode_Loop: nop   ; проверяем бит режима, и выполняем соответствующий переход: jnb fMode, lbCountMode jmp lbSetTimeMode_Loop   ; ***** ; ***** ; ПОДПРОГРАММЫ_ОСНОВНЫЕ   ; ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ;; процедура intTF0:   intTF0: clr TF0; сбрасываем бит переполнения ВРУЧНУЮ! djnz TimerRepeat, lbTF0_End;   ; реализация собственно "хода" часов: inc R2 cjne R2, #60, lbTF0_Next1 mov R2, #0 inc R3 cjne R3, #60, lbTF0_Next1 mov R3, #0

147. inc R4

cjne R4, #24, lbTF0_Next1 mov R4, #0   lbTF0_Next1: mov TimerRepeat, #13 lbTF0_End: call prDisplay reti   ; ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ;; процедура prDisplay:   lbDrawSeparator: call prWaitFor_TI mov SBUF, #3Ah;   ;; переводим значение из A в кодировку ACSII и выводим на экран: lbDrawElement: mov B, #10 div AB add A, #30h call prWaitFor_TI mov SBUF, A mov A, B add A, #30h call prWaitFor_TI mov SBUF, A ret   prDisplay:   ;[начало вывода 9 символов]   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; иначе - программа "зависнет" ;[конец вывода 9 символов]   ret   ; ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ;; обработчик прерывания intP1: ;; проверяет, нажата ли клавиша входа в режим установки времени. ;; Такой клавишей явл. '0' на маленькой клавиатуре   intP1: ; Запрещаем прерывания на время выполнения: mov 0E8h, #b clr 0C8h.0 clr 0C8h.1 clr 0C8h.2 clr 0C8h.3   jnb fMode, lbP1_CountMode ;;I. ПРЕРЫВАНИЕ ИЗ РЕЖИМА УСТАНОВКИ ВРЕМЕНИ: call prSmartDelay call prCheckNumKeys   cjne R7, #0FFh, lbP1_CountMode_KeyPressed jmp lbP1_SetTimeMode_Finalize   lbP1_CountMode_KeyPressed: call prSetTimeMode_Iteration   lbP1_SetTimeMode_Finalize: jmp lbP1_End   ;;II. ПРЕРЫВАНИЕ ИЗ РЕЖИМА СЧЁТА: lbP1_CountMode: call prSmartDelay call prCheckNumKeys cjne R7, #9, lbP1_End setb fMode   lbP1_End: call prSmartDelay mov P1, #b mov 0E8h, #b reti     prSetTimeMode_Iteration: mov A, R0 mov B, #2 div AB; в А - целая часть, в В - остаток mov R1, A mov A, B   cjne A, #0, lbSetTimeMode_Iteration_LO ;;Загружаем десятки в регистр: mov A, R7 mov B, #10 mul AB mov @R1, A jmp lbSetTimeMode_Iteration_Finalize   lbSetTimeMode_Iteration_LO: ;;Загружаем единицы в этот же регистр: mov A, @R1 add A, R7 mov @R1, A call prCorrect_SS; корректируем секунды (R2) call prCorrect_MM; корректируем минуты (R3) call prCorrect_HH; корректируем часы (R4)   lbSetTimeMode_Iteration_Finalize: 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   ; ***** ; ***** ; ПОДПРОГРАММЫ_ВСПОМОГАТЕЛЬНЫЕ   ; /////////////////////////////////////////////////////////////////////////// ;; процедуры prIs_R2_more_59, prIs_R3_more_59, prIs_R4_more_23: ;; проверяют соответствующие регистры на корректность значений в них; ;; большие значения уменьшаются до ближайших верных   prCorrect_SS: cjne R2, #59, lbR2_not_59 ret lbR2_not_59: jnc lbR2_more_59 ret lbR2_more_59: mov R2, #59 ret   prCorrect_MM: cjne R3, #59, lbR3_not_59 ret lbR3_not_59: jnc lbR3_more_59 ret lbR3_more_59: mov R3, #59 ret   prCorrect_HH: cjne R4, #23, lbR4_not_23 ret lbR4_not_23: jnc lbR4_more_23 ret lbR4_more_23: mov R4, #23 ret   ; /////////////////////////////////////////////////////////////////////////// ;; процедура prSmartDelay: ;; небольшая задержка, за время которой на клавиатуре успевает ;; завершиться "переходной процесс"   prSmartDelay: mov B, #0 mov A, #0 lbSmartDelay_Loop: djnz ACC, $ djnz B, lbSmartDelay_Loop ret   ; /////////////////////////////////////////////////////////////////////////// ;; процедура prWaitFor_TI: ;; ожидание "готовности передачи" по последовательному порту   prWaitFor_TI: jnb TI, $; зациклить, пока TI=0 clr TI ; устанавливаем "неготовность передачи" ret   ; /////////////////////////////////////////////////////////////////////////// ;; процедура prCheckNumKeys: ;; опрос цифровых клавиш. ;; Процедура помещает в регистр R7 номер нажатой клавиши '0'..'9' или ;; #0ffh, если ничего не нажато   prCheckNumKeys:   mov R7, #0FFh; допустим, что ничего не будет нажато   ;опрос первого столбца клавиш: lbKey_1: mov P1, #00DFh mov A, P1   cjne A, #00DDh, lbKey_2 mov R7, #1 ret   lbKey_2: cjne A, #00DEh, lbKey_3 mov R7, #2 ret   lbKey_3: cjne A, #00D7h, lbKey_4 mov R7, #3 ret   ;опрос второго столбца клавиш: lbKey_4: mov P1, #00EFh mov A, P1 cjne A, #00EDh, lbKey_5 mov R7, #4 ret   lbKey_5: cjne A, #00EEh, lbKey_6 mov R7, #5 ret   lbKey_6: cjne A, #00E7h, lbKey_7 mov R7, #6 ret   ;опрос третьего столбца клавиш: lbKey_7: mov P1, #007Fh mov A, P1   cjne A, #007Dh, lbKey_8 mov R7, #7 ret   lbKey_8: cjne A, #007Eh, lbKey_9 mov R7, #8 ret   lbKey_9: cjne A, #0077h, lbKey_0 mov R7, #9 ret   ;опрос четвёртого столбца клавиш: lbKey_0: mov P1, #00BFh mov A, P1   cjne A, #00BDh, lbEnd_Exam_NumKeys mov R7, #0 lbEnd_Exam_NumKeys: ret   ; ***** ; ***** ; ОПИСАНИЕ ТЕКСТОВЫХ СООБЩЕНИЙ:   msgSetTimeMode: db LF, LF, CR, '-= Rejim Ustanovki: =-', CR, LF, ESC msgShowTimeMode: db LF, LF, CR, '-= Tekushee Vremya: =-', CR, LF, ESC   END;;;; КОНЕЦ ПРОГРАММЫ

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

Курс лекций по дисциплине «Микропроцессорные системы» Микроконтроллеры семейства MSC-51 и др. пособия кафедры. , , . ОДНОКРИСТАЛЬНЫЙ МИКРОКОНТРОЛЛЕР 80C552. Методическое пособие по курсу «Схемотехника и программное обеспечение электронных средств измерений» для студентов, обучающихся по направлению «Информатика и вычислительная техника». М.: Издательство МЭИ, 2001.