Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Периферия » Управление МК с клавиатуры


Управление МК с клавиатуры

Сообщений 1 страница 14 из 14

1

Ну подскажите люди добрые суть проблемы:
к МК подключена клавиатура 4х4 , с PD5 ПОСРЕДСТВОМ КЛАВИАТУРЫ задается выходное напряжение через RC цепочку до 9 вольт в принципе без проблем, а далее
требуется при нажатии клавиши 1 и 0 , на выходе должно 10, если 0 и 1 соответственно 0,1 и т.д. т.е от 0,1 до 30 посредством чего ума пока не приложу, может кто нечто подобное делал или где может ссылкой поделитесь...

Код:
$crystal = 16000000
$regfile = "m32def.dat"
'*******************************************************************************
'                              Конфигурация
'*******************************************************************************
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2
Config Int1 = Falling                                       'INT0 - по заднему фронту
Config Portd.5 = Output
Config Portd.3 = Input
Set Portd.3
Key_1 Alias Portd.3
'*******************************************************************************
'                                Переменные
'*******************************************************************************
 'Dim Keycodes(12) As Byte
Dim Wtime As Byte                                           'время задержки
Dim Keycoderow As Byte                                      'код строки &B
Dim Keycodecol As Byte                                      'код столбца &B
Dim Keycode As Byte                                         'код позиции в таблице Keycodes
Dim Keychar As String * 2                                   'код кнопки (номер нажатой кнопки)
Dim U As Byte
Dim Temp As Byte
Dim Temp2 As Byte
Const Debouncetime = 15                                     'Задаем константу 150 мс
'*******************************************************************************
'                            обьявление процедур
'
'*******************************************************************************
 Declare Sub U_i_set()                                      ''
 Declare Sub Isobra()
'*******************************************************************************

'*******************************************************************************
'                              начало прграммы
'*******************************************************************************
Enable Interrupts                                           'разрешить все прерывания
Enable Int1                                                 'разрешить внешнее прерывание 0

On Int1 Button                                              'вектор внешнего прерывания 0
Ddrb = &B11110000                                           'старшая половина порта на выход, младшая - на вход
Portb = &B00001111                                          'установим высокий уровень по входу
Wtime = 255                                                 'Задержка 255 мс
Start Adc
'------------------------основной цикл программы------------- ------------------
 Maincicle:
 Do
Call U_i_set                                                ' установка напряжения и тока
Call Isobra                                                 ' вывод изображения
Loop
 End
'-------------------------------------------------------------------------------
'                                    процедуры
'-------------------------------------------------------------------------------

'*********************подпрогр установки ШИМ напряж и тока**********************
Sub U_i_set()

  Pwm1a = U
  Select Case Keycode                                       'Начинаем выбор переменной Keycode
  Case 0 : U = 20                                           '1 '10V-204 Если Keycode = 0, U равен 20
  Case 1 : U = 41                                           '2'20V-408
  Case 2 : U = 61                                           '3'30V-613
  Case 4 : U = 82                                           '4'817
  Case 5 : U = 102                                          '5'1023
  Case 6 : U = 123                                          '6
  Case 8 : U = 143                                          '7
  Case 9 : U = 164                                          '8
  Case 10 : U = 184                                         '9
  Case 13 : U = 0                                           '10
   End Select

End Sub
'*******************************************************************************
 Wej1:
 Do
If Key_1 = 0 Then
        Waitms 1 : If Key_1 = 1 Then Goto Wej1              ' Защита от помехи

'Led = 1

       Temp2 = 0
        If Key_1 = 0 Then
             For Temp = 0 To 250
                 Incr Temp2 : If Temp2 > 214 Then Goto Dolgoe_uderzhanie       ' На долгое удержание
                 If Key_1 = 1 Then Exit For                 ' Выходим из цикла подсчета времени удержания кнопки
                 Waitms 14
             Next
        End If


       For Temp = 0 To 99                                   ' Проверка на нажатие кнопки второй раз
           If Key_1 = 0 Then Goto Dvojnoe_nazhatie
           Waitms 2
      Next


    Goto Odinochnoe_nazhatie                                ' Одиночное нажатие


    'Led = 0
 End If

    My_end:
     Waitms 100

