add basic tachometer reader

This commit is contained in:
King Kévin 2013-10-13 19:39:31 +02:00
parent e4cb5d1f8f
commit be4f8c64bb
1 changed files with 57 additions and 7 deletions

View File

@ -11,9 +11,14 @@
/* global variables */ /* global variables */
volatile uint8_t pwr_ok; volatile uint8_t pwr_ok;
volatile uint8_t fan;
volatile uint16_t tachometer = 0;
volatile uint8_t timer2_ovf = 0;
const uint16_t TIMER2_PRESCALE[8] = {0,1,8,32,64,128,256,1024};
/* PWR_OK interrupt */ /* PWR_OK interrupt */
ISR(PCINT0_vect) { /* PCINT1 is actually triggering PCI0 Interrupt Vector */ ISR(PCINT0_vect) { /* PCI0 Interrupt Vector for PCINT[7:0] */
if (pwr_ok!=(PINB&(1<<PWR_OK))) { /* did the PWR_OK pin state changed */ if (pwr_ok!=(PINB&(1<<PWR_OK))) { /* did the PWR_OK pin state changed */
pwr_ok = PINB&(1<<PWR_OK); /* save new state */ pwr_ok = PINB&(1<<PWR_OK); /* save new state */
if (pwr_ok) { if (pwr_ok) {
@ -24,6 +29,25 @@ ISR(PCINT0_vect) { /* PCINT1 is actually triggering PCI0 Interrupt Vector */
} }
} }
/* fan tachometer interrupt */
ISR(PCINT1_vect) { /* PCI0 Interrupt Vector for PCINT[14:8] */
if (fan!=(PINC&(1<<FAN))) { /* did the FAN pin state changed */
fan = PINC&(1<<FAN); /* save new state */
if (fan) {
tachometer = timer2_ovf*256+TCNT2; /* save time */
TCNT2 = 0; /* reset timer 2 */
timer2_ovf = 0; /* reset timer 2 overflow counter */
}
}
}
/* timer 2 interrupt used to measure fan tachometer */
ISR(TIMER2_OVF_vect) { /* timer 2 overflow interrupt verctor */
if(pwr_ok) { /* only measure tachometer if power is ok */
timer2_ovf++; /* increase time 2 overflow counter */
}
}
static void ioinit(void) static void ioinit(void)
{ {
/* configure power */ /* configure power */
@ -37,7 +61,22 @@ static void ioinit(void)
/* configure peripherals */ /* configure peripherals */
DDRB &= ~(1<<IR); /* IR receiver is input */ DDRB &= ~(1<<IR); /* IR receiver is input */
DDRC &= ~(1<<FAN); /* FAN is input */
/* configure FAN */
DDRC &= ~(1<<FAN); /* FAN (PC5/PCINT13) is input */
fan = PINC&(1<<FAN); /* save state */
PCIFR &= ~(1<<PCIF1); /* clear interrupt flag */
PCICR |= (1<<PCIE1); /* enable interrupt for PCINT[14:8] */
PCMSK1 |= (1<<PCINT13); /* enable interrupt for PCINT1 */
/* use timer 2 to measure the tachometer */
/* use normal mode */
TCCR2A &= ~((1<<WGM20)|(1<<WGM21));
TCCR2B &= ~(1<<WGM22);
/* /256 prescale timer */
TCCR2B |= (1<<CS22)|(1<<CS21);
TCCR2B &= ~(1<<CS20);
TIFR2 &= ~(1<<TOV2); /* clear timer 2 overflow interrupt flag */
TIMSK2 |= (1<<TOIE2); /* enable timer 2 overflow interrupt */
/* configure channels (used for powering LEDs using an nMOS) */ /* configure channels (used for powering LEDs using an nMOS) */
DDRC |= (1<<CH1_1)|(1<<CH1_2)|(1<<CH1_3)|(1<<CH1_4)|(1<<CH1_5); /* CH1_x is output */ DDRC |= (1<<CH1_1)|(1<<CH1_2)|(1<<CH1_3)|(1<<CH1_4)|(1<<CH1_5); /* CH1_x is output */
@ -52,7 +91,7 @@ static void ioinit(void)
/* configure LED (on PD6/OC0A) */ /* configure LED (on PD6/OC0A) */
DDRD |= (1<<LED); /* LED is output */ DDRD |= (1<<LED); /* LED is output */
/* use phase correct PWM ode (because fast PWM is always on for at least 1 cycle) */ /* use phase correct PWM mode (because fast PWM is always on for at least 1 cycle) */
TCCR0A &= ~(1<<WGM01); TCCR0A &= ~(1<<WGM01);
TCCR0A |= (1<<WGM00); TCCR0A |= (1<<WGM00);
TCCR0B &= ~(1<<WGM02); TCCR0B &= ~(1<<WGM02);
@ -89,13 +128,13 @@ int main(void)
} }
break; break;
case 'a': case 'a':
PINB |= (1<<nPS_ON); printf("switching power supply ");
printf("power supply: ");
if (PINB&(1<<nPS_ON)) { if (PINB&(1<<nPS_ON)) {
puts("off");
} else {
puts("on"); puts("on");
} else {
puts("off");
} }
PINB |= (1<<nPS_ON);
break; break;
case 's': case 's':
printf("power: "); printf("power: ");
@ -207,6 +246,17 @@ int main(void)
} }
printf("increasing LED: %d\n",OCR0A); printf("increasing LED: %d\n",OCR0A);
break; break;
case 't':
if (tachometer) {
uint16_t prescale = TIMER2_PRESCALE[TCCR2B&((1<<CS22)|(1<<CS21)|(1<<CS20))];
if (prescale) {
uint32_t speed = ((60*F_CPU)/(prescale*(uint32_t)tachometer))/2;
printf("fan speed: %lurpm\n",speed);
}
} else {
printf("fan off or too slow\n");
}
break;
} }
} }