#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);
}
}
}
Este es el código que tengo funcionando en mi ATtiny13A. Hay un LED conectado al pin B4, y un potenciómetro a B3. El código se supone que enciende el LED si el valor analógico es mayor que 512 (la mitad del máximo de 1024). Sin embargo, no funciona, y el LED parece estar desactivado todo el tiempo.
Normalmente asumiría que hay algo mal en la configuración de los periféricos, pero están ocurriendo cosas muy extrañas. Por ejemplo, si cambio PORTB &= ~(1<<4);
a PORTB = 0
(que en este caso debería hacer exactamente lo mismo), el código empieza a funcionar mágicamente tal y como se esperaba. Otra cosa que probé es cambiar el estado del LED usando un simple contador descomentando las dos líneas cerca de _delay_ms
- y de nuevo, el LED comienza a parpadear como se esperaba.
La única vez que este código no funciona es cuando está exactamente en esta forma - por lo que debe haber algo mal con la combinación de la lectura del ADC y la escritura de bits del puerto de salida.
¿Por qué ocurre esto?
0 votos
Una cosa más - incluso con el código como se muestra, parece como si el LED podría encenderse UNA vez - por lo que si el potenciómetro comenzó bajo (con el LED apagado), podría encender el LED, y luego apagarlo, pero la próxima vez que traté de girar el potenciómetro, falla. Esto es tan raro...
0 votos
OK, tengo una buena pista - si uso
PORTB = 0
(la línea que ha funcionado), pero luego añade unnop
después, se vuelve a romper. Parece ser un problema de sincronización por alguna razón - añadiendo 4nop
s lo arregla de nuevo...