«Железные» переключатели Num Lock и Caps Lock
← Вернуться обратноПрошивка [полтора KB, zip]
1. Что нам понадобится.
- собственно, клавиатура (я взял Microsoft MultiMedia Keyboard 1.0)
 - 3 маломощных транзистора (p-n-p или n-p-n зависит от клавиатуры, я взял КТ315Б)
 - 3 резистора с сопротивлением 5,1—15 кОм
 - 3 резистора 2,2—10 кОм (их сопротивление должно быть меньше, чем у предыдущих раза в потора)
 - 3 резистора 2,2—5,1 кОм (зависит от клавиатуры, иногда вообще не требуются)
 - микроконтроллер с 9-ю свободными ножками (я взял PIC16F628A)
 - программатор контроллера (я пользуюсь PonyProg)
 - пара достаточнно прямых рук ;)
 
2. Приступим.
Для начало надо разобрать клавиатуру:

Это обычная плёночная клавиатура. На фото как раз видна контактная «решётка». Чтобы достичь нужного мне эффекта можно было бы выкинуть нафиг родной конроллер и поставить на его место свой. Но мне уж очень лень было разбираться в протоколе ps/2 и я решил просто эмулировать нажатие кнопок. Почему всё так сложно? Потому что состояние CapsLock и NumLock задаётся не клавиатурой, а софтом (сначала BIOS’ом, потом ОС, а потом — любой другой прогой).
Теперь разберёмся как же она всё-таки работает.

На пересечении горизонтальных и вертикальных проводов стоят кнопки. На горизонтальные линии контроллер по очереди подаёт либо высокий, либо низкий логический уровень (зависит от клавиатуры), потом читает состояние вертикальной линии.
Теперь нам надо найти, к каким линиям подключены всякие Lock’и. Делается это с помощью мультиметра (или, в крайнем случае, батарейки с лампочкой ;).

Далее припаиваем провода к найденным линиям на плате:

Также не забываем и про светодиоды (с обратной стороны платы), и питание с землёй (на разъёме):

3. Собираем схему.
Чтобы «изобразить» нажатие кнопки, поставим параллельно ей транзистор. Какой транзистор ставить и как — зависит от клавиатуры. С помощью мультиметра меряем разность потенциалов между двумя линиями, подключёнными к одной из кнопок. Чтобы транзистор не «замкнул» всю линию, надо подключать его эмиттер к выходу родного контроллера, а коллектор — ко входу.

Пробуем сначала припаять транзистор одной из полярностей (например, n-p-n), и подаём на его базу логическую 1 с шины питания (для n-p-n надо брать 0 с «земли»). Если у нас «нажалась» эта кнопка — всё нормально, мы угадали ;) Если же перемкнулась вся линия (комп в этом случае начинает жалобно пищать) — надо поменять полярность транзистора.
К базе транзистора будет подключён контроллер. Вот, собственно, вся схема:

[пояснения]
Припаиваем транзисторы параллельно остальным интересующим нас кнопкам. И собираем всю остальную схему.

И последними можно припаять сами выключатели (ради которых всё это и затевалось ;)

4. Программа контроллера.
Теперь нам надо написать прогу для контроллера, которая будет следить за состоянием светодиодов и тумблеров. И в случае несоответствия «нажимать» кнопку. Для написания и компиляции прошивки нам нужен будет MPLAB.
Сама программа очень простая, вот её текст:
        LIST P=16F628A, R=DEC               ; Use the PIC16F628 and decimal system 
        errorlevel 1
        #include <P16F628A.INC>             ; Include header file 
        __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CP_OFF & _MCLRE_OFF
                                            ; we use internal oscillator, and do not use watchdog
        CBLOCK 0x20
            lamps
        ENDC
        org 0
                goto PROG_START
        org 4
                retfie                      ; we don't use interrupts    
            
do_sleep macro                              ; macro for sleep some amount time
    local _dec
                movlw 0xFF
                movwf cntr
_dec:           nop
                nop
                nop
                nop
                nop
                nop
                nop
                decfsz cntr
                goto _dec
                endm
;---------------------------------------
; Program start
;---------------------------------------
PROG_START
                banksel 0
                movlw 7 
                movwf CMCON                 ; CMCON=7 set comperators off 
  
                clrf PORTA
                clrf PORTB
                banksel TRISA
                movlw b'00001111'           ; 1 means input
                movwf TRISA             
                movlw b'11110000'           ;
                movwf TRISB 
                banksel INTCON
                clrf INTCON
                banksel PCON
                bcf PCON, OSCF              ; we operate at low-speed inernal oscillator
                                            ; 48kHz approximately
                banksel 0
                movfw PORTB
                bcf OPTION_REG, NOT_RBPU    ; weak pull-up on portb
      
chk0:           swapf PORTB, W              ; Caps Lock
                xorwf PORTA, w
                andlw B'00000001'
                btfsc STATUS, Z
                goto chk1
                bsf PORTB, 0
                do_sleep
                bcf PORTB, 0
                do_sleep
chk1:           swapf PORTB, W              ; Num Lock
                xorwf PORTA, w
                andlw B'00000010'
                btfsc STATUS, Z
                goto chk2
                bsf PORTB, 1
                do_sleep
                bcf PORTB, 1
                do_sleep
chk2:           swapf PORTB, W              ; F Lock
                xorwf PORTA, w
                andlw B'00000100'
                btfsc STATUS, Z
                goto endchk
                bsf PORTB, 2
                do_sleep
                bcf PORTB, 2
endchk:         do_sleep
                goto chk0
                
        end
Уже скомпиленная программа находится в архиве.
Чтобы её «прошить» в контроллер, нам нужен программатор, и софт для него. Я использую PonyProg. Хотя вам рекомендую воспользоваться более простым программатором. Т.к. для pony необходимо довольно большое количество внешних компонентов, да и контроллеры он умеет прошивать не все.
Если вы всё-же рискнули воспользоваться pony, то для прошивки понадобится этот скрипт (сохраните его, как e2s-файл).