Консультация № 183006
30.04.2011, 18:55
56.38 руб.
0 12 1
Здравствуйте! У меня возникли сложности с таким вопросом:
К ОМК 8051 подключены клавиатура 3х4, ЖК-индикатор HD-44780, двигатель постоянного тока.
В исходном состоянии на ЖКИ выведено: |_|_|_|_|о|б|/|м| - в пустых отображается скорость работы двигателя в об/м.
Организовать ШИМ модулятор с частотой 8кГц, скважность примерно 1/25. На клавиатуре 10 цифр от 0 до 9.
Пользователь вводит данные - скорость работы двигателя, который отображается на ЖКИ, в соответствии с этими данными происходит изменение скважности в ШИМе и изменяется скорость работы двигателя.
Желательно продемонстрировать работу в САПР Proteus или Pinnacle 52

Обсуждение

давно
Посетитель
7438
7205
30.04.2011, 20:35
общий
Здравствуйте.
Как насчет схемы? Как прикажете управлять всеми этими устройствами: клавиатурой, ЖКИ, двигателем...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
30.04.2011, 21:11
общий
1) Кроме того, какой скорости соответствует скважность 1/25, 1?
2) Клавиатуру сканировать, это понятно, но какими разрядами и какого порта?
3) Каков протокол управления ЖКИ? Опять же, какими портами управлять?
4) Двигателем, допустим, управлять не надо, подключен напрямую...
Короче, требуется дополнительная информация...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
30.04.2011, 22:23
общий
30.04.2011, 22:29
1) Минимальная скорость 10 об/м - скважность 1/25, максимальная 1000 об/м - скважность примерно 0,8
2) Использовать порт P1: Настроить линии Р1.4 – Р1.6 на ввод данных.
Организовать на линиях Р1.0 – Р1.3 циклический регистр сдвига (рекомендуется сдвиг влево) и в каждом такте контролировать состояние линий Р1.4 – Р1.6.
3) Про протокол не знаю пока, можно использовать последовательный канал
4) двигатель можно не подключать вообще, а подключить осциллограф и посмотреть его на показания
давно
Посетитель
7438
7205
30.04.2011, 23:47
общий
HD-44780 не работает по последовательному каналу...
Ладно, я подумаю, попробую что-то слепить.
"Ввяжемся в драку", а там разберемся.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.05.2011, 08:43
общий
помогите хотя бы со сканированием клавиатуры
давно
Посетитель
7438
7205
05.05.2011, 10:36
общий
Я работаю... Если все сложится, то сегодня сделаю.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
05.05.2011, 10:52
общий
05.05.2011, 10:52
Кстати, определитесь с тем, как у Вас подключен ЖКИ.
Насколько я знаю, возможна работа по 4- или 8-битной шине...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.05.2011, 16:03
общий
по 8-битной шине
Неизвестный
05.05.2011, 17:06
общий
спасибо
давно
Посетитель
7438
7205
05.05.2011, 17:17
общий
Чуток подправил:
По кнопке сброса раньше все останавливалось, что неправильно.
Сейчас, как и предполагалось, просто сброс самого числа на индикаторе, модулятор же продолжает работать.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
05.05.2011, 17:24
общий
это ответ
Здравствуйте, BVSV!
Вот и программа.
Я сделал следующие предположения:
1) Для работы с ЖКИ сигналы RS заведен на A1, а R/W на A0
В результате для адресации регистров и операции используются два младших бита адреса
Для отличия от обычной памяти я предположил использовать старший бит адреса.
2) Кроме цифр остаются еще две клавиши, которые я предлагаю использовать следующим образом:
левая нижняя - для очистки числа, 0 приведет к останову,
правая нижняя - для отработки введенного числа
Причем младшую цифру я игнорирую, т.к. она лишняя.
3) для выхода я использую бит p1.7

Период у нас получается 125 мкс
Скважность меняется от 1/25 до 80/100 = 20/25 или от 5 мкс до 100 мкс (получается, что макс 1000 надо делить на 10)
Реальные цифры Вы увидете только на осциллографе :)
Для включения/выключения напряжения на выходе используются два таймера.
Один включает, второй выключает...

[code h=200];регистры ЖКИ
;конкретные адреса задавайте сами.
;важны только два младших бита
;предполагается, что 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

;строка с цифрами
obM_0 equ 30h ;младший
obM_1 equ 31h
obM_2 equ 32h
obM_3 equ 33h ;старший

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 ;код в acc.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
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
05.05.2011, 17:25
общий
Чего-то я вместо ответа в мини-форум поместил... Заработался...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа