UNIVERSIDAD TÉCNICA DEL NORTE FACULTAD DE INGENIERÍA EN CIENCIAS APLICADAS CARRERA DE INGENIERÍA ELECTRÓNICA Y REDES DE COMUNICACIÓN COMUNICACIÓN NOMBRE: David Guerra FECHA: 31 de Enero del 2014 CONSULTA DE MICROCONTROLADORES AVANZADOS CONVERSIÓN ANÁLOGO/DIGITAL La mayoría de los datos del mundo real es analógico. Ya se trate de la temperatura, presión, tensión, etc, su variación es siempre de naturaleza analógica. Por ejemplo, la temperatura en el interior de una caldera es de alrededor de 800 ° C. Durante su luz, la temperatura nunca se acerca directamente a 800 ° C.Si la temperatura ambiente es 400 ° C, que comenzará a aumentar gradualmente a 450 ° C, 500 ° C y por lo tanto llega a 800 ° C durante un período de tiempo.Este es un conjunto de datos analógicos.
Figura1. Proceso de Adquisición de Señal Ahora, tenemos que procesar los datos que hemos recibid, pero el procesamiento de señal analógica es bastante ineficiente en t érminos de la precisión, l a velocidad y la salida deseada, por lo tanto, l as convertimos a formato digital mediante un convertidor analógico a digital (ADC).
PROCESO DE ADQUISICIÓN DE SEÑAL En general, la señal (o datos) proceso de adquisición tiene 3 pasos. o
En el mundo real , un sensor un sensor detecta cualquier parámetro físico y la convierte en una señal eléctrica analógica equivalente.
o
Para eficiente y facilidad de procesamiento de la señal, esta señal analógica se convierte en una señal digital mediante un convertidor analógico a digital (ADC) .
o
Esta señal digital se alimenta a continuación a la
microcontrolador (MCU) y se procesa en
consecuencia.
Figura2. ADC Pins - ATMEGA164/324
EL ADC DEL AVR El AVR cuenta con ADC incorporado en casi toda su MCU. En ATMEGA16/32, PORTA contiene los pines ADC. Algunas otras características de la ADC son los siguientes:
Figura 3. ADC Características ATMEGA164/324 –
Ahora mismo, estamos preocupados por la
Resolución de 8 canales de 10 bits característica.
8 canales implica que hay 8 pines ADC se multiplexan juntos. Se puede ver fácilmente que estos
o
pines se encuentran en todo PORTA (PA0 o
PA7).
…
10 bits de resolución implica que hay 2 ^ 10 = 1024 pasos (tal como se describe a continuación).
o
Figura 4. 8 canales ADC de 10 bits Supongamos que utilizamos una referencia de 5V. En este caso, cualquier valor analógico en entre 0 y 5V se convierte en su valor ADC equivalente como se muestra arriba. El rango de 0-5V se divide en 2 ^ 10 = 1024 pasos. Por lo tanto, una entrada de 0 V dará una salida del ADC de 0, 5V dará una salida del ADC de 1023, mientras que una entrada de 2.5V dará una salida del ADC de alrededor de 512. Este es el concepto básico de la ADC. Para aquellos a los que podría referirse, del tipo de ADC implementado dentro del AVR MCU es de aproximación sucesiva tipo. Aparte de esto, las otras cosas que necesitamos saber acerca de la ADC AVR son: o
ADC Precontador
o
Registros ADC - ADMUX, ADCSRA, ADCH, ADCL y SFIOR
ADC PRESCALER El ADC del AVR convierte la señal analógica en señal digital en algún intervalo regular. Este intervalo se determina por la frecuencia de reloj. En general, el ADC opera dentro de un rango de frecuencia de 50 kHz a 200 kHz. Pero la frecuencia de reloj de la CPU es mucho más alta (en el orden de MHz). Así que para lograrlo, por división de frecuencia debe tener l ugar. El pre-escalador actúa como este factor de
división. Produce la frecuencia deseada de la mayor frecuencia externa. Hay algunos factores de división predefinidos - 2, 4, 8, 16, 32, 64, y 128.Por ejemplo, un pre-escalador de 64 implica F_ADC = F_CPU/64. Para F_CPU = 16MHz, F_ADC = 16M/64 = 250kHz. Ahora, la principal pregunta es ... que la frecuencia para seleccionar? Fuera de la gama de 50 kHz-200 kHz de las frecuencias, cuál necesitamos? Bueno, la respuesta radica en su necesidad.
Hay un trade-off entre la
frecuencia y la precisión . Mayor es la frecuencia, menor es la precisión y viceversa. Por lo tanto, si su aplicación no es sofisticado y no requiere mucha precisión, usted podría ir para las frecuencias más altas.
REGISTROS ADC ADMUX - ADC Multiplexer Selection Registro El registro ADMUX es como sigue.
Los bits que se destacan son de interés para nosotros. En cualquier caso, vamos a discutir todos los bits de uno en uno. o
Los bits 07:06 - REFS1: 0 - Referencia Bits de selección - Estos bits se utilizan para elegir la tensión de referencia. Se utilizan las siguientes combinaciones.
Figura 5. Selección de referencia de voltaje.
Figura 6. Pines de voltaje d e referencia ADC.
El ADC necesita una tensión de referencia para trabajar sobre. Para ello contamos con un tres pins Aref, AVCC y GND. Podemos suministrar nuestra propia tensión de referencia a través de AREF y GND. Para ello, elija la primera opción . Además de este caso, se puede conectar un condensador a través de pin AREF y tierra para evitar el ruido, o puede optar por dejarlo sin conectar. Si desea utilizar el VCC (+5 V), elegir
la
segunda opción . O si no, elegir la última opción para Vref interna. Vamos a elegir la segunda opción para Vcc = 5V. o
Bit 5 - ADLAR - ADC izquierdo Ajuste Resultado - Que sea '1 'para izquierdo Ajuste el Resultado ADC. Vamos a discutir sobre esto un poco más tarde.
o
Bits 04:00 - MUX4: 0 - Canal Analógico y ganancia Bits de selección - Hay 8 canales de ADC (PA0 ... PA7). ¿A cuál elegimos? Elige uno! No importa. ¿Cómo elegir? Usted puede elegir mediante el establecimiento de estos bits. Como hay 5 trozos, se compone de 2 ^ 5 = 32 condiciones diferentes de
la
siguiente
forma. Sin
embargo,
estamos
preocupados
condiciones. Inicialmente, todos los bits se ponen a cero.
Figura 7. Canal de entrada y selector de ganancia. Por lo tanto, para inicializar ADMUX, escribimos:
sólo
con
los
primeros
8
ADMUX = (1 << REFS0);
ADCSRA - CONTROL ADC Y REGISTRO DE ESTADO A El registro ADCSRA es como sigue.
ADCSRA Registrarse
Los bits que se destacan son de interés para nosotros. En cualquier caso, vamos a discutir todos los bits de uno en uno. o
Bit 7 - ADEN - ADC Enable - Como su nombre lo dice, se activa la función de ADC. A menos que esta opción está activada, las operaciones de ADC no puede tener lugar a través de PORTA PORTA es decir se comportará como pines GPIO.
o
Bit 6 - ADSC - ADC Start Conversion - Escribe esto en '1 'antes de iniciar ningún tipo de conversión. Esto se escribe 1, siempre y cuando la conversión está en curso, después de lo cual vuelve a cero. Normalmente se necesitan 13 pulsos de reloj ADC para esta operación. Pero cuando usted lo llama por primera vez, toma 25, ya que realiza la inicialización junto con él.
o
Bit 5 - ADATE - ADC Auto Disparador Enable - Si se establece en '1 'activa auto-activación de ADC. ADC se activa automáticamente en cada flanco de subida de pulso de reloj. Ver el registro SFIOR para más detalles.
o
Bit 4 - ADIF - ADC Interrupt Flag - Siempre que una conversión ha terminado, y los registros se actualizan, este bit se pone a '1 'automáticamente. Por lo tanto, esto se utiliza para comprobar si la conversión se ha completado o no.
o
Bit 3 - ADIE - ADC Interrupt Enable - Cuando este bit se pone a '1 ', la interrupción ADC está habilitada. Este se utiliza en el caso de interrupción del ADC impulsada.
o
Los bits 02:00 - ADPS2: 0 - ADC de divisor bits de selección - El pre-escalador (factor de división entre la frecuencia XTAL y la frecuencia de reloj ADC) se determina mediante la selección de la combinación apropiada de la siguiente.
Figura 8. Selección del prescaler del ADC.
Suponiendo que la frecuencia de 16MHz XTAL y el rango de frecuencia de 50 kHz-200 kHz, elegimos un prescaler de 128. Por lo tanto, F_ADC = 16M/128 = 125 kHz. Por lo tanto, inicializamos ADCSRA como sigue:
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); / / Prescaler = 128
ADCL Y ADCH - ADC REGISTROS DE DATOS El resultado de la conversión ADC se almacena aquí. Desde la ADC tiene una resolución de 1 0 bits, se requiere 10 bits para almacenar el resultado. Por lo tanto un solo registro de 8 bits no es suficiente. Necesitamos dos registros - ADCL y ADCH (ADC byte bajo y ADC de alta byte) de la siguiente manera. Los dos pueden ser llamados en conjunto como ADC.
Figura 9. ADC Registros de datos (ADLAR = 0)
Figura 10. ADC Registros de datos (ADLAR = 1) Usted puede ver muy bien el efecto de bits ADLAR (en el registro ADMUX). Al establecer ADLAR = 1, el resultado de la conversión se deja ajustado.
SFIOR - FUNCIÓN E / S ESPECIAL REGISTRARSE En funcionamiento normal, no utilizamos este registr o. Este registro entra en juego cuando ADATE (en ADCSRA) se pone a '1 '. El registro es el siguiente.
Figura 11. Registro SFIOR. Los bits resaltados en amarillo son discutidas como se relacionan con ADATE.Otros bits están reservados bits. o
Bits 07:05 - ADC Auto Disparador Fuente - Siempre ADATE se pone a '1 ', estos bits determinan la fuente de disparo para la conversión ADC. Hay 8 posibles fuentes de disparo.
Figura 12. ADC Auto Triggering Source Selections.
CODIGO EMPLEADO EN LA SIMULACION #include #include
//// ADC //// #define ADC_VREF_TYPE 0x00
// Read the AD conversion result unsigned int read_adc(unsigned char adc_input) { ADMUX=adc_input;
// Delay needed for the stabilization of the ADC input voltage delay_us(10); // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCW; }
static unsigned int time_count;
// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Place your code here TCNT0=6; ++time_count;
if (time_count==200) { read_adc(0);}; if (time_count==400) { read_adc(1);}; if (time_count==600) { read_adc(2);}; if (time_count==800) { read_adc(3);}; if (time_count==1000) {read_adc(4);}; if (time_count==1200) {read_adc(5);}; if (time_count==1400) {read_adc(6);};
if (time_count==1600) {read_adc(7);};
time_count=0; } // Declare your global variables here
void main(void) { // Declare your local variables here
// Crystal Oscillator division factor: 1 #pragma optsizeCLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
// Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF;
// Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00;
// Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 1000,000 kHz // Mode: Normal top=0xFF // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x02; TCNT0=0x00;
OCR0A=0x00; OCR0B=0x00;
// Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00;
// ADC initialization // ADC Clock frequency: 1000,000 kHz // ADC Voltage Reference: AREF pin // ADC Auto Trigger Source: ADC Stopped // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On // ADC4: On, ADC5: On, ADC6: On, ADC7: On DIDR0=0x00; ADMUX=ADC_VREF_TYPE & 0xff ; ADCSRA=0x83;
// Global enable interrupts #asm("sei")
while (1)
{ // Place your code here
if (read_adc(0)>((2*1023)/5)) { PORTB.0=1; } if (read_adc(1)>((2*1023)/5)) { PORTB.1=1; } if (read_adc(2)>(2*1023)/5) { PORTB.2=1; } if (read_adc(3)>(2*1023)/5) { PORTB.3=1; } if (read_adc(4)>(2*1023)/5) { PORTB.4=1; } if (read_adc(5)>(2*1023)/5) { PORTB.5=1; } if (read_adc(6)>(2*1023)/5) { PORTB.6=1; } if (read_adc(7)>(2*1023)/5) { PORTB.7=1; }
if (read_adc(0)<=((2*1023)/5)) { PORTB.0=0; } if (read_adc(1)<=((2*1023)/5)) { PORTB.1=0; } if (read_adc(2)<=(2*1023)/5) { PORTB.2=0; } if (read_adc(3)<=(2*1023)/5) { PORTB.3=0; } if (read_adc(4)<=(2*1023)/5) { PORTB.4=0; } if (read_adc(5)<=(2*1023)/5) { PORTB.5=0; } if (read_adc(6)<=(2*1023)/5) { PORTB.6=0; } if (read_adc(7)<=(2*1023)/5) { PORTB.7=0; } } }
BIBLIOGRAFÍA:
http://maxembedded.com/2011/06/20/the-adc-of-the-avr/ http://www.embedds.com/adc-on-atmega328-part-2/
http://tutorialcodevisionavr.blogspot.com/2011/05/goging-form-analog-to-digitaltutorial.html