Loop
Odinochnoe_nazhatie:
Goto U_i_set
Dvojnoe_nazhatie:

 Dolgoe_uderzhanie:
'*************************подпрграмма вывода на дисплей*************************
Sub Isobra()
Cursor Off

      Locate 1 , 1
      Lcd Keychar
End Sub

'*****************  подпрограмма обработки прерывания клавиатуры ***************
Button:

Keycoderow = Pinb                                           'опросим ноги порта B и определим, на которой низкий уровень
Waitms Debouncetime                                         'задержка 150 мс
'---------- поменяем назначение входов/выходов половин порта  ------------------
  Ddrb = &B00001111                                         'старшая половина порта на вход, младшая - на выход
  Portb = &B11110000                                        'установим высокий уровень по входу

  Waitms 1                                                  'выждем антидребезг
  Keycodecol = Pinb                                         'определим, в каком столбце низкий уровень

'---------------- вернем состояние порта к первоначальному ---------------------
  Ddrb = &B11110000                                         'старшая половина порта на выход, младшая - на вход
  Portb = &B00001111                                        'установим высокий уровень по входу

'------------ получим код клавиши исходя из полученных значений ----------------
  Select Case Keycoderow                                    'Выбрать действие в зависимости от
    Case 7 : Keycode = 12                                   'значения переменной Keycoderow
    Case 11 : Keycode = 8                                   'находим в какой позиции строки нажата клавиша
    Case 13 : Keycode = 4
    Case 14 : Keycode = 0
    Case Else : Keycode = 99
  End Select
  Shift Keycodecol , Right , 4                              'считываем позицию из столбца, возвращаем символы строки справа
  Select Case Keycodecol
    Case 7 : Keycode = Keycode + 3
    Case 11 : Keycode = Keycode + 2
    Case 13 : Keycode = Keycode + 1
    Case 14 : Keycode = Keycode + 0
    Case Else : Keycode = Keycode + 99
  End Select
'------------------- неверный код клавиши из-за дребезга...  -------------------
  If Keycode > 15 Then Keycode = 16                         'при дребезге отображаем "?"
  Keychar = Lookupstr(keycode , Keycodes)                   'находим номер нужной кнопки
            'Возвращает значение из таблицы строковых данных (keycode , Keycodes)
  Gifr = 64                                                 'сотрем дребезговое прерывание 0 из  регистра Gifr
Return

End

'*******************************************************************************
'Преобразование кода клавиши в соответствующий символ находится в блоке данных Keycodes.
'Если в вашей клавиатуре иное расположение клавиш, достаточно изменить блок данных.
'*******************************************************************************
Keycodes:
Data "1" , "2" , "3" , "A" , "4" , "5" , "6" , "B" ,
Data "7" , "8" , "9" , "C" , "R" , "0" , "E" , "D" , "?"
'Restore Keycodes                                            'Указать блок DATA для считывания оператором READ
 'For Keycode = 1 To 12                                      'Определение цикла с переменным параметром
 'Read Keycodes(keycode)                                     'Считать данные из секции DATA
 'Next Keycode

Отредактировано amv2000 (2011-05-11 13:43:08)

0

2

Если бы описание было не на тарабарском языке, легче было разобраться.

У меня матрица 4х4 подключена к порту 'C' ATMega64, 4 линии выход, 4 - вход.
Function Read_keyb() As Byte - проверка нажатия клавиши.
Function Wait_keyb() As Byte - чтение кода клавиши.
Sub Conv_key() - преобразование в нужный формат.

Код:
Function Read_keyb() As Byte
  Portc = $f0
  Waitus 10
  Read_keyb = Pinc And $0f
  Portc = $00
End Function

Function Wait_keyb() As Byte
Local R As Byte , C As Byte
 Do
  C = $10
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $20
  Portc = C
  Waitus 100
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $40
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $80
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
 Loop
  Wait_keyb = R + C
  Waitms 10
End Function

Sub Conv_key()
  Select Case K
    Case $18 : K = "*"
    Case $12 : K = "#"
    Case $88 : K = "1"
    Case $84 : K = "2"
    Case $82 : K = "3"
    Case $48 : K = "4"
    Case $44 : K = "5"
    Case $42 : K = "6"
    Case $28 : K = "7"
    Case $24 : K = "8"
    Case $22 : K = "9"
    Case $14 : K = "0"
    Case $81 : K = "A"
    Case $41 : K = "B"
    Case $21 : K = "C"
    Case $11 : K = "D"
  End Select
