Sei sulla pagina 1di 12

LABORATORIO PROCESAMIENTO DE SEÑALES

INFORME DE LA PRÁCTICA No. 4


(Conversión A/D)

INTEGRANTES: PROFESOR: Pedro Vizcaya Guarín


Andrés Camilo Ángel Marín MONITOR: Laura Daniela Melgarejo
Quiñonez
GRUPO: 1
FECHA DE ENTREGA: 21/09/19

Introducción o presentación

La importancia de Convertir una señal Digital a Analógica, es una de las aplicaciones que se dan hoy que
permiten que podamos escuchar música, su aplicación se dan en unos bafles como reproductores de música,
por lo que la finalidad de este conversor se da al muestrear una señal, que por ende se puede cuantizar una
aproximación de la señal dada su Entrada Analógica, por lo que para generar una señal analógica, es
primordial partir de una señal digital, por lo cual la importancia se da también el caso donde se analiza el caso
donde por medio de una señal digital, realizar la cuantización y tasa de muestreo para convertirlo en una señal
analógica, la base primordial de funcionamiento se da con la implementación del DAC del microcontrolador
ATMEGA328P de la placa Arduino Uno.

Equipo y material empleados

Equipo Marca Modelo


Osciloscopio Tektronix TDS 2022B
Fuente Alimentación Leader LPS-162
Punta de Osciloscopio 10x Hameg HZ 52
P2200
Punta de Osciloscopio 10x Tektronix 10X/X1
Punta Generador de Funciones null CBN045
Puntas Fuente Alimentación null BAC008
Puntas Fuente Alimentación null BAC029
Filtro Butterworth null null
Microcontrolador Arduino Uno

Tabla 1. Equipos suministrados y necesarios para el Desarrollo de la Practica.

Objetivos

Objetivo General

Aprender las características básicas de la conversión digital análoga y su relación con las exigencias de una
aplicación real.
Objetivos Específicos

1. Conocer las características básicas del módulo de PWM del microcontrolador empleado.
2. Aprender a programar el módulo de temporizador (timer) del microcontrolador para su uso en diversas
configuraciones de PWM.
3. Emplear la técnica de interrupción para programar el conversor A/D y generar una salida analógica a
partir de una señal muestreada.

Prerrequisitos

1. Leer en el manual del microcontrolador la descripción del TIMER 1

Desarrollo

Inicialmente se parte de un análisis sobre la conversión de una señal Digital a Analoga, por medio de
distintos modos de operación y comparación por medio de distintos tipos de Implementación aplicando la
Modulación de Ancho de Pulsos o comúnmente PWM.

1. Configuración del conversor A/D en 10 bits/muestra, 250 muestras/s, controladas por interrupción
generada a partir del temporizador 0 (programación que se hizo en la última parte de la práctica
anterior).

// Programar el microcontrolador para que se haga conversión a una tasa fija de 250 Hz
// Iniciar variables.
volatile boolean readFlag=false;
// Valor leído
volatile int analogVal;

