Вопрос № 183006: Здравствуйте! У меня возникли сложности с таким вопросом: К ОМК 8051 подключены клавиатура 3х4, ЖК-индикатор HD-44780, двигатель постоянного тока. В исходном состоянии на ЖКИ выведено: |_|_|_|_|о|б|/|м| - в пустых отображается скорость работы ...
Вопрос № 183006:
Здравствуйте! У меня возникли сложности с таким вопросом: К ОМК 8051 подключены клавиатура 3х4, ЖК-индикатор HD-44780, двигатель постоянного тока. В исходном состоянии на ЖКИ выведено: |_|_|_|_|о|б|/|м| - в пустых отображается скорость работы двигателя в об/м. Организовать ШИМ модулятор с частотой 8кГц, скважность примерно 1/25. На клавиатуре 10 цифр от 0 до 9. Пользователь вводит данные - скорость работы двигателя, который отображается на ЖКИ, в соответствии с этими данными происходит изменение
скважности в ШИМе и изменяется скорость работы двигателя. Желательно продемонстрировать работу в САПР Proteus или Pinnacle 52
Отправлен: 30.04.2011, 18:55
Вопрос задал: BVSV (Посетитель)
Всего ответов: 1 Страница вопроса »
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, BVSV! Вот и программа. Я сделал следующие предположения: 1) Для работы с ЖКИ сигналы RS заведен на A1, а R/W на A0 В результате для адресации регистров и операции используются два младших бита адреса Для отличия от обычной памяти я предположил использовать старший бит адреса. 2) Кроме цифр остаются еще две клавиши, которые я предлагаю использовать следующим образом: левая нижняя - для очистки числа, 0 приведет к останову, правая нижняя - для отработки введенного числа Причем
младшую цифру я игнорирую, т.к. она лишняя. 3) для выхода я использую бит p1.7
Период у нас получается 125 мкс Скважность меняется от 1/25 до 80/100 = 20/25 или от 5 мкс до 100 мкс (получается, что макс 1000 надо делить на 10) Реальные цифры Вы увидете только на осциллографе :) Для включения/выключения напряжения на выходе используются два таймера. Один включает, второй выключает...
Код:
;регистры ЖКИ ;конкретные адреса задавайте сами. ;важны только два младших бита ;предполагается, что RS заведен на A1, а R/W на A0 IR_WRITE equ 8000h IR_READ equ 8001h DR_WRITE equ 8002h DR_READ equ 8003h
CLEAR equ 01h ;команда
очистки экрана SET_POS_0 equ 80h ;установка позиции 0 SET_POS_4 equ 84h ;установка позиции 4
DEB_COUNT equ 100 ;число проверок для устранения дребезга клавиатуры
org 0 ;начало jmp Start ;переход на основную работу
org 0bh
;адрес вектора 0 таймера setb p1.7 ;включаем на выходе 1 setb tr1 ;запускаем таймер 1 reti
org 1bh ;адрес вектора 1 таймера clr p1.7 ;выключаем сигнал на выходе clr tr1 ;останавливаем таймер 1 reti
Start: mov tmod,#00100010b ;оба таймеpа - 8-битные перегружаемые mov ie,#8ah ;Разpешить пpеpывания от таймеpов + вообще разрешить mov th0,255-125 ;константы для периода 125мк, что соответствует
частоте 8кГц mov tl0,255-125
call display_init ;вывод на экран ob/m с 5 позиции Stop: ;останов clr p1.7 ;выход в 0, останов clr tr0 ;останов таймера 0 clr tr1 ;останов таймера 1 Zero: mov obM_0,'0' ;инициируем строку с цифрами в '0000' mov obM_1,'0' mov obM_2,'0' mov obM_3,'0' MainLoop: call display ;вывод строки на монитор
ScanLoop: ;цикл сканирования клави
атуры call scan ;сканируем клавиатуру cjne a,#0ffh, GetDigit ;если код 0-11, то на анализ кода jmp ScanLoop ;0ffh - нет кода - на цикл сканирования
GetDigit: ;нажата клавиша cjne a,#0ch,CmpEnter ;продолжаем сравнение jmp Zero ;нажата левая нижняя - сброс числа в 0 CmpEnter: cjne a,#0dh,Digit ;нажата цифра? call Calculate ;нажата правая нижняя - изменяем скважность jz Stop ;если ноль, то останавливаем jmp ScanLoop ;на сканирование клавиатуры Digit: ;циклически
вдвигаем цифру mov obM_3,obM_2 ;старшая цифра теряется mov obM_2,obM_1 mov obM_1,obM_0 mov obM_0,a jmp ScanLoop ;на сканирование
Calculate: ;расчет скважности ;преобразуем строку в число (младший разряд игнорируем) mov a,obM_3 ;проверим, чтобы число "входило" в один байт ; (допустимо вообще <= 100) cjne a,#'2',cmp_hi_digit ;проверим старший разряд cmp_hi_digit: jc mul_
hi ;если старший разряд < 2, то все в порядке mov a,#'1' ;иначе меняем на 1 mul_hi: ;формируем число anl a,#
0fh ;преобразуем символ '0'-'9' в число 0-9 mov b,#100 ; mul ab ;сотня mov r2,a ;сохраним mov a,obM_2 anl a,#0fh mov b,#10 mul ab ;десятки add a,r2 mov r2,a mov a,obM_0 anl a,#0fh ;единицы add a,r2 ;все число jz calc_ret ;проверим на 0 cjne a,#101,cmp_max ;проверим на максимальное - 100 cmp_max: jc set_timers ;<= 100 - все в порядке mov a,#100 ;ограничиваемся 100 (1000 об/м) set_timers: ;задаем таймер cpl a inc a ;константа
для срабатывания таймера 1 mov th1,a mov tl1,a setb tr0 ;запускаем таймер 0 calc_ret: ret
scan: ;сканируем клавиатуру mov r2,#4 ;четыре линии mov r3,#11111110b ;маска сканкода для выбора линии p1.0 - p1.3 mov r4,#0 ;база группы кнопок 0, 3, 6, 9 scan_loop: ;цикл сканирования линий mov p1,r3 ;вывод сканкода mov a,p1 ;читаем код клавиши из p1.4 - p1.6 swap a ;код в ac
c.0 - acc.2 anl a,#07h ;сбросим незначащие биты cjne a,#07h,debounce ;если есть нажатие, идем на устранение дребезга jmp next ;нет нажатия - на следующую линию сканирования
debounce: ;устранение дребезга mov r5,a ;сохраним код mov r6,#DEB_COUNT ;число циклов проверки дребезга debounce_loop: ;цикл проверки дребезга mov a,p1 ;читаем код swap a anl a,#07h cjne a,5,next ;если не равен сохраненному (r5 нулевого банка), ; то на следующее сканирование djnz r6,debounce_loop ;проверяем
DEB_COUNT раз ;клавиша нажата! wait_off: ;подождем отпускания клавиши mov a, p1 ;читаем код swap a anl a,#07h cjne a,#07h,wait_off ;ждем отпускания ;сформируем из кода вида 00001101b число r4 + 1 mov r2,#3 ;число бит mov a,r5 ;сканкод кнопки conv_loop: rrc a ;циклически выдвигаем младший бит в C jnc scan_ret ;0 - число посчитано inc r4 ;инкремент djnz
r2,conv_loop ;3 раза scan_ret: mov a,r4 ;код клавиши 0-11 mov dptr,#table ;таблица перекодировки movc a,@a+dptr ;код в соответствии с таблицей ret
next: ;переходим на следующую линию сканирования inc r4 ;база для следующей линии клавиш (по 3 кнопки в линии) inc r4 inc r4 mov a,r3 ;маска rl a ;циклически сдвигаем (перемещаем 0 бит влево) mov r3,a djnz r2,scan_loop ;по всем линиям mov a,#0ffh ;ничего не нажато ret
;таблица
кодов, соответствующих скан-кодам ;размещение, как на телефонной клавиатуре ;1 2 3 ;4 5 6 ;7 8 9 ;c 0 d ;c - сброс ;d - ввод table: db '1','2','3','4','5','6','7','8','9',0ch,'0',0dh
;п/п для работы с ЖКИ WAIT_LCD: ;ожидание готовности mov DPTR,#IR_READ WAIT_BUSY: movx a,@DPTR jb acc.7,WAIT_BUSY ;ждем бит IR.7 ret WRITE_LCD_DR:
;запись байта на ЖКИ mov DPTR,#DR_WRITE movx @DPTR,a acall WAIT_LCD ret WRITE_LCD_IR: ;запись байта в регистр IR mov DPTR,#IR_WRITE movx @DPTR,a acall WAIT_LCD ret display: ;п/п вывода строки цифр mov a,#SET_POS_0 ;позиция 0 acall WRITE_LCD_IR mov r0,#obM_0 ;адресс массива mov r1,#4 ;количество out_num_loop: mov a,@r0 acall WRITE_LCD_DR djnz r1,out_num_loop ret display_init: ;инициализация ЖКИ mov a,#CLEAR ;очищаем
экран acall WRITE_LCD_IR mov a,#SET_POS_4 ;устанавливаем позицию 4 acall WRITE_LCD_IR mov a,#'o' ;выводим сообщение acall WRITE_LCD_DR mov a,#'b' acall WRITE_LCD_DR mov a,#'/' acall WRITE_LCD_DR mov a,#'m' acall WRITE_LCD_DR ret
end
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 05.05.2011, 17:24
Номер ответа: 266993 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 266993
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.