End Sub

В основном цикле проверяю нажата клавиша или нет.
Если нажата, читаю код и обрабатываю его.

Код:
K = Read_keyb()
  If K > 0 Then

    K = Wait_keyb()
    Call Conv_key()
    If K = "4" Or K = "6" Then ......
    If K = "*" Then .....
    If K = "#" Then .....
 
      Waitms 100
    End If

  End If

В программе "*" у меня вместо "Enter", а "#" вместо "Esc".
В данном случае нужно дождаться нажатия двух цифровых клавиш.
обработать результат и записать в ШИМ,

0

3

А чтобы не было тарабарского языка, нужно копировать текст при включенной русской раскладке.

0

4

Уже "теплее". Спасибо!
В подпрограмме Sub U_i_set() можно напрямую выводить значение в ШИМ.
(Первый код клавиши * 10) + второй код клавиши. Для диапазона 0-99.
А можно испоьзовать доп. клавиши "A,B,C,D" для выбора нужного диапазона.

0

5

Вы имеете ввиду так
Sub U_i_set()

  Pwm1a = U
  Select Case Keychar                                       'Keycode                                     
  If Case 1 * 10 Or Case 0 Then U = 941
  Case 0 : U = 20                                           '1 '10V-204
  Case 1 : U = 41                                           '2'20V-408
  Case 2 : U = 61                                           '3'30V-613
  Case 4 : U = 82                                           '4'817
  Case 5 : U = 102                                          '5'1023
  Case 6 : U = 123                                          '6
  Case 8 : U = 143                                          '7
  Case 9 : U = 164                                          '8
  Case 10 : U = 184                                         '9
  Case 13 : U = 0                                           '10
   End Select

End Sub
вылазит куча ошибок, надо в начале программы переделывать.
В Протеусе набросал может понятнее будет.
А у Вас прерывание используется? вроде обработка клавиш похожа, но не совсем -по куску кода не очень понял...

Отредактировано amv2000 (2011-05-11 21:05:37)

0

6

Клавиатура опрашивается в основном цикле и в
подпрограммах, где она нужна.
Вот накидал по быстррому.

Код:
$crystal = 8000000

$regfile = "m64def.dat"

Declare Function Read_keyb() As Byte
Declare Function Wait_keyb() As Byte
Declare Sub Conv_key()


Dim A As Byte , B As Byte , K As Byte
Dim Kd As Byte , Ke As Byte , Key As Byte

Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
Config Lcd = 20 * 4
Config Timer2 = Pwm , Async = Off , Prescale = 1 , Compare = Set , Pwm = On
Ocr2 = 0

Cursor Off Noblink
Cls
Waitms 10

Portc = 0
Ddrc = $f0
Ddrb.7 = 1

Do

   K = Read_keyb()
   If K > 0 Then

    K = Wait_keyb()
    Call Conv_key()
    Kd = K * 10
    Waitms 100
Wkey:
    K = Read_keyb()
    If K = 0 Then Goto Wkey
    K = Wait_keyb()
    Call Conv_key()
    Ke = K
    Key = Kd + Ke


    Ocr2 = Key
    Locate 4 , 1
    Lcd Str(key)
    Waitms 300

   End If

Loop

'===============================================================================
Function Read_keyb() As Byte
  Portc = $f0
  Waitus 10
  Read_keyb = Pinc And $0f
  Portc = $00
End Function

Function Wait_keyb() As Byte
Local R As Byte , C As Byte
 Do
  C = $10
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $20
  Portc = C
  Waitus 100
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $40
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
  C = $80
  Portc = C
  Waitus 10
  R = Pinc And $0f
  If R > 0 Then Exit Do
  Waitus 100
 Loop
  Wait_keyb = R + C
  Waitms 10
End Function

Sub Conv_key()
  Select Case K
    Case $18 : K = "*"
    Case $12 : K = "#"
    Case $88 : K = 1
    Case $84 : K = 2
    Case $82 : K = 3
    Case $48 : K = 4
    Case $44 : K = 5
    Case $42 : K = 6
    Case $28 : K = 7
    Case $24 : K = 8
    Case $22 : K = 9
    Case $14 : K = 0
    Case $81 : K = "A"
    Case $41 : K = "B"
    Case $21 : K = "C"
    Case $11 : K = "D"
  End Select
