#include <avr/io.h>
#include <util/delay.h>
void init(){
// LED output.
DDRB |= 1<<4;
// Turn on ADC on third pin, continuous mode, prescaler 128.
ADMUX |= (1<<MUX0) | (1<<MUX1);
ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
}
int main(){
init();
uint16_t adc = 0;
while(1){
adc = (ADCH << 8) | ADCL;
// adc = (adc + 1) & 1023;
// _delay_ms(1);
if(adc > 512){
PORTB |= 1<<4;
}
else{
// PORTB = 0;
PORTB &= ~(1<<4);
}
}
}
This is the code I have running on my ATtiny13A. There is an LED connected to pin B4, and potentiometer to B3. The code is supposed to turn on the LED if the analog value is greater than 512 (half of maximum 1024). It doesn't work though, and LED seems to be disabled all the time.
Normally I would assume there is something wrong in configuration of peripherals, but there are some very strange things happening. For example, if I change PORTB &= ~(1<<4);
to PORTB = 0
(which in this case should do exactly the same thing), the code magically starts working just as expected. Another thing I tried is changing LED status using simple counter by uncommenting the two lines near _delay_ms
- and again, LED starts blinking as expected.
The only time when this code does not work is when it's in exactly this form - so there must be something wrong with combination of ADC reading and output port bit writing.
Why does this happen?
PORTB = 0
(the line that worked), but then add a singlenop
afterwards, it gets broken again. It appears to be a timing issue for some reason - adding 4nop
s fixes it again... \$\endgroup\$