ATmega328P: Módulo ADC

Contenido:

Módulo ADC del ATmega328P

El ATmega328P cuenta con un Módulo ADC (convertidor analógico-digital) de 10 bits que permite la conversión de señales analógicas a digitales. El ADC puede convertir señales en un rango de voltajes entre 0V y VCC, que es la tensión de alimentación del microcontrolador.

El ADC del ATmega328P tiene las siguientes características:

  • Resolución: 10 bits (1024 niveles de voltaje)
  • Rango de voltaje de entrada: 0V a VCC
  • Tasa de conversión: hasta 15.6k muestras por segundo (con una frecuencia de reloj de 16 MHz)
  • Selección de canal de entrada: puede seleccionarse uno de los 6 pines de entrada analógica (A0-A5) como canal de entrada del ADC
  • Modos de conversión: se pueden realizar conversiones en modo único o en modo de conversión libre (free-running mode)
  • Selección de referencia de voltaje: puede seleccionarse la referencia de voltaje interna del microcontrolador (1.1V) o la referencia externa a través del pin AREF

El ADC del ATmega328P se configura mediante registros específicos, como ADMUX (para seleccionar el canal de entrada y la referencia de voltaje), ADCSRA (para configurar la tasa de conversión y el modo de conversión) y ADCL/ADCH (para leer los valores convertidos).

✅ Si quieres conocer la descripción de cada uno de los registros, además de varios ejemplos adicionales de los que encontrarás en este post, te invito a que adquieras la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 dando clic ⭐ aquí ⭐. Adicionalmente recibirás los sketch de Arduino IDE y de Microchip Studio, incluyendo los archivos de simulación en Proteus Profesional v8.10.

Video Tutorial

Ejemplo 1: Leer el Pin AD0 del Dispositivo y enviar el valor de la Lectura al PC mediante el Puerto Serial.

Arduino:

at328p adc ejm1 1
Figura 1: Circuito con Arduino para el Ejemplo 1 del Módulo ADC.
uint16_t valor_ADC; // Variable para guardar el valor del ADC

void setup() {
  Serial.begin(9600); // Inicializa la Comunicación Serial a 9600 Baudios
  ADMUX = 0b01000000; // [7:6] AVCC con condensador externo en AREF, [5] Justificacion derecha, [3:0] CanalADC0
  ADCSRA = 0b00000111; // [7]DeshabilitoAdc, [6]NoIniciaPrimeraConversión, [5]SinDisparoAutomatico, [4:3]SinInterrupciones, [2:0]Prescaler128=125kHz
  ADCSRB = 0b00000000; // [2:0] Funcionamiento Libre
  DIDR0 = 0b00000001; // Entrada digital ADC0 desactivada
  _delay_ms(10);
}

void loop() {
  ADCSRA |= 0b11000000; // [7] HabilitoAdc, [6] IniciaPrimeraConversión
  while (ADCSRA & 0b01000000); // [6] Espero que termine la conversion
  ADCSRA &= 0b00111111; // [7] DeshabilitoAdc
  valor_ADC = ADC; // Coloco los valores leidos por el adc en la variable
  Serial.println(valor_ADC); // Envio los valores de la variable por el puerto serial
  _delay_ms(200); // Retardo 200ms
}

Lenguaje C:

at328p adc ejm1 2
Figura 2: Circuito con ATmega328P para el Ejemplo 1 del Módulo ADC.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

uint16_t valor_ADC; // Variable para guardar el valor del ADC

int main(void){
	// No incluye la Comunicación Serial, la puede agregar cuando llegue a ese capitulo

	ADMUX = 0b01000000; // [7:6] AVCC con condensador externo en AREF, [5] Justificacion derecha, [3:0] CanalADC0

	ADCSRA = 0b00000111; // [7]DeshabilitoAdc, [6]NoIniciaPrimeraConversión, [5]SinDisparoAutomatico, [4:3]SinInterrupciones, [2:0]Prescaler128=125kHz

	ADCSRB = 0b00000000; // [2:0] Funcionamiento Libre
	DIDR0 = 0b00000001; // Entrada digital ADC0 desactivada
	_delay_ms(10);
	while (1){
		ADCSRA |= 0b11000000; // [7] HabilitoAdc, [6] IniciaPrimeraConversión
		while (ADCSRA & 0b01000000); // [6] Espero que termine la conversion
		ADCSRA &= 0b00111111; // [7] DeshabilitoAdc
		valor_ADC = ADC; // Coloco los valores leidos por el adc en la variable
		// En esta linea agregue el envio de los valores de la variable por el puerto serial

		_delay_ms(200); // Retardo 200ms
	}
}