End Sub

Программа написана "в лоб" без провеки кода нажатой
клавиши. Вводятся две цифры от 0 до 9, первая десятки,
вторая - единицы. Результат число в диапазоне 0-99 выводится
на дисплей и в ШИМ.

0

7

блин, народ! оформляйте код программы в тег "код" - замучился после многих вычищать!
щелкнули по "КОД", между скобками вставьте текст вашей программы
Чтобы русские символы не превращались в кракозяблы выделение кода программы делать при включенной русской раскладке клавиатуры

0

8

Извините исправимся!

Насчет переменных:
Key - это то что мы выводим в ШИМ и LCD(преобразованное число),  K - код клавиши, Kd - код десятичных чисел, Ke - код единиц
А - ?
В - ?
R - ?
С - ?
Вы писали:
Function Read_keyb() As Byte - проверка нажатия клавиши.
Function Wait_keyb() As Byte - чтение кода клавиши.
Может наоборот первое чтение второе проверка?
И схема подключения матрицы какая С0,С1,С2,С3 - строки С4,С5,С6,С7 - столбцы или по другому?

Код:
                                                       C4     C5     C6      C7  
                                                        I      I       I       I
                                                        I      I       I       I
                         C0  I  -----------------  ( 1 )  ( 2 )  ( 3 )  ( А )
                               I
                         C1  I  ---I-------------  ( 4 )  ( 5 )  ( 6  )  ( В )
                               I     I
                         C2  I  ---I------I------  ( 7 )  ( 8 )  ( 9  )  ( С )
                               I     I      I
                         C3  I  ---I------I-----I-  ( * )   ( 0 )  ( # )  ( D )
                             _I_  _I_   _I_ _I_
                              /\    /\     /\    /\
                             Диоды на ногу прерывания

Отредактировано amv2000 (2011-05-12 18:01:54)

0

9

PORTC 0-3 входы и они подтянуты к "земле"  через резисторы 4К7.
Function Read_keyb() As Byte выводит все единицы в старшую
половину и читает младшую. Если нет нажатия то читается 0, если не 0
то нажата клавиша и тогда вызываем Function Wait_keyb() As Byte.
А если необходимо получить от клавиши определённый код то вызываем
Sub Conv_key() . Здесь слева то что читаем из порта, а справа то
что хотим получить.

0

10

Спасибо будем пробовать

0

11

Ребят, а вот меня библиотека баскома заинтересовала с встроенной определялкой клавиши без лишних строк

Config Kbd = Portb
do
B = Getkbd()
print b
loop

На данный код можно подцепить только 16 кнопок (4х4 линии). Меня же интересует 49 кнопок (7х7 линий)! т.е. два порта нужно юзать.
1. Как это сделать? Можно ли к стандартной функции баскома прикрутить больше линий?
2. Питание батарейное. Между нажатиями кнопок камень должен уходить в сон. (пока что придумал 7 линий через диоды пустить на прерывание на остальные подать потенциал типа portd=255)
Охота переделать пульт от телевизора под несколько устройств (в.т. числе и под телек) Энергоэффективность на первом месте.

0

12

Судя из хелпа конфигурации функции - нет, но на немецком форуме было предложение попробовать сделать таким образом:

Код:
Sub Key1
Config Kbd = Porta
A = Getkbd()
B = Lookup(a , Numer_id_1 )
End Sub

Sub Key2
Config Kbd = Portb
A = Getkbd()
b= Lookup(c , Numer_id_2 )
End Sub

Для попробовать...впрочем вроде обещана поддержка только портов B и D...

0

13

RDW написал(а):

Для попробовать...

Не то. Тут задействовано две матрицы   4х4. т.е 16+16 кнопок=32. А если юзать два порта правильно - матрица 8х8 = 64 кнопки.

0

14

alex_r61 спасибо за код. Мне нравится твой вариант из-за отсутствия прерывания, правда при этом цикл удлиняется, но кому как смотря в каких случаях.

0


Вы здесь » Программирование ATMEL в BASCOM. » Периферия » Управление МК с клавиатуры