Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2530
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2028
∙ повысить рейтинг »
vladisslav
Статус: 7-й класс
Рейтинг: 1303
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1384
Дата выхода:21.11.2010, 09:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:223 / 66
Вопросов / ответов:1 / 1

Вопрос № 180784: Необходимо провести опрос клавиатуры - нажать две кнопки, потом вывести числа на индикатор. Микропроцессор 8051 Интересуют примеры, литература. ...



Вопрос № 180784:

Необходимо провести опрос клавиатуры - нажать две кнопки, потом вывести числа на индикатор.
Микропроцессор 8051
Интересуют примеры, литература.

Отправлен: 16.11.2010, 08:37
Вопрос задал: Serg90 (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Serg90
Вот Вам программа. Несколько моментов:
1) секундная пауза реализована, как 20 раз прерываний по 50мс.
Возможно, потребуется подправить константу, т.к. пауза будет фактически чуть больше 1 сек
2) там же, в прерывании идет декремент введенного числа
3) прерывание запускается только после ввода 2-х цифр числа
4) вывод числа на индикаторы - в основном цикле, причем старшая тетрада идет на 7Seg2
поэтому будут выводиться и все промежуточный значения, N, N-1, N-2,...,0 (так, по-моему, нагляднее)
5) при сканировании клавиатуры считаем, что активным является 0 (выбор линии и результат нажатия)
Код:
;значения для загрузки таймера
TIMER0_H equ high(65 535-50000)
TIMER0_L equ low (65535-50000) ;=50000mks=50ms
INT_COUNT equ 20 ;число прерываний 20*50ms = 1sec
NUM_COUNT equ 2 ;число цифр
DEB_COUNT equ 100 ;число проверок для устранения дребезга клавиатуры

org 0 ;начало
jmp Start ;переход на основную работу

org 0bh ;адрес вектора 0 таймера
jmp _timer0 ;переход на отработку

Start:
mov r0, #0 ;введенное число
mov r1, #NUM_COUNT ;число цифр и одновременно - номер ожидаемой цифры
; (2-старшая, 1-младшая)

mov r7, #INT_COUNT ;число прерываний таймера, чтобы получить 1 секунду

mov tmod,#01h ;Таймеp/счетчик T0 - 16-битный таймеp
mov th0,#TIMER0_H ;Загpузим таймер значением для первого режима
mov tl0,#TIMER0_L
mov ie,#82h ;Разpешить пpеpывание от таймеpа 0 + вообще разрешить

DigitsLoop: ;цикл сканирования и вывода н а индикаторы
mov p0, r0 ;на индикаторы
cjne r1, #0, KeyScan ;если не 0, то на сканирование клавиатуры
jmp DigitsLoop ;если введены две цифры (дошли до 0), то не сканируем
; а только декрементируем число до нуля (в прерывании)
; и выводим на индикаторы
KeyScan:
call scan ;сканируем клавиатуру
cjne a, #0ffh, GetDigit ;если код 0-0fh, то вставляем код в нужное место числа
jmp DigitsLoop ;0ffh - нет кода - на основной цикл

GetDigit: ;нажата клавиша
cjne r1, #2, DigitLow ;r1 = 2 - вводим старшую цифру, r1 = 1 - младшую
swap a ;старшую цифру - в старшую тетраду
DigitLow:
orl a, r0 ;вставляем в число hex цифру
mov r0, a ;сохраняем
djnz r1, DigitsLoop ;r1 = r1 - 1 и на основной цикл
;r1 = 0 - ввели обе цифры
setb tr0 ;запуск таймеpа T0 - начинает работать прерывание
jmp DigitsLoop ;на основной цикл

_timer0: ;прерывание от 0 таймера
c lr tr0 ;Остановим таймеp
push psw ;сохраним PSW

djnz r7, start_timer ;считаем прерывания, если не дошли до 0, то на перезапуск
mov r7, #INT_COUNT ;прошло 1 сек, переинициализируем счетчик прерываний

cjne r0, #0, dec_number ;если наше число не 0, то не декремент
mov r1, #NUM_COUNT ;если 0, то счет закончился, ждем 2 новые цифры
jmp exit ;на выход без перезапуска таймера

dec_number:
dec r0 ;декремент нашего числа

start_timer: ;перезапуск таймера
setb tr0 ;Запуск таймеpа 0
exit: ;выход из прерывания
mov th0, #TIMER0_H ;Пеpезагpузка
mov tl0, #TIMER0_L ;таймеpа 0 для режима 0
pop psw ;восстановим регистр PSW
reti

scan: ;сканируем клавиатуру
mov r2,#4 ;четыре линии
mov r3,#11111110b ;маска сканкода для выбора линии p1.0 - p1.3
mov r4,#0 ;база группы кнопок 0, 4, 8, 12
sc an_loop: ;цикл сканирования линий
mov p1,r3 ;вывод сканкода
mov a,p1 ;читаем код клавиши из p1.4 - p1.7
swap a ;код в acc.0 - acc.3
anl a,#0fh ;сбросим незначащие биты
cjne a,#0fh,debounce ;если есть нажатие, идем на устранение дребезга
jmp next ;нет нажатия - на следующую линию сканирования

debounce: ;устранение дребезга
mov r5,a ;сохраним код
mov r6,#DEB_COUNT ;число циклов проверки дребезга
debounce_loop: ;цикл проверки дребезга
mov a,p1 ;читаем код
swap a
anl a,#0fh
cjne a,5,next ;если не равен сохраненному (r5 нулевого банка),
; то на следующее сканирование
djnz r6,debounce_loop ;проверяем DEB_COUNT раз
;клавиша нажата!
wait_off: ;подождем отпускания клавиши
mov a, p1 ;читаем код
swap a
anl a,#0fh
cjne a,#0fh,wait_off ;ждем отпускания
;сформируем из кода вида 00001101b число r4 + 1
mov r2,#4 ;число бит
mov a,r5 ;сканкод кнопки
conv_loop:
rrc a ;циклически выдвигаем младший бит в C
jnc scan_ret ;0 - число посчитано
inc r4 ;инкремент
djn z r2,conv_loop ;4 раза
scan_ret:
mov a,r4 ;результат - код клавиши 0-0fh
ret

next: ;переходим на следующую линию сканирования
inc r4 ;база для следующей линии клавиш (по 4 кнопки в линии)
inc r4
inc r4
inc r4
mov a,r3 ;маска
rl a ;циклически сдвигаем (перемещаем 0 бит влево)
mov r3,a
djnz r2,scan_loop ;по всем линиям
mov a,#0ffh ;ничего не нажато
ret

end

-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 19.11.2010, 12:32
Номер ответа: 264202
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Оценка ответа: 5
Комментарий к оценке:
Спасибо!

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 264202 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.23 от 18.11.2010

    В избранное