Ejemplo 2: Leer el Pin AD0 del Dispositivo y visualizar el valor de la lectura en el Puerto D y B.

Arduino:

at328p adc ejm2 1
Figura 3: Circuito con Arduino para el Ejemplo 2 del Módulo ADC.
uint16_t valor_ADC; // Variable para guardar el valor del ADC

void setup() {
  DDRD = 0b11111100; // Puerto D: Salidas [7:2]
  DDRB = 0b00001111; // Puerto B: Salidas [3:0]
  PORTD = 0b00000000; // Salidas en LOW
  PORTB = 0b00000000; // Salidas en LOW
  ADMUX = 0b01000000; // [7:6] AVCC con condensador externo en AREF, [5] Justificacion derecha, [3:0] CanalADC0
  ADCSRA = 0b00000111; // [7]DeshabilitoAdc, [6]NoIniciaPrimeraConversión, [5]SinDisparoAutomatico, [4:3]SinInterrupciones, [2:0]Prescaler128-125kHz
  ADCSRB = 0b00000000; // [2:0] Funcionamiento Libre
  DIDR0 = 0b00000001; // Entrada digital ADC0 desactivada
  _delay_ms(10);
}

void loop () {
  ADCSRA |= 0b11000000; // [7] HabilitoAdc, [6] IniciaPrimeraConversión
  while (ADCSRA & 0b01000000); // [6] Espero que termine la conversion
  ADCSRA &= 0b00111111; // [7] DeshabilitoAdc
  valor_ADC = ADC; // Coloco los valores leidos por el adc en la variable
  PORTD = (valor_ADC & 0b0000111111) << 2; // Escribo los 6 primeros bits en el Puerto D
  PORTB = (valor_ADC & 0b1111000000) >> 6; // Escribo los 4 bits restantes en el Puerto B
  _delay_ms(100); // Retardo 100ms
}

Lenguaje C:

at328p adc ejm2 2
Figura 4: Circuito con ATmega328P para el Ejemplo 2 del Módulo ADC.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

uint16_t valor_ADC; // Variable para guardar el valor del ADC

int main(void){
	DDRD = 0b11111100; // Puerto D: Salidas [7:2]
	DDRB = 0b00001111; // Puerto B: Salidas [3:0]
	PORTD = 0b00000000; // Salidas en LOW
	PORTB = 0b00000000; // Salidas en LOW
	ADMUX = 0b01000000; // [7:6] AVCC con condensador externo en AREF, [5] Justificacion derecha, [3:0] CanalADC0
	ADCSRA = 0b00000111; // [7]DeshabilitoAdc, [6]NoIniciaPrimeraConversión, [5]SinDisparoAutomatico, [4:3]SinInterrupciones, [2:0]Prescaler128-125kHz
	ADCSRB = 0b00000000; // [2:0] Funcionamiento Libre
	DIDR0 = 0b00000001; // Entrada digital ADC0 desactivada
	_delay_ms(10);
	while (1){
		ADCSRA |= 0b11000000; // [7] HabilitoAdc, [6] IniciaPrimeraConversión
		while (ADCSRA & 0b01000000); // [6] Espero que termine la conversion
		ADCSRA &= 0b00111111; // [7] DeshabilitoAdc
		valor_ADC = ADC; // Coloco los valores leidos por el adc en la variable
		PORTD = (valor_ADC & 0b0000111111) << 2; // Escribo los 6 primeros bits en el Puerto D
		PORTB = (valor_ADC & 0b1111000000) >> 6; // Escribo los 4 bits restantes en el Puerto B
		_delay_ms(100); // Retardo 100ms
	}
}

Ejemplo 3: Leer una Señal Senoidal de 5vpp con un offset de 2.5v conectada en el Pin AD0 del Dispositivo y enviar el valor de la Lectura al PC mediante el Puerto Serial.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Ejemplo 4: Leer el Sensor de Temperatura Interno del Microcontrolador y enviar el valor de la Lectura al PC mediante el Puerto Serial.

Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Deja un comentario