|
||||||||||||
|
||||||||||||
|
|||||||||
МЕНЮ
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА - РЕФЕРАТЫ - Счетчик обратного отсчетаСчетчик обратного отсчетаКафедра электронно-вычислительной аппаратуры Курсовая работа по дисциплине «Микропроцессорные системы» Тема “Счетчик обратного отсчета”Москва - 2007 ОглавлениеЧтобы определить, нажата или нет какая-либо клавиша-ключ, сначала нужно выставить на линии регистра-защёлки P1, которые соединяет клавиша, разные логические значения. Затем необходимо считать из регистра значения этих линий: если оба бита стали равными «0», то значит, проверяемая клавиша была нажата. Для сокращения процедуры опроса клавиатуры будем делать опрос по «строкам»:
Чтобы просто зафиксировать факт нажатия любой из цифровых клавиш, достаточно выставить в регистр P1 слово #00001111b и ожидать на P1 значение #0000x1xxb, где x{0;1}. Особенностью данной клавиатуры, которую надо учитывать при программировании, является наличие переходного процесса (дребезга) с длительностью в несколько раз большей, чем время машинного цикла ОМЭВМ МК8051: Текст программыORG 8000h;jmp lbMainORG 800Bh;jmp intTF0lbMain:; конфигурируем таймер T0:anl TMOD, #0F0h; обнуляем младшую тетрадуorl TMOD, #01h; младшую тетраду приводим к виду "0001"clr TR0; остановка таймера T0 (таймер - не считает); загружаем старший и младший байты регистра таймера T0 нулями:mov TH0, #0mov TL0, #0; настраиваем систему прерываний:mov IP, #0; все прерывания (пока) - с одинаковым низким уровнем приоритетаmov IE, #10000010b; IEN0: выставили биты EA(7),ES(4),ET0(1);mov 0E8h, #00001011b; IEN1: выставили биты 0,1,3mov P1, #00001111bmov 0EBh,#0FFh;;;;; ОПИСАНИЕ ПЕРЕМЕННЫХ: ;;;;;регистр R0 - единицы;регистр R1 - десятки;регистр R2 - сотни;регистр R3 - тысячи;регистры R4, R5, R6 - для разных промежуточных значений;регистр R7 - буфер для хранения значения нажатой клавиши [#0..#9] или; значения #FFh, если клавиша не нажатаCR equ 0Dh; "возврат каретки"LF equ 0Ah; "перевод строки"ESC equ 1Bh; "конец сообщения"Buf_R0 equ 20hBuf_R1 equ 21hBuf_R2 equ 22hBuf_R3 equ 23h;;;; ТЕЛО ПРОГРАММЫ: ;;;;;задаём начальное время:mov R0, #0;mov R1, #2;mov R2, #1;mov R3, #0;mov Buf_R0, R0mov Buf_R1, R1mov Buf_R2, R2mov Buf_R3, R3mov DPTR, #msgShowTime_Modecall prShowMessage; вывод сообщения msgShowTime_Modesetb TR0mov R4, #13lbMainLoop:nopclr Aadd A, R0add A, R1add A, R2add A, R3jz lbFinalcall prIs_SetTime_Mode;jmp lbMainLoop;call prDelay;;call prDisplay;;call prIs_SetTime_Mode;intTF0:clr TF0djnz R4, lbTF0_End;; реализация обратного отсчёта:dec R0cjne R0, #0FFh, lbTF0_Next1;mov R0, #9dec R1cjne R1, #0FFh, lbTF0_Next1;mov R1, #9dec R2cjne R2, #0FFh, lbTF0_Next1;mov R2, #9dec R3cjne R3, #0FFh, lbTF0_Next1;lbTF0_Next1: mov R4, #13lbTF0_End: call prDisplayretilbFinal:clr TR0mov DPTR, #msgFinalcall prShowMessage;call prIs_SetTime_Mode;jmp $;;;; ОПИСАНИЕ ПРОЦЕДУР: ;;;;;; процедура prDelay:; lb5: mov R5, #1;;; lb3: djnz R6, lb3; djnz R4, lb3; djnz R5, lb3;; ret;; prDelay:; mov R6, #0; mov R4, #0; mov R5, #6; call lb3;; mov R4, #244; (!!!); call lb5;; mov R4, #1; mov R6, #118; (!!!) Это следует менять для подстройки задержки!!!; call lb5;; ret;; процедура prSmartDelay:;; небольшая задержка, за время которой на клавиатуре успевает;; завершиться "переходный процесс"prSmartDelay:mov R6, #0mov R5, #0lbSmartDelay_Loop:djnz R5, $djnz R6, lbSmartDelay_Loopret;; процедура prDisplay:;; [2 на вызов]+[2 на возврат]+[7]+[1]+[1432]=[1444];; переводим значения R0, R1, R2 в кодировку ACSII:lbDrawElement:add A, #30hcall prWaitFor_TImov SBUF, AretprDisplay:call prWaitFor_TImov SBUF, #CR; переводим курсор в начало строки:mov A, R3call lbDrawElementmov A, R2call lbDrawElementmov A, R1call lbDrawElementmov A, R0call lbDrawElementcall prWaitFor_TI; для выравнивания подождём передачи последнего символаsetb TI; [1] иначе - программа "зависнет"ret; [2];; процедура prWaitFor_TI:;; ожидание "готовности передачи" по последовательному портуprWaitFor_TI:jnb TI, $; зациклить, пока TI=0clr TI ; устанавливаем "неготовность пердачи"ret;; процедура prIs_SetTime_Mode:;; [2 на вызов]+[2+1+2+2]=[9];; проверяет, нажата ли клавиша входа в режим установки времени;;; такой клавишей явл. '0'prIs_SetTime_Mode:mov P1, #00BFhmov A, P1cjne A, #00BEh, lbNot_SetTime_Modecall prSetTime; переход в режим установки таймераlbNot_SetTime_Mode:cjne A, #00B7h, lbNotAnyModemov R0, Buf_R0mov R1, Buf_R1mov R2, Buf_R2mov R3, Buf_R3lbNotAnyMode: ret;; процедура prExam_NumKeys:;; опрос цифровых клавишprExam_NumKeys:mov R7, #0FFh; допустим, что ничего не будет нажато;опрос первого столбца клавиш:lbKey_1:mov P1, #00DFhmov A, P1cjne A, #00DDh, lbKey_2mov R7, #1retlbKey_2:cjne A, #00DEh, lbKey_3mov R7, #2retlbKey_3:cjne A, #00D7h, lbKey_4mov R7, #3ret;опрос второго столбца клавиш:lbKey_4:mov P1, #00EFhmov A, P1cjne A, #00EDh, lbKey_5mov R7, #4retlbKey_5:cjne A, #00EEh, lbKey_6mov R7, #5retlbKey_6:cjne A, #00E7h, lbKey_7mov R7, #6ret;опрос третьего столбца клавиш:lbKey_7:mov P1, #007Fhmov A, P1cjne A, #007Dh, lbKey_8mov R7, #7retlbKey_8:cjne A, #007Eh, lbKey_9mov R7, #8retlbKey_9:cjne A, #0077h, lbKey_0mov R7, #9ret;опрос четвёртого столбца клавиш:lbKey_0:mov P1, #00BFhmov A, P1cjne A, #00BDh, lbEnd_Exam_NumKeysmov R7, #0lbEnd_Exam_NumKeys: ret;; процедура prWaitFor_NextKey_Pressed:;; ждёт СЛЕДУЮЩЕГО НАЖАТИЯ, чтобы долгое нажатие не "флудило"prWaitFor_NextKey_Pressed:lbPrevKey_Pressed: call prSmartDelay; чтоб избежать "дребезга" клавиатурыcall prExam_NumKeys;cjne R7, #0FFh, lbPrevKey_Pressed;call prSmartDelay; чтоб избежать "дребезга" клавиатурыlbNo_NextKey_Pressed: call prExam_NumKeyscjne R7, #0FFh, lbNextKey_Pressedjmp lbNo_NextKey_PressedlbNextKey_Pressed: ret;; процедура prSetTime:;; режим установки таймера:prSetTime:clr EAmov DPTR, #msgSetTime_Modecall prShowMessage; вывод сообщения msgSetTime_Modecall prDisplay;регистр R3:call prWaitFor_NextKey_Pressed;mov R3, 07call prDisplay;регистр R2:call prWaitFor_NextKey_Pressedmov R2, 07call prDisplay;регистр R1:call prWaitFor_NextKey_Pressedmov R1, 07call prDisplay;регистр R0:call prWaitFor_NextKey_Pressedmov R0, 07call prDisplaymov Buf_R0, R0mov Buf_R1, R1mov Buf_R2, R2mov Buf_R3, R3mov DPTR, #msgShowTime_Modecall prShowMessage; вывод сообщения msgShowTime_Modesetb EAret;; процедуры prIs_R0_more_59, prIs_R1_more_59, prIs_R2_more_23:;; проверяют соответствующие регистры на корректность значений в них;;; большие значения уменьшаются до ближайших верныхprCorrect_R0:cjne R0, #59, lbR0_not_59retlbR0_not_59: jnc lbR0_more_59retlbR0_more_59: mov R0, #59retprCorrect_R1:cjne R1, #59, lbR1_not_59retlbR1_not_59: jnc lbR1_more_59retlbR1_more_59: mov R1, #59retprCorrect_R2:cjne R2, #23, lbR2_not_23retlbR2_not_23: jnc lbR2_more_23retlbR2_more_23: mov R2, #23ret;; процедура prShowMessage:;; выводит на экран текстовое сообщение; символ ESC - признак конца сообщенияprShowMessage:clr Amovc A, @A + DPTRlbNextSymbol: call prWaitFor_TImov SBUF, Ainc DPTRclr Amovc A, @A + DPTRcjne A, #ESC, lbNextSymbolret;;;; ОПИСАНИЕ ТЕКСТОВЫХ СООБЩЕНИЙ: ;;;;msgSetTime_Mode: db LF,CR, '[Regim ustanovki taymera:]', CR, LF, ESCmsgShowTime_Mode: db LF,CR, 'OBRATNYI OTSCHET...', CR, LF, ESCmsgFinal: db CR, '!!!OBRATNYI OTSCHET ZAKONCHEN!!!:', CR, LF, ESCEND;;;; КОНЕЦ ПРОГРАММЫ |
РЕКЛАМА
|
||||||||||||||||||||
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА | ||
© 2010 |