void setup() {
// 1. Suspender interrupciones

cli();

// 2. Programar temporizador 0 para producir interrupciones a la tasa de muestreo de 250 Hz.

TCCR0A = 0; // Genera un reset en el registro


TCCR0B = 0; // Genera un reset en el registro
TCNT0 = 0; // inicializa el contador de valor a 0

OCR0A = 249; // = 16000000 / (256 * 250) - 1 (debe ser menor a <256)


// // encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare
TCCR0A |= (1 << WGM01);
// subiendo bits CS02, CS01 y CS00 para prescaler en 256
TCCR0B |= (1 << CS02) | (0 << CS01) | (0 << CS00);
// habilitando interrupcion por timer es el bit apropiado de mascara para temporizer
TIMSK0 |= (1 << OCIE0A);// se encarga de habilitar interrupciones globales pág 88//

// 3. Programar conversor A/D para convertir a la máxima velocidad de reloj, pero empleando el
// temporizador 0 como fuente de disparo (Timer/Counter0 Compare Match A).

ADCSRA |= (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2);


// Estos determinan el factor de division entre el & la frecuencia
// del sistema de reloj entre la entrada del reloj y el ADC // Pag 219

ADMUX |= (1 << REFS0) | (0 << REFS1);// Indica que para tener un


// voltaje referido a ADC tiene que estar AVcc con un capacitor
// externo referido a un pin AREF en REFS0 en 1 & REFS1 en 0.

ADMUX |= (0 << MUX0) | (0 << MUX1) | (0 << MUX2) | (0 << MUX3);


// todo esto va de acuerdo a la entrada negativa de comparador Analoga
// paginas 202 - pagina 218

ADMUX |= (0<<ADLAR); // indica que ADLAR tiene que estar en 1


// Revisar Tablas 23.9.3.1.1 & 23.9.3.1.2 pagina 219

ADCSRB |= (0 << ADTS0) | (0 << ADTS1) | (0 << ADTS2);

// esto quiere decir que se toma como referencia los 3 ADTS0/1/2


// porque esto se da de acuerdo a una condicion de trigger source
// de la tabla 23.6 pagina 220 Datasheet

ADCSRA |= (1 << ADEN) | (1 << ADSC) | (1 << ADATE);

// Tabla 23.9.2 ADCSRA - ADCSRA pagina 218


// ADEN habilita el adc en modo escritura, escrito en 0 es apagado
// ADSC en 1a conversion esta habilitado escrito al mismo tiempo
// tomando 25 ciclos de reloj de lo normal que son 13
// al terminar la conversión regresa a 0
// ADATE configura el ADC con auto-triggering, seleccionando
// un eje positivo, al cual selecciona los bits en ADSCRB

ADCSRA |= (1 << ADIE);

sei();

ADCSRA |= (1 << ADSC);

pinMode(13, OUTPUT);

// Configurar puerto serial para recibir datos a la tasa de muestreo.


Serial.begin(2000000); /*velocidad maxima para que no interfiera con otros procesos*/
while (!Serial) {
; // Esperar a que el puerto inicie
}
}

void loop() {
// Se lee dato y envía hacia el puerto serial.
if (readFlag)
{
readFlag=false;
enviardato();
}
}

void enviardato(){
Serial.println(analogVal);
//Serial.print(" ");
}
ISR(ADC_vect){
TIFR0 |= (1 << OCF0A); // Bajar la bandera del disparo por timer0.
readFlag = true;
// Leer dato
analogVal = ADCL | (ADCH << 8);
}
ISR(TIMER0_COMPA_vect){
}

2. Configuración de la conversión D/A con PWM, empleando el temporizador de 16 bits, temporizador


