пятница, 22 мая 2015 г.

Избавление от дребезга контактов 1

Вариантов борьбы с дребезгом кнопок много. Я расскажу о программном способе с задержкой, генерируемой таймером и прерыванием.


При нажатии кнопки в цикле проверяется нажата ли кнопка необходимое количество миллисекунд (переменная delay). Если да, то кнопка считается нажатой.

Данный код актуален как минимум для AtmelStudio и микроконтроллера Attiny2313 с частотой 4 МГц с кнопкой на ножке PD6.

#include <avr/io.h>
/*подключим заголовочный файл для использования прерываний*/
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>

#define F_CPU 4000000UL

/*задержка в миллисекундах*/
unsigned int delay = 100;
int t1 = 0;

char push = 0;

/*обработка прерывания по переполнению счётчика T0*/
ISR (TIMER0_OVF_vect)
{
  t1++;
}

int main (void)
{
     /*настраиваем порт D как вход*/
DDRD = 0x00;
PORTD = 0xFF;
     /*настраиваем порт B как выход*/
DDRB = 0xFF;
PORTB = 0x00;

 /*источник тактирования таймера T0 - внутренный генератор без делителя*/
TCCR0B = 0b00000001;
/*сбрасываем счётчик T0*/
TCNT0 = 0x00000000;

int count = (F_CPU/1000) * delay/255;

 /*общее разрешение прерываний*/
sei ();

 /*отключение прерывания по переполнению таймера T0*/
TIMSK |= (0<<TOIE0);

while(1)
{
while (bit_is_set (PIND, 6))     //пока нажата кнопка на PD6
{
TIMSK |= (1<<TOIE0); //разрешение прерывания по переполнению таймера T0

if (t1>count)
{
push = 1;
TIMSK |= (0<<TOIE0);
t1=0;
}
}
 
  t1 = 0;
 
  if (push == 1)
{
               /*инвертирование состояния порта B*/
PORTB = ~PORTB;
push = 0;
}
}
}

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

Комментариев нет:

Отправить комментарий