Я уже рассматривал в статьях ранее работу микроконтроллера с кнопками, где решалась проблема дребезга с помощью 74HC14.

Теперь попробую подобную кнопку, но без 74HC14 соединить с контроллером и обрабатывать нажатия кнопки с помощью прерывания.

Схема кнопки апаратно подавляет дребезг и представлена: 1) резистором 100К 2) резистором 10К 3) емкостью 100nF

Работа кнопки расписана ранее, при нажатии кнопки происходит коммутация источника питания через резистор на вход, емкость выступает фильтром. При размыкании кнопки происходит коммутация входа контроллера на землю.

Выход данной конструкции соединен с портом PD2 контроллера ATMega8, который настроен как вход.

Вот код обслуживающий прерывания от кнопки:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>

#define SetBit(x,y) (x|=(1<<y))
#define ClrBit(x,y) (x&=~(1<<y))
#define ToggleBit(x,y) (x^=(1<<y))
#define FlipBit(x,y) (x^=(1<<y)) // Same as ToggleBit.
#define TestBit(x,y) (x&(1<<y))

#define _BV(bit) (1 << (bit))

#define BUTTON_STOP_MOTOR PD2
#define MOTOR_STOP_LIGHT PC5

#define MOTO_FLAG _BV(0)
uint8_t button_flags = 0;

ISR(INT0_vect){
    button_flags = button_flags ^ 1;
}

uint8_t prev_flag = 0;

void doMotorLight(){
    if (prev_flag != button_flags){
        if (button_flags & MOTO_FLAG){
            SetBit(PORTC, MOTOR_STOP_LIGHT);
            } else {
            ClrBit(PORTC, MOTOR_STOP_LIGHT);
        }
        prev_flag = button_flags;
    }
}

int main(void)
{
    //включаем вход для чтения кнопки PD2
    ClrBit(DDRD, BUTTON_STOP_MOTOR);
    ClrBit(PORTD, BUTTON_STOP_MOTOR);
    //включаем выход, для управления диодом PC5
    SetBit(DDRC, MOTOR_STOP_LIGHT);
    PORTC = 0;
    prev_flag = button_flags;
    //Садим кнопку на прерывание
    SetBit(GICR, INT0);
    //Конфигурируем прерывание на переход 0->1
    MCUCR |= _BV(ISC01) | _BV(ISC00);
    sei();
    while (1)
    {
        doMotorLight();
        _delay_ms(20);
    }
}

Особого внимания заслуживает участок кода

  //Садим кнопку на прерывание
    SetBit(GICR, INT0);
    //Конфигурируем прерывание на переход 0->1
    MCUCR |= _BV(ISC01) | _BV(ISC00);
    sei();

Здесь активируется внешнее прерывание по линии INT0 и устанавливается поведение порта, т.е генерировать прерывание при переходе 0-1.

При желании это поведение можно изменить, сделать срабатывание на любое изменение уровня входящего сигнала.

При дететкте нажатия, через ножку PC5 диод загорается или гаснет.

Ниже приведен видеоотчет о работе схемы:

Добавить комментарий

Следующая запись Предыдущая запись