add basic tachometer reader
This commit is contained in:
parent
e4cb5d1f8f
commit
be4f8c64bb
64
src/main.c
64
src/main.c
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue