#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define	F_CPU				(16000000)		// Частота кварца
#define	TIMER0_FREQ			(1000)			// желаемая частота таймерного прерывания
#define	TIMER0_PRESCALER	(64)			// прескалер таймера

// вычисление величины, которую надо загрузить в таймер для получения частоты TIMER0_FREQ
#define	TIMER0_RELOAD_LO	((0xFFFF-(F_CPU/TIMER0_PRESCALER/TIMER0_FREQ)+1) & 0xFF)
#define	TIMER0_RELOAD_HI	((0xFFFF-(F_CPU/TIMER0_PRESCALER/TIMER0_FREQ)+1) >> 8)

// проверка, что 8-битного таймера хватает.
#if (TIMER0_RELOAD_HI!=0xFF)
#error TIMER0_RELOAD_HI!=0xFF!
#endif

// до скольки считать при подавлении дребезга
// (не знаю, сколько у нас антидребезг. Пусть 100мс)
#define DEBOUNCE_CNT	(100)

// ByteBits: Объединение для битовой маски.
// Позволяет обратиться как к целому байту, так и к отдельным битам.
// То есть, для переменной flags типа ByteBits:
//  - весь байт:	flags.byte,
//  - бит 0:		flags.bits.FL_JB_1
//  - бит 1:		flags.bits.FL_OK_1
// Можно обойтись без этого, но так лучше читается.
typedef union
{
    unsigned char	byte;
    struct
    {
	    unsigned char	FL_JB_1 :1;		// бит 0
    	unsigned char	FL_OK_1 :1;		// бит 1
	}bits;
}ByteBits;

// Собственно флаги
static ByteBits flags = {0x20};

// Счётчик
static unsigned char counter;

// Прерывание от таймера 0
SIGNAL(SIG_OVERFLOW0)
{
	unsigned char ch;

	TCNT0 = TIMER0_RELOAD_LO;	// Перезагрузка таймера

	ch = PINB & 0x01;			// читаем ногу
	ch ^= flags.byte;			// xor с флагами

	// смотрим результат.
	// "00 - делаем RETI (никто на кнопки не лезет)"

	// "01 - делаем FL_JB_1=0 и RETI (это была помеха,забудем )"
	if (ch == 1)
    {
		flags.bits.FL_JB_1 = 0;
    }

	// "10 - делаем FL_JB_1=1,обнуляем счетчик и на RETI"
    else if (ch == 2)
    {
		flags.bits.FL_JB_1 = 1;
		counter = 0;
    }

	// "11 - делаем +1"
    else if (ch == 3)
    {
		if (++counter == DEBOUNCE_CNT)	// досчитали!
		{
			if (flags.bits.FL_OK_1)	// кнопку нажали (не знаю что делать при этом:-))
			{
				flags.bits.FL_OK_1 = 0;
			}
			else					// кнопку отжали
			{
				flags.bits.FL_OK_1 = 1;
			}
			flags.bits.FL_JB_1 = 0;
		}
    }

}



int main(void)
{
	// Инициализация
//	flags.byte = 0x20;

	TCCR0 = _BV(CS01) | _BV(CS00);	//	prescaler = 64.
  	TCNT0 = TIMER0_RELOAD_LO;		//
	TIMSK |= _BV(TOIE0);

	sei();		// включаем прерывания

	while (1);
}


