Страница 1 из 1

Нажатие кнопки, что я делаю не так?

Добавлено: Пн июн 08, 2015 20:05:30
xterro
Доброго времени суток, играюсь с ПИКом, подключил к нему 3-х цифровой семисегментный индикатор(на порт B) и пару кнопок(порт А: RA0 и RA1).
Залил прошивку, циферка отображается, но не получается обработать нажатие кнопок. Предполагается, что при нажатию на одну кнопку, значение увеличивается, нажимая на другую - уменьшается. Но в реале, при нажатии, значение не увеличивается, а если и увеличивается то как-то через раз. Причём, на уменьшение работает, но уменьшает сразу в 0, а не на 1 как предполагается. Далее код, прошу посмотреть, всё ли в порядке в плане организации работы с кнопкой как таковой, а то может у меня код не правильный в принципе. Порт А от кнопок подтянул к плюсу через резисторы в 5кОм. Может из-за дребезга такое, может какую-нибудь задержку добавить перед проверкой значения порта? :facepalm:

Код: Выделить всё

list      p=16f84a
include "p16f84.inc"
__config  _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC

COUNT_REG equ 0x0d ; регистр, в котором хранится отображаемое число

org 0x00
clrwdt
goto init

init:
    bsf STATUS, RP0
    ; чтобы горели индикаторы, порт В ставим на выход,
    ; порт А - первые выводы на вход(для кнопок), остальное на выход
    clrf TRISB
    
    movlw b'00000011'
    movwf TRISA

    bcf STATUS, RP0

    ; изначально включим все разряды индикатора
    movlw b'11111111'
    movwf PORTB

    ; используется 3 разрядный индикатор, зажгем только первый разряд
    movlw b'00011011'
    movwf PORTA

    ; инициализируем значение счётного регистра
    movlw 0x3
    movwf COUNT_REG

main_loop:
    
    ; проверяем нажатие кнопок, увеличиваем/уменьшаем значение счётчика
    btfss PORTA, 0
    call inc_count

    btfss PORTA, 1
    call dec_count

    ; выводим значение счётчика на индикатор
    movfw COUNT_REG
    call load_digit
    movwf PORTB

    goto main_loop

inc_count:
    ; if COUNT_REG < 0x9 then increase
    
    incf COUNT_REG, F
    return

dec_count:
    ; if COUNT_REG > 0x0 then decrease

    decf COUNT_REG, F
    return


load_digit:
    addwf PCL, F
    retlw b'00111111' ; 0
    retlw b'00000110' ; 1
    retlw b'01011011' ; 2
    retlw b'01001111' ; 3
    retlw b'01100110' ; 4
    retlw b'01101101' ; 5
    retlw b'01111101' ; 6
    retlw b'00000111' ; 7
    retlw b'01111111' ; 8
    retlw b'01101111' ; 9
    retlw b'01000000' ; -

