#include "avr8.h" class Voltimeter { protected: ATMEGA16 * atmega16; public: /** * Construtor da classe */ Voltimeter(){ atmega16 = reinterpret_cast(0); /** Habilita interrupções */ atmega16->sreg = 0x80; /** Seta os leds da portaB para saída */ atmega16->ddrb = 0xff; /** Desliga os leds da portaB */ atmega16->portb = 0xff; /** * ADMUX : ADC Multiplexer Selection Register (Pag 215) * Bit 7-6 : Reference Selection Bits => AVCC com capacitor externo no pino AREF (0x01) * Bit 5 : ADC Left Adjust Result (0x1) Detalhes (Pag 218) * Bit 4-0 : Analog Channel and Gain Selection Bits (0x00000 ADC0 Single-Ended) */ atmega16->admux = 0x60; /** 0110 0000 */ /** * ADCSRA : ADC Status and Control Register A (Pag 217) * Bit 7 : ADC Enable * Bit 6 : ADC Start Conversion * Bit 5 : ADC Auto Trigger Enable * Bit 4 : ADC Interrupt Flag * Bit 3 : ADC Interrupt Enable * Bit 2-0 : ADC Prescaler Select Bits (Fator de divisão 2) */ atmega16->adcsra = 0xe8; /** 1110 1000 */ /** * SFIOR : Special Funcition IO Register (Pag 219) * Bit 7-5 : ADC Auto Trigger Source (Free Running Mode 0x000) * Bit 4 : Reserved Bit (Este bit deve ser escrito como 0x0) * Bit 3 : Analog Comparator Multiplexer Enable * Bit 2 : Pull-up disable * Bit 1 : Prescaler Reset Timer/Counter2 * Bit 0 : Prescaler Reset Timer/Counter1 and Timer/Counter0 */ atmega16->sfior = 0x00; } ~Voltimeter(){ } /** * Tratador de interrupções do ADC */ void handle_ADCint(){ /** * "(...) if the result is left adjusted (bit 5 ADMUX está setado) and no more than 8-bit precision * is required, it is sufficient to read ADCH." * (Pag 218, ATMega16 manual) * * A precisão para essa aplicação era de 8 bits, portanto, é suficiente ler apenas o registrador ADCH * */ atmega16->portb = ~(atmega16->adch); /** Inicia uma nova conversão. É necessário setar (nível lógico "1") o bit6 novamente, pois o hardware * o coloca em "0", ao terminar a conversão. */ atmega16->adcsra |= 0x40; /** x1xx xxxx */ } }; Voltimeter voltimeter; extern "C" { void __vector_14() __attribute__ ((signal)); /** Vetor do Tratador de Interrupções do ADC */ } void __vector_14(){ voltimeter.handle_ADCint(); } int main(){ while(1); return 0; }