-
Notifications
You must be signed in to change notification settings - Fork 0
/
odoconv.ino
80 lines (60 loc) · 1.73 KB
/
odoconv.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
/*
* Uses Timer0 with Output Compare Match Interrupt to break down the input frequency
* -> TO pin as external signal source
* -> Counter0 Output Compare Match A interrupt
*/
// configuration
static const uint8_t INPUT_PIN = PB2;
static const uint8_t OUTPUT_PIN = PB3;
static const uint8_t DIVIDER = 12;
static const uint8_t OUTPUT_MS = 5;
// globals
volatile uint8_t output = 0;
// helper functions for readability
static inline void enable_pin(volatile uint8_t& port, const uint8_t pin)
{
port |= _BV(pin);
}
static inline void disable_pin(volatile uint8_t& port, const uint8_t pin)
{
port &= ~_BV(pin);
}
// pin change interrupt routine
// called for changes on all pins enabled in PCMSK
ISR(TIMER0_COMPA_vect) {
output = OUTPUT_MS;
}
int main(void)
{
cli();
// disable unused features to reduce power consumption
ADCSRA = 0; // disable ADC
WDTCR = 0; // disable watchdog
PRR &= ~_BV(PRADC) & ~_BV(PRTIM1); // disable unused ADC and TIMER1 through the Power Reduction Register
// configure PB2 (0xf - 0x4 = 0xb) as input, others as output
DDRB = ~_BV(INPUT_PIN);
// configure timer/counter0
TIMSK = _BV(OCIE0A); // enable output compare 0A interrupt
OCR0A = DIVIDER; // set output compare value
TCCR0A = _BV(WGM01); // use CTC mode
TCCR0B = _BV(CS00) | _BV(CS01) | _BV(CS02); // use external clock on TO pin, rising edge
sei();
while(1)
{
cli();
if (output)
{
--output;
enable_pin(PORTB, OUTPUT_PIN);
}
else
{
disable_pin(PORTB, OUTPUT_PIN);
}
sei();
_delay_ms(1);
}
}