void uart_init() {
// set baud rate 9600
UBRR0 = (F_CPU / 16 / 9600 - 1);
// enable USART transmitter
UCSR0B = 1 << TXEN0;
UCSR0C = 0
| 0b11 << UCSZ00 // 8 data bits
| 0b1 << USBS0 // 2 stop bits
;
}
ISR(USART_RX_vect) {
// copy received UART byte to pins 2..9
uint8_t c = UDR0;
if (c != '\n' && c != '\r') {
PORTD = c << 2;
PORTB = c >> 6;
}
}
void uart_putc(char c) {
while (!(UCSR0A & 1 << UDRE0)) {}
UDR0 = c;
}
void uart_puts(char const *s) {
while (*s) uart_putc(*s++);
}
void uart_putn(int n, bool neg = 1) {
char buf[5];
neg = neg && n < 0;
if (neg) n = -n;
char *s = buf[5];
*--s = 0;
do {
*--s = n % 10 + '0';
n /= 10;
} while (n);
uart_puts(s);
}
void adc_init() {
// CTC mode
uint8_t wgm1 = 0b1111;
TCCR1A = 0
// set waveform generation mode
| (wgm1 & 0b11) << WGM10
;
TCCR1B = 0
// set timer 1 prescaler to 1/8
| 0b010 << CS10
// set waveform generation mode
| ((wgm1 >> 2) & 0b11) << WGM12
;
// overflow every 400 ticks
OCR1A = 400;
// enable timer 1 overflow interrupt
TIMSK1 = 1 << TOIE1;
ADMUX = 0
// use ADC0 as input
| 0 << MUX0
;
ADCSRA = 0
// enable the ADC
| 1 << ADEN
// enable conversion on trigger
| 1 << ADATE
// enable conversion done interrupt
| 1 << ADIE
;
ADCSRB = 0
// trigger conversion on timer 1 overflow
| 0b110 << ADTS0
;
}
ISR(TIMER1_OVF_vect) {
// start ADC conversion
ADCSRA |= 1 << ADSC;
}
volatile uint16_t adc__result;
volatile uint8_t adc__result_changed = 0;
ISR(ADC_vect) {
// read the conversion result.
// ADCL must be read before ADCH
adc__result = ADC;
adc__result_changed = 1;
uint16_t leds = 0;
adc__result /= 102; // map adc__result from 0..1023 to 0..9
for (int i = 0; i < 10; i++)
leds |= (adc__result > i) << i;
PORTD = leds << 2;
PORTB = leds >> 6;
}
uint16_t adc_get() {
uint16_t ret;
do {
adc__result_changed = 0;
ret = adc__result;
} while (adc__result_changed);
return ret;
}
int main() {
// mark pins 2..13 as output and pin 1 as TX
DDRD = ~0b11;
DDRB = ~0;
adc_init();
uart_init();
// enable interrupts
sei();
uart_putc('0');
uint16_t old_result = 11;
for (;;) {
uint16_t result = adc_get();
if (old_result != result) {
uart_putn(result);
uart_putc('\n');
}
old_result = result;
}
}