#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define F_CPU 14745600
//index shows number from 0-9 that can be shown in 7segments
char Numbers[] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111};
volatile uint16_t rpm = 0; //Revolution per minute
volatile uint16_t rps=0; //Revolution per second
volatile char DisplayBuffer[8]={0,0,0,0,0,0,0,0};
volatile uint16_t cnttime = 0;
volatile uint16_t count=0; //Main revolution counter
unsigned char ignore = 0; //when 0 counts, when 1 doesn't count
void display(void)
{
unsigned int i;
for( i=0;i<8;i++)
{
PORTD = DisplayBuffer[i];
PORTB = i;
if(PORTD==0)
{
PORTD = ~Numbers[0];
}
_delay_ms(1);
}
}
//prepare numbers for display
void breakup(uint16_t num)
{
unsigned int i=7;
int a=0;
if(num==0)
{
unsigned int h;
for(h=0;h<8;h++)
{
DisplayBuffer[i]=~Numbers[0];
}
}
else
{
while (num!=0)
{
a = num%10;
DisplayBuffer[i]=~Numbers[a];
num=num/10;
i--;
}
}
}
void initSegments(void)
{
DDRD = 0xFF;
DDRB = 0x07;
PORTD = 0xFF;// tung off all segments
PORTB = 0xFF;
unsigned int i;
for( i=0;i<8;i++)
{
PORTD=~Numbers[0];//fill with 0
PORTB=i;
}
}
void initCount(void)
{
DDRD = 0x00;//all ports input
PORTD = 0xFF;
}
void InitTimer(void)
{
TCNT1=0;
TCCR1A = 0x00;
//Timer Clock = 1/256 of sys clock
//Mode = CTC (Clear Timer On Compare)
TCCR1B|=((1<<ICNC1)|(1<<ICES1)|(1<<WGM12)|(1<<CS12)); //prescaler 256 14745600/256=57600
OCR1A=57600; //1s
TIMSK|=((1<<TICIE1)|(1<<OCIE1A));
}
ISR(TIMER1_CAPT_vect)//
{
//CPU Jumps here automatically when pin detect a falling edge
if(ignore==0)
count++;
}
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
ignore = 1;
rps = count;
rpm = rps*60;
cnttime++;
count=0;
}
int main()
{
initCount();
InitTimer();
//Enable interrupts globaly
sei();
while(1)
{
//test to show every 1 sec
if(cnttime==1)
{
TCCR1B &= 0b11111000;//disable timer
initSegments();
unsigned int h;
for(h=0;h<1000;h++)
{
breakup(rps);
display();
}
DDRD = 0x00;
PORTD = 0xFF;
PORTB = 0x00;
cnttime=0;
ignore =0;
initCount();
InitTimer();
}
}
return 0;
}