/*****************************************************
Project : Freq_Counter
Version : 1.0
Date    : 21.09.2007
Author  : Panda                     
Frequnsy counter

Chip type           : ATtiny2313
Clock frequency     : 20,000000 MHz
Memory model        : Tiny
Data Stack size     : 32
*****************************************************/

#include <tiny2313.h> 
#include <delay.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>

//Global vaiable defination
char dg[10] = {'0','1','2','3','4','5','6','7','8','9'};
char fq[12];     
unsigned char k_div;
 
unsigned long freq;

void display(void)
{//Вот тут будем отображать измеренные значения частоты      
 unsigned long tmp =0, tmp1=0;
 unsigned char _cnt=0;
 tmp = freq/1000; 
 for (_cnt = 12; _cnt > 0; _cnt--)
        fq[_cnt]=0;
 _cnt=10;
 while (tmp > 0)
 {
   tmp1 = tmp;
   tmp1 = tmp1/10;
   fq[_cnt] = dg[tmp-tmp1*10];
   _cnt--;
   tmp = tmp1;
   };
 lcd_clear();
 lcd_gotoxy(0,0); 
 lcd_putsf("F(kHz)=");
 lcd_puts(fq+_cnt+1); 
 lcd_putsf(".");
 
 _cnt = 0;
 tmp = freq/1000; 
 tmp = freq-tmp*1000;
 tmp = tmp/10;
 for (_cnt = 12; _cnt > 0; _cnt--)
        fq[_cnt]=0;
 _cnt=10;
 while (tmp > 0)
 {
   tmp1 = tmp;
   tmp1 = tmp1/10;
   fq[_cnt] = dg[tmp-tmp1*10];
   _cnt--;
   tmp = tmp1;
   };
 lcd_puts(fq+_cnt+1); 
 
}            

//Timer1 compare service routine
interrupt [TIM1_COMPA] void _timer1_compare_subroutine_ (void)
{
//все остановим, измерение закончено,
//отобразим результат
//подготовимся к следующему измерению и все повторим
TCCR1B  = 0x00;         //остановим счетчик
TCCR0B  = 0x00;         //остановим счетчик
freq    = freq + TCNT0; //добавим к значению частоты то что осталось в счетчике
freq = freq * 50;
//freq = freq/1000;
display();              //отобразим результат
TCNT0   = 0x00;         //сбросим счетчик
freq    = 0x00000000;   //Сбросим значение частоты для начала следующего измерения
TCNT1   = 0x0000;  
TCCR1B  = k_div; //установим  Кдел
TCCR0B  = 0x07; //Разрешим тактирование таймера 0 с внешнего входа по нарастаю-
}

//Timer0 overflow service routine
interrupt [TIM0_OVF] void _tovf0_ (void)
{
freq = freq + 0xFF + 1;
}

void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif    
PORTD=0x7C;
DDRD=0x7E;
TCCR1A=0x00;
TCCR1B=0x00;
GIMSK = 0;
EIFR=0x00;
TIMSK=0x00;
lcd_init(16); 
#asm("sei")
lcd_putsf("Hello...");
while ((PIND &0x01) == 1); 
TIMSK = 0x42;    //TOIE0, OCIE1A 
TCNT0   = 0;     //сбросим счетчик
TCNT1   = 0x0000;
TCCR0B  = 0;     //остановим счетчик
OCR1A   = 62500; //Установим регистр сравнения таймера 1 (16 бит)
freq    = 0;     //очистим значение частоты
k_div = 0x03;    //k div = 64, t=3.2mks
TCCR1B  = k_div; //
TCCR0B  = 0x07; //Разрешим тактирование таймера 0 с внешнего входа по нарастаю-

while (1)
      {
        // Power off
        if ((PIND & 0x01) == 1)
           PORTD = 0x22;
      };
}