end
P.S. Так же хочу сделать проверку на то, чтобы величина счётчика попадала в диапазон от 0 до 9(чтобы в обработчике не увеличивали счётчик больше необходимого). Погуглил на предмет примера кода, как организовать условие, но так ничего и не понял, xor, sublw - какие-то шаманства с вычитанием или ксором, объясните на пальцах, как организовываются сравнения? :dont_know:

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Пн июн 08, 2015 21:42:27
otest
Может из-за дребезга такое
Именно из-за него. Посмотри у других как это сделать.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 09:43:03
xterro
Т.е перед опросом бита порта (btfss PORTA, 0) нужно сделать задержку на 1-2 микросекунды, этого хватит чтобы пропустить дребезг?
А вообще, практика опроса в главном цикле кнопки это нормально или как-то по иному это делают? (хотя, похоже в моём случае, на pic16f84 другого способа то и нет - внешнее прерывание RB0/INT занят под индикатор)

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 09:52:50
Albert_V
Тут уже кто как делает.
Я, обычно, по таймеру. Ставлю задержку на "нажатие" 5mS, на "отпускание" 50mS.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 11:52:58
Psych
xterro писал(а):А вообще, практика опроса в главном цикле кнопки это нормально или как-то по иному это делают?
Ну если МК больше ниче не делает, то нормально.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 12:07:18
wws63
И ещё замечание по программе:
1. В слове конфигурации вы отключили "собаку"
и тут же в инициализации МК обнуляете регистр - clrwdt.
Далее у вас идёт команда безусловного перехода на метку init, но сама метка находится по следующему адресу. Смысл?
Делайте всё сразу аккуратно, без всяких лишних.... команд. А вот при инициализации МК показать настройку OPTION_REG не помешает, с учетом будущего...

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 12:17:56
xterro
wws63 писал(а):И ещё замечание по программе:
1. В слове конфигурации вы отключили "собаку"
и тут же в инициализации МК обнуляете регистр - clrwdt.
Далее у вас идёт команда безусловного перехода на метку init, но сама метка находится по следующему адресу. Смысл?
Спасибо за замечание, действительно, смысла нет, изначально код брался из какого-то шаблона, видимо просто недосмотрел и забыл выкинуть лишнее :)
wws63 писал(а):И ещё замечание по программе:
А вот при инициализации МК показать настройку OPTION_REG не помешает, с учетом будущего...
Тут не понял, в смысле, в коде, комментарием вывести значение регистра OPTION_REG? Или что имелось ввиду? :dont_know:

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 12:27:08
Albert_V
xterro писал(а):...Тут не понял, в смысле, в коде, комментарием вывести значение регистра OPTION_REG? Или что имелось ввиду? :dont_know:
Изображение

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 17:23:18
pyzhman
xterro писал(а):сделать задержку на 1-2 микросекунды
Мало. Очень мало. Поставьте 10мс.
xterro писал(а):практика опроса
Поскольку структура программы довольна проста, то поставьте в основном цикле программную задержку сразу после main_loop. Но учтите, проверять нужно фронт сигнала с кнопки, т.е. именно момент ее нажатия.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Вт июн 09, 2015 19:32:53
xterro
pyzhman писал(а):Но учтите, проверять нужно фронт сигнала с кнопки, т.е. именно момент ее нажатия.
Тут малость недопонял, что значит фронт сигнала? Ведь мы и так проверяем факт нажатия, т.е бит в регистре порта. Если 0, значит кнопка нажата, иначе отпущена :)

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 01:14:21
Albert_V
xterro писал(а):... что значит фронт сигнала?...
Есть понятия "фронт" и "спад".
Ребята, давайте перед писаниной в теме, пытаться самостоятельно искать в Internet-е смысл незнакомых слов.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 06:29:37
xterro
Это я знаю, я имел ввиду, что значит фронт, применительно к этой ситуации, где тут фронт? :dont_know:

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 08:20:39
Psych
xterro писал(а):Это я знаю, я имел ввиду, что значит фронт, применительно к этой ситуации, где тут фронт? :dont_know:
Переход от 0 к 1.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 10:59:14
Vano79
xterro писал(а):
pyzhman писал(а):Но учтите, проверять нужно фронт сигнала с кнопки, т.е. именно момент ее нажатия.
Тут малость недопонял, что значит фронт сигнала? Ведь мы и так проверяем факт нажатия, т.е бит в регистре порта. Если 0, значит кнопка нажата, иначе отпущена :)
При нажатии 1 -> 0, при отпускании 0 -> 1. Ловить нажатие, т.е. 1->0, получается спад сигнала. pyzhman вас запутал, не?

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 11:29:28
pyzhman
Под понятием фронт подразумевается изменение сигнала. Т.е. переход 1->0 (ниспадающий/отрицательный фронт, он же спад(хе, а если сигнал отрицательный?)) или 0->1(нарастающий/положительный фронт).
Чтобы поймать фронт, нужно сравнить предыдущее состояние кнопки с текущим. Выявили разницу - значит кнопка поменяла состояние.

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Ср июн 10, 2015 11:49:15
xterro
pyzhman писал(а):Под понятием фронт подразумевается изменение сигнала. Т.е. переход 1->0 (ниспадающий/отрицательный фронт, он же спад(хе, а если сигнал отрицательный?)) или 0->1(нарастающий/положительный фронт).
Чтобы поймать фронт, нужно сравнить предыдущее состояние кнопки с текущим. Выявили разницу - значит кнопка поменяла состояние.
Да, теперь понял, спасибо :tea:

Re: Нажатие кнопки, что я делаю не так?

Добавлено: Чт июн 11, 2015 11:14:17
pyzhman
Пожалуйста.