1, en el modo de fase y frecuencia correcta (revise la configuración de los registros de control de
contador TCCR1A y B para los siguientes casos:

a. Tasa de muestreo de 250 Hz y a la mayor resolución posible (modo 8).

volatile boolean toggle = false;


volatile boolean readFlag=false;
volatile int analogVal; // Valor leído

// Codigo PWM Caso 8


void setup() {
// put your setup code here, to run once:

//1. Suspender Interrupciones


cli();
pinMode(9,OUTPUT);//OC1A
pinMode(10,OUTPUT);//OC1B

// 2. Programar temporizador 0 para producir interrupciones a la tasa de muestreo de 250 Hz.

TCCR0A = 0; // Genera un reset en el registro


TCCR0B = 0; // Genera un reset en el registro
TCCR1A = 0; // esta función declarada es un reset generado al Registro (Pag77)
TCCR1B = 0;// esta función declarada es un reset generado al Registro (Pag77)
TCNT0 = 0; // inicializa el contador de valor a 0
ADMUX &= 0;

TCNT1 = 0; // Reset al Contador (Pag 78 - 79) en este caso se toma referente al timer 1
TCCR0A |= (0 << WGM00) | (1 << WGM01); // datasheet Pagina 86
TCCR0B |= (0 << WGM02); // datasheet Pagina 86

TCCR0B |= (1 << CS02) | (0 << CS01) | (0 << CS00);


OCR0A = 249; // = 16000000 / (256 * 250) - 1 (debe ser menor a <256)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare
TIMSK0 |= (1 << OCIE0A);// se encarga de habilitar interrupciones globales pág 88//

// 3. Programar conversor A/D para convertir a la máxima velocidad de reloj, pero empleando el
// temporizador 0 como fuente de disparo (Timer/Counter0 Compare Match A).
ADCSRA |= (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2);
// Estos determinan el factor de division entre el la frecuencia
// del sistema de reloj entre la entrada del reloj y el ADC // Pag
ADMUX |= (0<<ADLAR);// indica que ADLAR tiene que estar en 1
// Revisar Tablas 23.9.3.1.1 & 23.9.3.1.2 pagina 219
ADMUX |= (1 << REFS0) | (0 << REFS1); // esto quiere decir que se toma como referencia los
3 ADTS0/1/2
// porque esto se da de acuerdo a una condicion de trigger source
// de la tabla 23.6 pagina 220 Datasheet
ADMUX |= (0 << MUX0) | (0 << MUX1) | (0 << MUX2) | (0 << MUX3);
// todo esto va de acuerdo a la entrada negativa de comparador Analoga
// paginas 202 - pagina 218
ADCSRB |= (0 << ADTS0) | (0 << ADTS1) | (0 << ADTS2);
// esto quiere decir que se toma como referencia los 3 ADTS0/1/2
// porque esto se da de acuerdo a una condicion de trigger source
// de la tabla 23.6 pagina 220 Datasheet
ADCSRA |= (1 << ADEN) | (1 << ADSC) | (1 << ADATE);
ADCSRA |= (1 << ADIE);
//Programacion Timer 1 para PWM:

TCCR1A |=(1<<COM1A1)| (0<<COM1A0)|(1 << COM1B1) | (1 << COM1B0) | (0 << WGM11)


| (0 << WGM10);
// estos bits controlan 0C1A & 0C1B por lo cual la funcionalidad de entrada/salida
// y es conectada para un normal puerto de operacion, un reset, un clear o un toggle
// tabla 15.2 para no tener PWM
TCCR1B = (0 << ICNC1) | (0 << ICES1) | (1 << WGM13) | (0 << WGM12) | (0 << CS12) | (0
<< CS11) | (1 << CS10);
// el bit 7 es para cancelar el ruido
// el 6 para ajustar una caida o una pendiente de acuerdo a la captura
// el 5 es un bit para uso futura
// 4 y 3 son para generar ondas
// del 2 al 0 es para selecicionar el counter del reloj.
OCR1A = 63999; // = 16000000 / (1 * 250) - 1 (debe ser menor a <65536)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare"
OCR1B = 63999; // = 16000000 / (1 * 250) - 1 (debe ser menor a <65536)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare"
ICR1 = 1023;// se toma este valor porque es valor que se alcanza de acuerdo a
// unos valores fijos en OCR1A o ICR1 en el tope o TOP.
sei();
ADCSRA |= (1 << ADSC);
}
Void loop() {
// Se lee dato y envía hacia el puerto serial.
if (readFlag=true)
{
readFlag=false;
enviardato();
}
}

void enviardato(){
Serial.println(analogVal);
//Serial.print(" ");
}
ISR(ADC_vect){
TIFR0 |= (1 << OCF0A); // Bajar la bandera del disparo por timer0.
readFlag = true;
// Leer dato
analogVal = ADCL | (ADCH << 8);
OCR1A = analogVal;
OCR1B = analogVal;

b. Con una resolución de 10 bits y a la máxima tasa de muestreo (modo 7).

// Codigo PWM Caso 7

// Iniciar variables.
volatile boolean readFlag=false;
// Valor leído
volatile int analogVal;

void setup() {
// put your setup code here, to run once:

//1. Suspender Interrupciones


cli();
pinMode(9,OUTPUT);//OC1A
pinMode(10,OUTPUT);//OC1B
// 2. Programar temporizador 0 para producir interrupciones a la tasa de muestreo de 250 Hz.

TCCR0A = 0; // Genera un reset en el registro


TCCR0B = 0; // Genera un reset en el registro
TCCR1A = 0; // esta función declarada es un reset generado al Registro (Pag77)
TCCR1B = 0; // esta función declarada es un reset generado al Registro (Pag77)
TCNT0 = 0; // inicializa el contador de valor a 0
ADMUX &= 0;

TCNT1 = 0; // Reset al Contador (Pag 78 - 79) en este caso se toma referente al timer 1
TCCR0A |= (0 << WGM00) | (1 << WGM01); // datasheet Pagina 86
TCCR0B |= (0 << WGM02); // datasheet Pagina 86

TCCR0B |= (1 << CS02) | (0 << CS01) | (0 << CS00);


OCR0A = 249; // = 16000000 / (256 * 250) - 1 (debe ser menor a <256)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare
TIMSK0 |= (1 << OCIE0A); // se encarga de habilitar interrupciones globales pág 88//

// 3. Programar conversor A/D para convertir a la máxima velocidad de reloj, pero empleando el
// temporizador 0 como fuente de disparo (Timer/Counter0 Compare Match A).
ADCSRA |= (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2);
// Estos determinan el factor de division entre el la frecuencia
// del sistema de reloj entre la entrada del reloj y el ADC // Pag

ADMUX |= (0<<ADLAR); // indica que ADLAR tiene que estar en 1


// Revisar Tablas 23.9.3.1.1 & 23.9.3.1.2 pagina 219
ADMUX |= (1 << REFS0) | (0 << REFS1); // esto quiere decir que se toma como referencia los
3 ADTS0/1/2
// porque esto se da de acuerdo a una condicion de trigger source
// de la tabla 23.6 pagina 220 Datasheet
ADMUX |= (0 << MUX0) | (0 << MUX1) | (0 << MUX2) | (0 << MUX3);
// todo esto va de acuerdo a la entrada negativa de comparador Analoga
// paginas 202 – pagina 218
ADCSRB |= (0 << ADTS0) | (0 << ADTS1) | (0 << ADTS2);
// esto quiere decir que se toma como referencia los 3 ADTS0/1/2
// porque esto se da de acuerdo a una 7ondición de trigger source
// de la tabla 23.6 pagina 220 Datasheet
ADCSRA |= (1 << ADEN) | (1 << ADSC) | (1 << ADATE);
ADCSRA |= (1 << ADIE);
//Programacion Timer 1 para PWM:

TCCR1A |=(1<<COM1A1)| (0<<COM1A0)|(1 << COM1B1) | (1 << COM1B0) | (0 << WGM11) |


(0 << WGM10);
// estos bits controlan 0C1A & 0C1B por lo cual la funcionalidad de entrada/salida
// y es conectada para un normal puerto de operacion, un reset, un clear o un toggle
// tabla 15.2 para no tener PWM
TCCR1B = (0 << ICNC1) | (0 << ICES1) | (1 << WGM13) | (0 << WGM12) | (0 << CS12) | (0
<< CS11) | (1 << CS10);
// el bit 7 es para cancelar el ruido
// el 6 para ajustar una caida o una pendiente de acuerdo a la captura
// el 5 es un bit para uso futura
// 4 y 3 son para generar ondas
// del 2 al 0 es para selecicionar el counter del reloj.
OCR1A = 63999; // = 16000000 / (1 * 250) - 1 (debe ser menor a <65536)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare"
OCR1B = 63999; // = 16000000 / (1 * 250) - 1 (debe ser menor a <65536)
// encendiendo modo de conteo CTC mode ver tabla 19-9 "clear timer on compare"
sei();
ADCSRA |= (1 << ADSC);
}
void loop() {
// Se lee dato y envía hacia el puerto serial.
if (readFlag=true)
{
readFlag=false;
enviardato();
}
}
void enviardato() {
Serial.println(analogVal);
//Serial.println("1");
}

ISR(ADC_vect)
{
TIFR0 |= (1 << OCF0A); // Bajar la bandera del disparo por timer0.
readFlag = true;
// Leer dato
analogVal = ADCL | (ADCH << 8);
OCR1A = analogVal;
OCR1B = analogVal;

}
ISR(TIMER0_COMPA_vect){
}

Los codigos pertinentes se define que la primera parte es esencial, dado que esta programación se da para la
configuración de los timers, se han programado por medio de Registros. En sí el análisis que se realizó a
través de PWM, es uno de los conceptos necesarios, para desarrollar la implementación de modulación por
ancho de Impulsos, por medio de una interrupción definida, por lo que El PWM debe operar de 2 formas en
forma Fase & Frecuencia Correcta y en una fase rápida, por lo que partiendo de la figura 15.9 que se encuentra
en la pagina 105 del Documento de Manual Del Microcontrolador donde define cada una de las interrupciones
definidos para los registros OCR1X, el TCNTn, los canales donde el timer tiene un ciclo de reloj en un registro
como es el OCR1x donde se actualizan a un buffer de valor doble, donde resume la implementación y
comportamiento de acuerdo a la cuenta de un top, donde dicha lectura se da partiendo de las alteraciones que
sufre la onda.

Por lo que para el caso 8, en la tabla 15-5 pagina 109 La tabla de Waveform Generation Mode Bit Description,
muestra que tiene una medición de Top que al realizar la operación por medio de potencias de 2 se obtiene lo
siguiente:

210 = 1024

Por lo que mínimo se necesitan 10 bits del registro, además de los valores iniciales de acuerdo a cada uno de
los registros, esto aplica para el Registro OCR1X, tanto para A – B.

El segundo Codigo tiene como prioridad activar las interrupciones para realizar las respectivas mediciones de
las señales, por lo que para el registro del caso 7, es similar dado que hay un momento en que se configura el
registro TCCR1B, para posicionarlo en el set de cada uno de los bits correspondientes al PWM, esta
información respectiva se encuentra en la figura 14.6 Fast PWM Mode, Timing Diagram, que indica un
diagrama de Tiempos para un PWM en Modo Rapida, con los respectivas Graficas de cada uno de los registros
presentes, pero de acuerdo a lo anterior se puede observar claramente que para cada uno de los diferentes
manejos en la fase de onda, de acuerdo a la conexión implementada del circuito incluyendo el código, dado
que para conseguir reconstruir la señal baja un poco su calidad perdiendo información fundamental en la
implementación.

Mode Case 8

Figura 1. Comparación de Señal PWM con Señal Filtrada por Filtro Analogo(Butterworth)

Esta figura muestra una señal PWM con una señal PWM, de la cual la señal generada del filtro pasabajos es
la señal coseno que muestra que al realizar un filtro sobre la señal PWM se obtiene la señal de Entrada que es
la que se Define en la Señal de Entrada.

Figura 2. Señal de Entrada con Frecuencia de 35Hz.

Partiendo de la señal obtenida se procede a ingresarla al filtro que es la que por ende transforma la señal PWM
en la señal de Entrada, por lo que la figura 3 muestra como la señal de entrada creada de acuerdo con el
generador de funciones, donde respecto a la segunda señal obtenida se obtiene una fase, donde debido a la
configuración del PWM se configura de tal forma que se corrija la fase y la frecuencia de la señal de salida,
por lo que si a la salida al no ingresarle el PWM configurado desde el código de Arduino se presenta algo de
ruido sobre la señal por lo que al generar la fase se pudo evidenciar que la fase se da por el Filtro Butterworth
más no por el PWM que era lo que se esperaba.

Figura 3. Comparación de señal de entrada con señal filtrada con filtro análogo.
La primer señal la amarilla, es la señal que se genera sobre el generador de funciones y la punta del canal 1,
la segunda es la que proviene del pin de salida del Arduino, del pin 9, por lo que esta señal se generó dejando
la conexión positiva es decir un cable sin conectar a un cable que viene referenciado de la segunda fuente

Mode case 7

Figura 4. Señal PWM Con respecto a señal filtrada a análoga


Al configurar el modo 7 de acuerdo al código para modo rápido, muestra una atenuación en la señal de salida,
que no se encuentra en el momento de modificar la frecuencia y su fase, pero esta atenuación se da por el
circuito empleado es decir el circuito referente al filtro análogo.

Figura 5. Comparación de señal de entrada con señal filtrada con filtro análogo.
Analizando las señales de entrada y la generada por la salida del filtro se obtiene una señal de salida con
desfase y atenuación en cuanto a la magnitu de voltaje.

Análisis de resultados

Partiendo de los 2 casos de PWM, es decir, el caso 7 y el caso 8, es decir los de frecuencia-fase Correcta y el
modo rápido, se puede mostrar que el resultado sin duda, estuvo en un rango aceptable, en la conversión D/A,
por lo que el desfase en las señales una vez más se puede evidenciar que no se da por la conversión de Digital
a Analogo, sino que se atribuye al filtro pasabajos, esto se dió en ambos casos.

Por otro lado en el caso 7 al aplicar una frecuencia rápida, se puede ver que el filtro y las graficas generadas
sobre el osciloscopio tienen modificaciones en su fase, al aumentar su periodo, se evidencia que este cuenta
como un periodo de tipo activo, por lo que la recta generada cambia de posición, con su fase.

Que el filtro no desfase la señal no quiere decir que no se desfase, por lo que en si el filtro desfasa la señal
con un poco de atenuación generando ruido, por lo que se pudo comprobar en la señal del circuito generado.
Conclusiones y recomendaciones

Para cada caso, y cada modo que requiera implementar, se debe aplicar un registro, ya que no todo código
generado para PWM, por lo que cada modo se tiene en cuenta dado que representan la estabilidad sobre la
señal dada su fase, y por ello incurre en la velocidad que se procesa la señal, por ello los códigos generados
muestra las respectivas diferencias entre la atenuación de las señales, las conexiones pertinentes, dado que al
realizar la práctica individual se pudo observar que la atenuación de la señal esta en definir los registros
TCNT, OCR1x, la configuración del timer, los diferentes diagramas de tiempo, las tablas de Generador de
Ondas de acuerdo a los bits requeridos, y la utilización de los 10 bits para un efectivo procesamiento de
señales, en este caso la de modulación de PWM.

Las conversiones de Digital-Análogo de un filtro DAC se puede ver como un resultado aceptable de acuerdo
a lo establecido inicialmente partiendo de la practica anterior y parte de los parámetros para esta practica,
donde su finalidad era evidenciar la salida de una señal por PWM, y como esta salida era muy similar a la
señal de entrada, teniendo en cuenta algunos de los datos que se pierden del muestreo sobre cada una de las
señales.

La elección de los timer es clave dado que ello implica utilizar una cantidad estimada de bits, y destinar un
cierto espacio de memoria partiendo también del uso que requiere el microcontrolador para efectuar las
debidas operaciones sobre cada uno de los contadores del sistema, partiendo que en total se uso solo el 6% de
espacio de almacenamiento y de acuerdo a los registros, y algunas variables globales se uso el 9% , por lo que
una vez más se puede ver que dependiendo del timer que se elija la cantidad de memoria a usar varia de
acuerdo a lo que se le suministre propiamente al microcontrolador.

1. Referencias

1] Atmel. (2019/09/07). Atmel-7810-Automotive-Microcontrollers-Atmega328P_Datasheet. Recuperado de:


https://uvirtual.javeriana.edu.co/bbcswebdav/pid-273526-dt-content-rid-
1504227_1/courses/031680_1930_2664/Atmel-7810-Automotive-Microcontrollers-
ATmega328P_Datasheet.pdf

Potrebbero piacerti anche