Вариантов борьбы с дребезгом кнопок много. Я расскажу о программном способе с задержкой, генерируемой таймером и прерыванием.
При нажатии кнопки в цикле проверяется нажата ли кнопка необходимое количество миллисекунд (переменная 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.
При нажатии кнопки в цикле проверяется нажата ли кнопка необходимое количество миллисекунд (переменная 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.
Комментариев нет:
Отправить комментарий