//chipenable.ru   02.10.09
//adc avr- получение первых результатов
//убираем дребезг

#include <ioavr.h>
#include <intrinsics.h>
 
#define StartConvAdc() ADCSRA |= (1<<ADSC)  

#define KEY_NULL  0
#define KEY_S1    1
#define KEY_S2    2
#define KEY_S3    3
#define KEY_S4    4

//кнопочный буфер
volatile unsigned char KeyBuf = 0;

int main( void )
{
  unsigned char tmp;
  
  //настраиваем порты
  DDRC = 0xff;
  PORTC = 0xff;

  //инициализируем АЦП
  //ион - напряжение питания, выравнивание влево, нулевой канал
  ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
  //вкл. ацп, режим одиночного преобразования, разрешение прерывания, частота преобр. = FCPU/128
  ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);

  //разрешаем прерывания и запускаем преобразование
  __enable_interrupt();
   StartConvAdc();

  //основной цикл программы - опрос кнопочного буфера
  while(1)
  {
    tmp = KeyBuf;
    if (tmp)
    {
      tmp--;
      PORTC = ~(1<<tmp);
    }
    else
      PORTC = 0xff;
  } 
  return 0;
}


unsigned char comp = 0;

#pragma vector=ADC_vect
__interrupt void adc_my(void) 
{
  unsigned char AdcBuf;   
  unsigned char Key;
  static unsigned char LastState;
  
  //считываем старший регистр АЦП
  AdcBuf = ADCH;
  
  //опеределяем в какой диапазон он попал
  if (AdcBuf > 240) 
    Key = KEY_S4;
  else if (AdcBuf > 180) 
    Key = KEY_S3;
  else if (AdcBuf > 120) 
    Key = KEY_S2;
  else if (AdcBuf > 50) 
    Key = KEY_S1;
  else 
    Key = KEY_NULL;
  
  //защита от дребезга и не только. если нажата какая-нибудь кнопка
  //сравниваем совпадают ли текущее состояние и предыдущее
  //если совпадают - проверяем счетчик comp, если нет обнуляем его
  //кнопка считается нажатой если она удерживается в течении 100
  //преобразований АЦП
  if (Key)
  { 
    if (Key == LastState)
    {
      if (comp > 100)
        KeyBuf = Key;      
      else 
        comp++;
    }
    else
    {
      LastState = Key;
      comp = 0;
    }
  }
  else
  {
    comp = 0;
    KeyBuf = KEY_NULL;
    LastState = KEY_NULL;
  }

  //запускаем преобразование и выходим
  StartConvAdc();
}