|
|
|
|
DWD: Радио №8, 2000г., стр.30 Спасибо, вечером посмотрю! |
|
|
to Левон: диодов в схеме picmaniac 3, на трех выходах, для защиты от выжигания выводов порта при двух нажатых кнопках, когда образуется КЗ между выводами с нулем и единицей. еще там 4 резистора на входах, на мой взгляд лишних - защищать входы не от чего, а 220 ом по сравнению с 50 ком на внутренних подтягивающих ничего и не дадут. так что три выхода и четыре входа с тремя диодами и 12 кнопок. В результате контроллер сможет однозначно определить ситуации: - ничего не нажато - нажата одна и какая - нажато две и какие - нажато больше двух, но уже не известно каких Программно два последних варианта можно и не обрабатывать (считать в этих случаях, что нажато 0 ), а кнопки на клавиатуре нажимать одним пальцем |
|
|
ну вот, первая программа для PIC готова оцените в программе реализовал: - считывание кода с клавиатуры 4 строки 3 столбца и вывод его на семисегментный индикатор с общим анодом (не уверен в правильности названия - вроде анод это "минус", а здесь общий "плюс") (клавиатуру подключил к PORTB, индикатор к PORTA) - сделал модель для протеуса (даже три, с разным количеством диодов) - работает (глюки в моделях без и с 4-я диодами при нажатии трех и более клавиш объясняются фантомами - программную защиту делать не стал, наоборот, хотел, чтобы принимались символы каждой нажатой клавиши (это давняя мечта - так надоела блокировка компьютерной клавиатуры в играх )) - при чтении клавиатуры: -- учтен дребезг контактов -- "*" - обнуляет уже введенный код -- "#" - завершает ввод кода без набора установленного в программе количества символов -- цифровые кнопки - ввод символа - вроде неплохое описание всех ассемблерных инструкций (на описание потратил столько-же, сколько и на программу ) Программа работает по алгоритму: - опрос клавиатуры и заполнение 8 разрядных буферов для каждой клавиши - если в буфере появилось B'11111111' - значит восемь циклов назад была нажата клавиша - записываем или обрабатываем символ - если B'00000000' - клавиша была отпущена В 194 строке устанавливается количество вводимых символов = от 1 до 16 (сейчас 6). Если нужно больше 16, надо добавить регистров ОЗУ для их хранения. В 226 строке стоит задержка между выбором считываемой строки. При текущей задержке время выполнения основного цикла примерно 1 секунда. В результате можно поэкспериментировать с дребезгом контактов. Для нормальной работы эту задержку нужно убрать.
42357.rar |
|
|
Солидно. Достаточно сложно. Хорошие комментарии. Я тут немного поразмыслил над техзаданием. Если делать по предложенной мною http://www.pic16.nm.ru/likbez2/ButtonMatrix5.gif схеме с тремя диодами, то идея возникла такая - зарезервировать в ОЗУ контроллера 3 регистра (к примеру, С1, С2, С3 их назвать). Затем настроить RB4-RB7 на вход, RB1-RB3 на выход. Выставлять поочередно лог.0 на выходах RB1, RB2, RB3 и считывать состояние входов PORTB. Сохранять состояние входов в регистрах С1, С2, С3 для первого, второго и третьего столбца соответственно. При этом лог.1 в старших полубайтах будут соответствовать отпущенным кнопкам, лог.0 - нажатым. Затем можем проинвертировать эти регистры и "забить нулями" их младшие полубайты при помощи лог.И (andlw или andwf). Получим такую картину - три регистра, старшие полубайты которых содержат информацию о нажатых кнопках, а младшие полубайты нули. Причем после инверсии отпущенной кнопке будет соответствовать лог.0 в бите регистра, а нажатой - лог.1. С1 = |_*_|_7_|_4_|_1_|0|0|0|0| С2 = |_0_|_8_|_5_|_2_|0|0|0|0| С3 = |_#_|_9_|_6_|_3_|0|0|0|0| _1_ - так я обозначил соответствие битов кнопкам. Далее потребуется обработать эти данные и выдать результат в одном байте. Для подсчета количества нажатых кнопок можем использовать еще один зарезервированный заранее регистр (к примеру, назовем его KEYCOUNTER). А результат будем помещать, к примеру, в регистр с названием KEYRESULT. Обнуляем эти регистры заранее. Проверяем поочередно каждый из 12 бит в старших полубайтах регистров С1, С2, С3. Если бит=0, то ничего не делаем, переходим к следующему биту. А если бит=1, то инкрементируем KEYCOUNTER. Если этот равный единице бит соответствует одной из цифровых кнопок 0-9, то записываем в регистр KEYRESULT соответствующее число (для кн."1" - единицу, для "9" - девятку, для "0" можем либо 0, либо 10 записывать). Если же нажата кн. "*", то устанавливаем в 1 бит KEYRESULT,4. А если нажата "#" - то устанавливаем в 1 бит KEYRESULT,5. Таким образом появляется возможность устанавливать любой приоритет при нажатии нескольких цифровых кнопок (вдруг потребуется). После проверки всех 12 бит смотрим - какое число в регистре KEYCOUNTER (сколько кнопок было одновременно нажато). Если число больше 3, то записываем туда 3. И переносим это число в два старших бита регистра KEYRESULT. В итоге получаем в регистре KEYRESULT результат опроса клавиатуры. В младшем полубайте содержится число, соответствующее старшей (условно старшей - мы сами её выбираем) из нажатых цифровых кнопок. Биты 4 и 5 содержат информацию о состоянии кнопок * и # соответственно. Биты 6 и 7 содержат число одновременно нажатых кнопок (от 0 до 3, а случай больше 3 нам неинтересен). Представленный в таком виде результат удобен для последующего анализа, в том числе и для вывода на индикатор. Всё вышеописанное - лишь моё ИМХО и предложение. |
|
|
можно и так, т. е. 3 выхода (RB1, RB2, RB3) с диодами – столбцы и 4 входа (RB4, RB5, RB6, RB7) с резисторами – строки но я бы все таки предложил сделать 4 выхода на RB0, RB1, RB2 и RB3 с диодами и 3 входа на RB4, RB5 и RB6 вот почему: - входы RB4 - RB7 можно использовать для прерываний от внешних устройств, а RB0 - RB3 нет (в результате – применительно к варианту "кодовый замок" – на свободный RB7 в будущем например можно поставить геркон входных дверей, по которому начнется отсчет времени, отведенного на ввод кода) - к выходам RB можно без проблем подключить кроме клавиатуры любые другие устройства, ко входам – не все (например, если это будет семисегментный индикатор, то нажатия кнопок всего лишь исказят отображаемый код – зажгут лишние сегменты. Если это будет цифровое устройство – результат может быть неожиданным ) В результате на клавиатуру мы фактически теряем всего три линии вместо четырех и освобождаем одну, по которой возможно прерывание. Затем, с получением кода клавиши в одном регистре согласен, но есть предложение по модификации способа его получения: - 3 и более одновременно нажатых клавиш не обрабатывать – ждать пока лишние будут отпущены. К примеру если будут нажаты “*” + “#” + “7” какую из четырех (“*”, “#”, “7” или “9”) считать фантомом? - 2 обрабатывать только если это “*” + “цифра” или “#” + “цифра” - 1 обрабатывать После все цифровые клавиши запоминать в массиве. Можно ограничиться 8 регистрами ОЗУ, по одному символу в регистре (первые 4 бита – цифра плюс 4-ый и 5-ый – клавиши “*” и “#”) Затем нужен сам алгоритм работы клавиатуры, я предлагаю: - цифра – запись символа в массив - “*” – очистка массива - “#” – конец ввода и действия с введенным кодом (проверка или что-то еще) - достижение предустановленного количества знаков в коде – то-же, что и “#” Вывод кода на индикатор предлагаю делать сразу. В качестве индикатора можно использовать два 4-ех значных семисегментных (итого 8 знаков), и фактически постоянно выводить туда массив символов (можно организовать по прерыванию от таймера). Используя дешифратор и регистр или счетчик (правда две лишние микросхемы, ну и с дешифраторами пока не работал, лишь догадываюсь об их существовании) можно ограничиться 6 выводами МК – 4 RB0-RB3 на дешифратор и два от RA на регистр
|
|
|
к выходам RB можно подключить кроме клавиатуры любые другие устройства, ко входам – не все picmaniac, приношу извинения - смысл резисторов наконец-то дошел действительно, можно подключить и цифровые устройства, единственно, чтобы они не срабатывали без участия МК от нажатия клавиш, пока RB4-RB7 настроены как входы поэтому, можно принять ваше ТЗ
|
|
|
Alex73, да какие извинения, о чём речь! Приятно иметь дело с единомышленником! Жаль, у меня сейчас времени нет на контроллеры. Вчера часик всего лишь покумекал. А для внешних прерываний специальный вход есть - RB0/INT, я его в схеме клавиатуры не задействовал. Нам бы для начала совместно написать и отладить фрагмент кода для опроса клавиатуры и помещения результата в один байт. Желательно с составлением графа и алгоритма - для лучшего понимания, это всё же ликбез. Такое моё предложение. А потом уже будем решать - как результат дальше обрабатывать и на что выводить. |
|
|
составил алгоритм почти по ТЗ: - по трем и более клавишам зацикливание на начало, т. е. пока не отпустят лишние - две проходят, только если это "*"&"цифра" или "#"&"цифра", иначе зацикливание на начало - ноль - зацикливание на начало - есть защита от дребезга - задержка 10 ms и повторное считывание - цифры имеют код от 0 для нуля до 9 для девяти - "*", если нажата одна, имеет код 10 - "#", если нажата одна, имеет код 11 - перед завершением стоит проверка "изменилось ли состояние клавиатуры", и если нет - зацикливание на начало т. е. на выходе в KeyResult имеем всегда новое состояние клавиатуры: 6 и 7 биты - количество нажатых клавиш = 1 или 2 5 бит - если установлен, нажата "#" 4 бит - если установлен, нажата "*" 0 - 3 биты - код цифры, или если цифра не нажата, решетки (11) или звездочки (10) ну как? |
|
|
вот сам файл с алгоритмом |
|
|
извиняюсь, сразу после отправки заметил ошибку в рисунке, и так два раза вот алгоритм; вроде на этот раз рабочий
|
|
|
|
|