Московский государственный институт электроники и математики
Кафедра ЭВА
ЛАБОРАТОРНАЯ РАБОТА
по дисциплине “Микропроцессорные системы”
(Вариант )
Выполнили: студенты группы С-74
Воробьев Д. Н.
Баталов А. В.
Проверил:
Гудков Ю. И.
Москва 2007
1. Задание Ввод: -С клавиатуры, подключенной к контроллеру, вводится двоичное число X разрядов. - Используя кнопки 1 и 0 - для ввода двоичного числа, и копки 9 стоп, 2 старт, 5 сброс - клавиатура ПК - вводится двоичное число кнопками 1 и 0 , стоп - кнопка p, сброс - кнопка - r, старт - копка – s. Вывод: Выводить введенное число на экран, после запуска счетчика выводить каждый резултат на новой строке.
2. Исходный код ORG 8000H ;//main()
buffer EQU 020H
buffer_count EQU 021H
timer_count EQU 022H
start_flag EQU 023H
ready_flag EQU 024H
CONST_T0 EQU 4cf6H;//(0xffff) - 50000*11/12мс
SET_FLAG EQU 0
UNSET_FLAG EQU 1
MAX_TIMER_COUNT EQU 020H
START_KEY EQU 2
STOP_KEY EQU 9
RESET_KEY EQU 5
;/* инициализация */
mov buffer, #0
mov buffer_count, #8
mov timer_count, #0
mov start_flag, #UNSET_FLAG
mov ready_flag, #UNSET_FLAG
clr F0;//сброс бита переполнения счетчика
clr RI
mov P1, #0ffh
;/*устанавливаем для таймера mode = {M0=1, M1=0} */
mov A, TMOD
anl A, #0f0H
orl A, #1H
mov TMOD, A
get_p1:
mov R1, start_flag
cjne R1, #SET_FLAG, get_p2
;//если start_flag установлен
call f_timer
get_p2:
call f_get_keyboard
call f_get_symbol
jmp get_p1 ret ;//end main ;/* Возвращает значение считанного с основной клавиатуры символа */
f_get_symbol:
jnb RI, end_get_symbol
mov A, SBUF
call f_get_main_keyboard
clr RI
end_get_symbol:
ret f_get_main_keyboard:
push ACC
cjne A, #'0', gmk_key_1
mov A, #0
jmp gmk_hit
gmk_key_1:
cjne A, #'1', gmk_key_start
mov A, #1
jmp gmk_hit
gmk_key_start:
cjne A, #'s', gmk_key_stop
mov A, #START_KEY
jmp gmk_hit
gmk_key_stop:
cjne A, #'p', gmk_key_reset
mov A, #STOP_KEY
jmp gmk_hit
gmk_key_reset:
cjne A, #'r', end_gmk
mov A, #RESET_KEY
gmk_hit:
call f_key_hit
end_gmk: pop ACC
ret
f_timer:
push ACC jnb TR0, tm_1;//если счетчик не запущен=>запускаем его
jb TF0, tm_1;//когда бит переполнения таймера установлен
jmp end_f_timer
tm_1:
clr TR0;//сброс бита запуска счетчика
mov TH0, #HIGH(CONST_T0)
mov TL0, #LOW(CONST_T0)
clr TF0;//сброс бита переполнения
setb TR0;//запуск счетчика
;/* инкремент счетчика тиков (1 тик = 50мс)*/
mov A, timer_count
inc A
mov timer_count, A
mov R1, timer_count
cjne R1, #20, end_f_timer
;/* если значение счетчика = 20 */
mov timer_count, #0 ;//обнуляем счетчик тиков
mov A, #0AH
call f_print_symbol
mov A, buffer
dec A
mov buffer, A
mov R2, A
call f_print_binary
mov R1, buffer
cjne R1, #0, end_f_timer
;/* если значение буфера == 0 */
clr TR0;//останавливаем таймер
mov DPTR, #WARNING_END
call f_print_warning
mov start_flag, #UNSET_FLAG
mov buffer, #0
mov buffer_count, #0
end_f_timer: pop ACC
ret f_get_keyboard:
LINE_0 equ p1.5
LINE_1 equ p1.4
LINE_2 equ p1.7
LINE_3 equ p1.6
;//цикл опроса клавиатурной матрицы
; mov R1, #4;//инициализация
c0:
mov P1, #0ffh ;//устанавливаем все биты в 1
clr LINE_0 ;//опрашиваем линию 0
mov A, #START_KEY ;//клавиша '2' - используем ее как "пуск"
jnb p1.0, key_hit
mov A, #1 ;//клавиша '1'
jnb p1.1, key_hit
mov A, #STOP_KEY ;//клавиша '9' - используем ее как "стоп"
jnb p1.2, key_hit
mov A, #3
jnb p1.3, key_hit
mov P1, #0ffh ;//устанавливаем все биты в 1
clr LINE_1 ;//опрашиваем линию 1
mov A, #RESET_KEY ;//клавиша '5' - используем ее как "сброс"
jnb p1.0, key_hit
;/* резерв
; mov A, #4
; jnb p1.1, key_hit ; mov A, #7
; jnb p1.2, key_hit ; mov A, #6
; jnb p1.3, key_hit
;*/
mov P1, #0ffh
clr LINE_3
mov A, #0 ;//клавиша '0'
jnb p1.1, key_hit
jmp end_get_keyboard
key_hit:
call f_key_hit
end_get_keyboard:
ret ;/* Функция обрабатывает проинтерпретированное значение клавиши,
; находящееся в A */
f_key_hit: ;//(A - проинтерпретированное значение клавиши)
push ACC
cjne A, #0, not_0
jmp keys_0_1
not_0: cjne A, #1, key_start
keys_0_1:
mov R1, ready_flag
cjne R1, #SET_FLAG, mtb_0
mov ready_flag, #UNSET_FLAG
call f_key_reset
mtb_0:
call f_print_digit
call f_move_to_buffer
jmp hit_end
key_start:
cjne A, #START_KEY, key_stop
call f_key_start
jmp hit_end
key_stop:
cjne A, #STOP_KEY, key_reset
call f_key_stop
jmp hit_end
key_reset:
cjne A, #RESET_KEY, hit_end
call f_key_reset
jmp hit_end
hit_end:
call f_delay
pop ACC
ret ;/* печатает 10-тичные числа*/
f_print_digit:
push ACC
add A, #30h
call f_print_symbol
pop ACC
ret f_key_start:
push ACC mov DPTR, #WARNING_START
call f_print_warning
mov start_flag, #SET_FLAG;
pop ACC
ret f_key_stop:
push ACC
mov DPTR, #WARNING_STOP
call f_print_warning
mov start_flag, #UNSET_FLAG
pop ACC
ret
f_key_reset: push ACC
mov DPTR, #WARNING_RESET
call f_print_warning
mov buffer, #0
mov buffer_count, #8
mov ready_flag, #UNSET_FLAG
mov start_flag, #UNSET_FLAG
pop ACC
ret ;/* Функция помещает в буфер начальное значение счетчика */
f_move_to_buffer:
push ACC
mov R6, A
mov R7, buffer_count
mov A, R7
dec A
mov R7, A
call f_left_shift
mov A, buffer
orl A, R6
mov buffer, A
;/* декремент значения счетчика буфера */
mov A, buffer_count
dec A
mov buffer_count, A
jnz mtb_end ;//если buffer_count == 0 =>
mov A, #0AH
call f_print_symbol
mov R2, buffer
call f_print_binary
mov DPTR, #WARNING_READY
call f_print_warning
mov ready_flag, #SET_FLAG
mtb_end:
pop ACC
ret f_delay:
mov R2, #0bfh
a_2: mov R1, #0ffh
a_1:
nop djnz R1, a_1
djnz R2, a_2
ret
;/* размещаем в программной памяти несколько таблиц констант */
;TAB_LINE_HORIZONTAL: db LINE_4, LINE_5, LINE_6, LINE_7 TAB_LINE_0_KEY_VALUES: db '0', '1', '2','3' WARNING_RESET: db 0AH,'r','e','s','e','t',0AH, ' '
WARNING_START: db 0AH,'s','t','a','r','t',0AH, ' '
WARNING_READY: db 0AH,'r','e','a','d','y',0AH, ' '
WARNING_STOP: db 0AH,'s','t','o','p',0AH, ' '
WARNING_END: db 0AH,'B','O','O','M',0AH, ' ' f_print_warning:
push ACC mov R1, #0
pr_c1:
mov A, R1
movc A, @A+DPTR
call f_print_symbol
mov R2, A
;//инкремент R1
mov A, R1
inc A
mov R1, A
cjne R2, #' ', pr_c1
pr_c2:
;mov A, #'!'
;call f_print_symbol
pop ACC
ret ;/* распечатывает значение R2 в двоичном представлении */
f_print_binary: ;(R2 - число для печати) push ACC
mov R1, #8 ;//инициализация цикла c1:
mov A, R1;//R3 == R1
mov R3, A
mov A, R2
mov R6, A
mov A, R1
dec A
mov R7, A
call f_right_shift
mov A, R6
anl A, #01H; накладываем 1-битную маску
jnz c1_nzero
mov A, #'0' ;//if(A == 0)
jmp c1_endif
c1_nzero: ;//else
mov A, #'1'
c1_endif: ;//endif
call f_print_symbol
djnz R1, c1 pop ACC
ret ;/* печатает символ, находящийся в аккумуляторе */
f_print_symbol:
CLR TI
mov SBUF, A
pr_s:
jnb TI, pr_s ret ; /* сдвигает R6 вправо на {R7} раз */
f_right_shift: ;(R6-число, R7- кол-во раз для сдвига)
push ACC
rs_0:
mov A, R6
rr A
mov R6, A
djnz R7, rs_0
pop ACC
ret;(R6 - результат) f_left_shift: ;(R6-число, R7- кол-во раз для сдвига)
push ACC
ls_0:
mov A, R6
rl A
mov R6, A
djnz R7, ls_0 pop ACC
ret;(R6 - результат)
END
3. Список использованной литературы
1. Конспект лекций и семинаров по дисциплине “Микропроцессорные системы”
2. Э. Каспер “Программирование на языке Ассемблер для i8051” |