Usando un PIC para la Generación de Tonos de Audio



Documentos relacionados
Usando los Codificadores Cuadráticos

Temporizadores y contadores en tiempo real: El módulo Timer0 y el prescaler del PIC

TRANSMISION DIGITAL. PCM, Modulación por Codificación de Pulsos

Unidad I. 1.1 Sistemas numéricos (Binario, Octal, Decimal, Hexadecimal)

Maqueta: Osciloscopio y generador

DISEÑO E IMPLEMENTACIÓN DE UNA TARJETA DE ADQUISICIÓN DE DATOS PARA EL LABORATORIO DE TELECOMUNICACIONES DE LA FIEC.

Aprendiendo a programar Microcontroladores PIC en Lenguaje C con CCS

CONVERTIDORES DIGITAL ANALÓGICO Y ANALÓGICO - DIGITAL

DESCRIPCION DEL SITEMA MASTER.

Unidad 1. La información

CAPÍTULO 3. Las principales funciones del microcontrolador son: adquirir por medio del A/D y también, mostrar mensajes de pesos y voltaje en el LCD.

22.1. t, ms. Y la frecuencia mínima de muestreo será: f smín = 1/T máx = 1/0,1µs = 10MHz.

UNIVERSIDAD SIMÓN BOLÍVAR VICERRECTORADO ACADÉMICO DECANATO DE ESTUDIOS TECNOLÓGICOS COORDINACIÓN DE TECNOLOGÍA ELÉCTRICA Y ELECTRÓNICA

Control de un módulo LCD a través del bus I2C

Gestión digital sencilla de controladores de fuentes de alimentación analógicas

❷ Aritmética Binaria Entera

by Tim Tran:

JUEGO DE CARRERA DE AUTOS EN LCD

podemos enfocar al funcionamiento del robot, es decir la parte de electrónica. Para que el

Clase 02: Representación de datos

Anexo B. Comunicaciones entre mc y PC

Matemática de redes Representación binaria de datos Bits y bytes

Curso sobre Microcontroladores Familia HC9S08 de Freescale

Los sistemas de numeración se clasifican en: posicionales y no posicionales.

3rasJornadasITE-2015-FacultaddeIngeniería-UNLP PROCESAMIENTO DIGITALSOBRELAPLACABASELPC1769. Anderson,Jorge;Osio, Jorge;Kunysz,EduardoYRapalini;José

Filtros pasa banda. Filtro pasa bajos. Filtro pasa medios Filtro pasa altos

Objetivo. Desarrollo. Práctica 6 Multiplexado. Sección 1 Estudio del comportamiento de un circuito sample and hold

Tema 3. Medidas de tendencia central Introducción. Contenido

Apuntes de Microcontroladores (Repaso de temas previos)

Capítulo 1 CAPÍTULO 1-INTRODUCCIÓN-

Sistemas de Numeración Operaciones - Códigos

Informática 1 Sistemas numéricos: decimal, binario, octal y hexadecimal FCFA Febrero 2012

Sistemas de numeración y aritmética binaria

UNIDADES DE ALMACENAMIENTO DE DATOS

Tema 2. La Información y su representación

Tema 07: Acondicionamiento

Preguntas teóricas de la Clase N 5

Informática Bioingeniería

SOMI XVIII Congreso de Instrumentación MICROONDAS JRA1878 TRANSMISIÓN DE AUDIO Y VIDEO A TRAVÉS DE FIBRA ÓPTICA CON PREMODULACIÓN PCM

CATEDRA de PROYECTO FINAL

CAN-101, HT6P20x2 Encoder para aplicaciones remotas de control

CASO PRÁCTICO DISTRIBUCIÓN DE COSTES

DESARROLLO DE HABILIDADES DEL PENSAMIENTO LÓGICO

Sistemas de numeración

En el presente capítulo se describe la programación del instrumento virtual y cómo

Unidad de trabajo 2: INFORMÁTICA BÁSICA (primera parte)

SIIGO Pyme. Templates. Cartilla I

Centro de Capacitación en Informática

CAPÍTULO 5. PRUEBAS Y RESULTADOS

Un filtro general de respuesta al impulso finita con n etapas, cada una con un retardo independiente d i y ganancia a i.

1. SISTEMAS DIGITALES

SISTEMAS DE NUMERACIÓN. Sistema decimal

Capítulo 1: Sistemas de representación numérica Introducción. Dpto. de ATC, Universidad de Sevilla - Página 1 de 8

Fundamentos de Investigación de Operaciones Investigación de Operaciones 1

Ecuaciones de primer grado con dos incógnitas

TELECOMUNICACIONES ANALÓGICAS Y DIGITALES

Control Digital en PC con MS-DOS

SALIDAS ANALÓGICAS. Adquisición de datos y acondicionamiento de la señal Tema 6

!!!!!!!! !!!!! Práctica!4.! Programación!básica!en!C.! ! Grado!en!Ingeniería!!en!Electrónica!y!Automática!Industrial! ! Curso!2015H2016!

Propuesta de Portal de la Red de Laboratorios Virtuales y Remotos de CEA

Lección 1. Representación de números

Cualquier número de cualquier base se puede representar mediante la siguiente ecuación polinómica:

Cuestionario: Programación en C y máscaras (II)

Conclusiones, aportaciones y sugerencias para futuros trabajos

Cifras significativas e incertidumbre en las mediciones


5. Despliegue en la PC

INSTITUTO POLITÉCNICO NACIONAL ESCUELA SUPERIOR DE INGENIERÍA MECÁNICA Y ELÉCTRICA UNIDAD CULHUACÁN INTEGRANTES

MODIFICACIÓN DEL MINITNC PARA MANDAR

SISTEMAS NUMERICOS CAMILO ANDREY NEIRA IBAÑEZ UNINSANGIL INTRODUCTORIO A LA INGENIERIA LOGICA Y PROGRAMACION

INFORMÁTICA. Práctica 5. Programación en C. Grado en Ingeniería en Electrónica y Automática Industrial. Curso v1.0 (05.03.

Procesamiento Analógico de Señales

Charla N 6: Utilidades de Consulta de datos.

ANEXO 2: REPRESENTACION DE LA INFORMACION EN LOS COMPUTADORES

DISCOS RAID. Se considera que todos los discos físicos tienen la misma capacidad, y de no ser así, en el que sea mayor se desperdicia la diferencia.

Naturaleza binaria. Conversión decimal a binario

Tema 4: Sistemas de Numeración. Codificación Binaria. Escuela Politécnica Superior Ingeniería Informática Universidad Autónoma de Madrid

CODIFICADORES. Cuando solo una de las entradas está activa para cada combinación de salida, se le denomina codificador completo.

Figura 1. Símbolo que representa una ALU. El sentido y la funcionalidad de las señales de la ALU de la Figura 1 es el siguiente:

LIMITE DE SHANON PARA LA CAPACIDAD DE INFORMACIÓN

Materia: Informática. Nota de Clases Sistemas de Numeración

CRIPTOGRAFÍA SIMÉTRICA Y ASIMÉTRICA

TEMA 2: Representación de la Información en las computadoras

CAPÍTULO 2 INTERFASE VISUAL BASIC 6.0

T6. CIRCUITOS ARITMÉTICOS

Sistemas Digitales Ingeniería Técnica en Informática de Sistemas Curso Aritmética binaria

CAPITULO II CARACTERISTICAS DE LOS INSTRUMENTOS DE MEDICION

SISTEMAS NUMERICOS. Ing. Rudy Alberto Bravo

Instituto Tecnológico de Celaya

EJERCICIOS RESUELTOS SOBRE ERRORES DE REDONDEO

UNIDAD 3: ARITMÉTICA DEL COMPUTADOR

Tema I. Sistemas Numéricos y Códigos Binarios

Capítulo I. Convertidores de CA-CD y CD-CA

EJERCICIOS DEL TEMA 1

ANTENAS: CONCEPTOS TRIGONOMETRICOS

Instituto Tecnológico de Massachussets Departamento de Ingeniería Eléctrica e Informática Circuitos electrónicos Otoño 2000

11 Número de publicación: Int. Cl.: 72 Inventor/es: Okabe, Shouji. 74 Agente: Sugrañes Moliné, Pedro

En la actualidad ASCII es un código de 8 bits, también conocido como ASCII extendido, que aumenta su capacidad con 128 caracteres adicionales

Los polinomios. Un polinomio es una expresión algebraica con una única letra, llamada variable. Ejemplo: 9x 6 3x 4 + x 6 polinomio de variable x

Transcripción:

Usando un PIC para la Generación de Tonos de Audio Autor: Ing. Carlos Narváez Universidad de Oriente email: cnarvaez@udo.edu.ve Introducción Existen varias maneras de implementar la generación de tonos de audiofrecuencia de manera digital usando software: tabla Lookup, interpolación, aproximaciones polinomiales y filtros digitales. Esto tiene aplicación en la generación de tonos DTMF, la síntesis de sonidos de diferentes frecuencias, Modulación etc.. En microcontroladores es poco práctico el uso de métodos tradicionales, como la aproximación por series, CORDIC o filtros digitales. La técnica denominada tabla lookup resulta bien apropiada, sin embargo la literatura acerca del tema resulta algo confusa. El presente trabajo enfoca el tema de una manera sencilla y práctica lo que permitirá al lector realizar sus propios desarrollos, tanto de hardware como de software. El mismo aborda, la generación de ondas sinusoidales de diferentes frecuencias partiendo del acceso a una tabla de senos previamente construida y almacenada en el programa. La frecuencia generada esta en función de un valor incremento agregado a un apuntador utilizado para acceder a la tabla en cada periodo de muestreo. Como salida se puede utilizar el módulo PWM o algún DAC externo. Finalmente se revisa la aplicación práctica de generar tonos DTMF. A pesar de que existen un gran número de circuitos integrados análogos que pueden realizar estas funciones, hay dos razones fundamentales para considerar la generación de tonos usando software: la primera es que normalmente existe un microcontrolador como parte del producto final, por lo que generar tonos por software ahorra muchos componentes de hardware necesarios para realizar esta función. La segunda es la flexibilidad que ofrece la implementación por software la cual resulta inexistente o cara cuando se implementa por hardware. Generando la Tabla de Senos Una de las primeras confusiones es como generar la tabla de senos que encontramos en muchos programas y cuales son sus distintas variantes. El caso general, cuando utilizamos 16 bits para almacenamiento, implica generar 65536 muestras 2 16. Utilizando programas como Matlab podemos realizar esto de la siguiente manera: Y = sin( 2π * N 65536) 0 N 65535 Escalando por 32767, es decir: Y = 32767 *sin(2π * N 65536) Obtenemos un rango que va desde 32767 a +32767 apropiado al utilizar números en complemento a 2 de 16 bits. Más exactamente, la tabla es generada utilizando: y= fix(65536.0*sin(pi*n/65536.0)+0.5)

Naturalmente una tabla de 65536 entradas no es apropiada, pues utiliza mucha memoria, por lo que normalmente se utilizan tablas de 256 y 128 entradas, generadas de la siguiente manera: Y Y = 127 *sin(2π * N 256) 0 N 255 = 63*sin(2π * N 128) 0 N 127 En el primer caso se escala por 127 lo que da una rango de 127 a +127 apropiado cuando se utiliza números complemento a 2 de 8 bits. En el segundo se escala por 63 para un rango de 63 a +63 apropiado para números complemento a 2 de 7 bits. Se puede también generar tablas de 64 entradas y escalar a 63 para mantener el rango entre 63 y +63 es decir: Y = 63*sin(2π * N 64) 0 N 63 En este caso tenemos 64 muestras cuyo escalamiento natural debería ser 31 para obtener un rango entre 31 y +31. El efecto de escalar a 63 es que los valores quedan representados en 7 bits y al convertirlos en formato unipolar sin signo, como veremos más adelante, el valor máximo es 127. Si tuviéramos que sumar dos ondas como en el caso de la implementación de tonos DTMF, el valor máximo sería 127+127 = 255 es decir 8 bits que pueden ser aplicados directamente a un DAC de 8 bits. Asimismo es posible utilizar un solo cuadrante de la tabla (0 a π/2) ó 65 entradas en el caso de una tabla generada de 256 entradas y utilizar algunas identidades trigonométrica en el programa para cubrir la totalidad de un ciclo de onda seno. Veamos algunos ejemplos: La siguiente tabla de 65 valores (0 a 90 grados) fue calculada de la siguiente manera: Y = 127 *sin(2π * N 256) 0 N 255 Se tomaron sólo 65 valores que representan el seno del primer cuadrante en hexadecimal: 000h,003h,006h,009h,00ch,010h,013h,016h 019h,01ch,01fh,022h,025h,028h,02bh,02eh 031h,033h,036h,039h,03ch,03fh,041h,044h 047h,049h,04ch,04eh,051h,053h,055h,058h 05ah,05ch,05eh,060h,062h,064h,066h,068h 06ah,06bh,06dh,06fh,070h,071h,073h,074h 075h,076h,078h,079h,07ah,07ah,07bh,07ch 07dh,07dh,07eh,07eh,07eh,07fh,07fh,07fh 07fh La siguiente tabla dada en decimal, consta de 64 muestras y fue generada de la siguiente manera: Y = 64 + 63* sin(2π * N 64) 0 N 63

64,70,76,82,88,94,99,104,109,113,117,120,123,125,126,127 127,127,125,124,121,118,115,111,107,102,97,91,85,79,73,67 60,54,48,42,36,30,25,20,16,12,9,6,3,2,0,0 0,1,2,4,7,10,14,18,23,28,33,39,45,51,57,63 Al agregar el valor 64, los números son convertidos de complemento 2 a unipolar sin signo como veremos más adelante. La tabla 1, representa un ciclo completo de una onda sinusoidal utilizando 256 entradas en complemento 2 y en hexadecimal: Tabla 1. Seno(x) 256 entradas Complemento 2 y Hexadecimal

Conversión Números Complemento 2 a Unipolar sin signo Como hardware de salida normalmente se utiliza el módulo PWM o un convertidor Digital/Analógico los cuales utilizan valores unipolares sin signo. Para convertir números complemento 2 a formato unipolar sin signo, le sumamos 32768 en caso de números complemento a 2 de 16 bits, 128 en caso de 8 bits y 64 en el caso de 7 bits. Si la tabla es generada, de tal manera, que no incluya números en complemento 2 entonces los valores obtenidos pueden ser aplicados directamente al módulo PWM o al convertidor DAC. Esto es, generar la tabla de la siguiente manera: y = 32768 + 32767 * sin(2π * N 65536) Caso 16 bits y = 128 + 127 *sin(2π * N 256) Caso 8 bits y = 64 + 63* sin(2π * N 128) Caso 7 bits La figura 1 muestra la gráfica de 128 muestras en el rango 64 a +63 y la fig. 2 muestra la misma gráfica con sus valores convertidos a formato unipolar sin signo. Estos últimos valores pueden ser aplicados directamente al módulo PWM o un DAC externo. 80 y=63*sin(2*pi*n/128 60 40 20 0-20 -40-60 -80 0 20 40 60 80 100 120 140 N Fig. 1 Valores en complemento 2.

140 y=64*63*sin(2*pi*n/128 120 100 80 60 40 20 0 0 20 40 60 80 100 120 140 N Fig. 2 Valores Unipolares sin signo Frecuencia de Muestreo Una vez construida la tabla, necesitamos definir la frecuencia de muestreo. Esto es cada cuanto tiempo T debo acceder a la tabla continuamente. Así la frecuencia de muestreo puede definirse como: T = 1 Fs Donde Fs es la frecuencia de muestreo en Hz. Si tenemos una tabla de 128 muestras que corresponden a un ciclo completo de una onda sinusoidal y las tomamos de la tabla una a una cada T segundos ó a una frecuencia Fs = 1 T, entonces se generará una onda sinusoidal cuya frecuencia es: F = FS 128 Suponiendo Fs = 8Khz tenemos: F = 1 8000 = 62. 5Hz De acuerdo con Nyquist la frecuencia de muestreo debe se por lo menos el doble que la frecuencia más alta que se desee generar, así, si usamos una frecuencia de muestreo de 8Khz, podemos generar señales de hasta 4Khz.

Como vimos anteriormente la tabla se accedió con un incremento de 1 en cada periodo de muestreo, es decir tomamos el primer valor en la tabla, luego el segundo y así sucesivamente. Pero que pasa si tomamos el primer valor de la tabla, luego el tercero, luego el quinto y así sucesivamente, entonces la frecuencia generada es: F = 2 * Fs 128 = 125Hz En general la frecuencia generada para 128 muestras de un ciclo completo es: F = incremento * Fs 128 donde, 1 incremento 64 Si incremento es igual a 64, se puede obtener la máxima frecuencia que en este caso es 4000Hz según Nyquist. Algunas características del método Tabla Lookup Cualquier forma de onda puede ser generada con este método, con sólo cambiar los valores almacenados en la tabla. Adicionalmente, varias señales, pueden ser generadas, realizando múltiples accesos a la misma, las señales pueden ser sumadas y luego enviadas al DAC. Se pueden usar varias tablas o sólo una con el fin de ahorrar memoria. Ondas de diferentes frecuencias pueden ser generadas de una misma tabla usando la técnica que se describe más adelante. También deben evitarse los overflow por suma, escalando los datos a valores apropiados, técnica que también será tratada más adelante. La amplitud de la onda de salida, puede ser variada digitalmente, multiplicando cada muestra por un factor de escala antes de que sea enviada al DAC. Esta también puede ser controlada por hardware externo, bien sea el DAC o circuitos analógicos basados en amplificadores operacionales. Cambiando la Frecuencia de la Señal de Salida Para cambiar la frecuencia de salida, se puede variar la frecuencia de muestreo, pero esta no es la mejor manera de hacerlo, particularmente en telecomunicaciones, donde la mayoría de los sistemas requieren de una frecuencia de muestreo fija. Una manera más apropiada es almacenar en la tabla más muestras que las necesarias y entonces saltar un número especifico de muestras para cada valor enviado al DAC. Ya que la frecuencia de salida es igual a la frecuencia de muestreo dividida por el número de muestras por ciclo de la onda, saltar un número de entradas en la tabla por cada muestra de salida (ejemplo: incremento > 1), equivale a multiplicar la frecuencia de salida, esto es: Fsalida = incremento * Fs TamañoTabla Si por ejemplo el número de entradas en la tabla es 256 (un ciclo de onda sinusoidal), la frecuencia de muestreo 8 Khz y el valor de incremento igual a 1, la frecuencia de salida es: Fsalida = 1 *8000 256 = 31. 25Hz

Si incremento es igual a 2, que implica tomar de la tabla sólo las muestras impares, entonces, la frecuencia de salida es: Fsalida = 2 *8000 256 = 62. 5Hz La resolución en frecuencia se obtiene sustituyendo incremento por 1, en este caso: Fresolucion = Fs TamañoTabla = 31. 5Hz Así, la frecuencia puede ser controlada en unidades de 31.25Hz Para incrementar la resolución en frecuencia, se puede incrementar el tamaño de la tabla, manteniendo constante la frecuencia de muestreo. También es útil acotar el rango de incremento a los límites de la tabla usando: ( TamañoTabl ) incremento = incremento & a 1 Hardware La figura 3 muestra el diagrama esquemático utilizado para la generación de una onda sinusoidal. Para ello utilizamos un PIC16F88 y un DAC MAX517, este último trabaja utilizando el bus I 2 C y es de 8 bits. VCC 0.1uf VCC RESET 10K 1N4148 100 S1 33pf 20Mhz 33pf 2 3 4 5 6 7 21 22 23 24 25 26 27 28 9 1 20 U2 RA0/AN0 RA1/AN1 RA2/AN2/VREF- RA3/AN3/VREF+ RA4/T0CKI RA5/SS/AN4 RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD OSC1/CLKIN MCLR/VPP/THV VDD PIC16F873 RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT OSC2/CLKOUT 11 12 13 14 15 16 17 18 10 4.7K 4.7K I2C BUS 4.7K U1 1 8 2 O0 O1 7 3 GNDVDD 6 4 SCL AD0 5 SDA AD1 MAX517 0.01uf 2 1 J1 Salida Fig. 3. Diagrama esquemático Generador Onda Sinusoidal

Software /******************************************************************/ /* SENO.C */ /* */ /* Programa que genera una onda sinusoidal de 15Hz */ /* usa la interrupción por desbordamiento del RTCC (timer0) y */ /* el DAC MAX517 I2C */ /* */ /* Autor: Carlos A. Narváez */ /* Fecha: septiembre, 2005 */ /******************************************************************/ #include <16F873.h> #fuses HS,NOWDT,PUT, NOPROTECT, NOBROWNOUT,NOLVP,NOCPD #use delay(clock=20000000) #define MAX517_SDA PIN_C4 #define MAX517_CLK PIN_C3 #use i2c(master, sda=max517_sda, scl=max517_clk, FAST) void write_dac(int data_byte) { i2c_start(); i2c_write(0x5e); i2c_write(0); i2c_write(data_byte); i2c_stop(); // Envía la dirección del dispositivo // Envía datos al dispositivos BYTE CONST SINE_WAVE[256] = { 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174, 177,179,182,185,187,191,193,196,199,201,204,206,209,211,213,216, 218,220,222,224,226,228,230,232,233,235,237,239,240,241,243,244, 245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255, 255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246, 245,244,243,241,240,239,237,235,234,232,230,228,226,224,222,220, 218,216,213,211,209,206,203,201,199,196,193,191,188,185,182,179, 177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131, 128,125,122,119,116,112,109,106,103,100,97,94,91,88,85,82,79,76, 74,71,68,65,63,60,57,54,52,49,47,45,43,40,38,36,34,32,30,28,26, 24,22,21,19,17,16,15,13,12,11,10,8,7,6,6,5,4,3,3,2,1,1,1,1,1,1, 1,1,1,2,2,2,3,3,4,5,6,6,7,8,10,11,12,13,15,16,17,19,21,24,26,28, 30,32,34,36,38,40,43,45,47,50,52,55,57,60,63,65,68,71,74,77,79, 82,85,88,91,94,97,100,103,106,109,112,116,119,122,125,128; BYTE sine_index; #int_rtcc void isr() { set_rtcc(0x66); // Fs = 1/4*tosc*(256-N)*rango divisor write_dac(sine_wave[sine_index]); if(++sine_index==256) { sine_index=0;

void main() { setup_counters( RTCC_INTERNAL, RTCC_DIV_8); enable_interrupts(int_rtcc); enable_interrupts(global); while (TRUE) ; Tonos DTMF La señalización DTMF (Dual Tone Multi-Frecuency) es usada para transmitir números telefónicos en la red de telefonía pública, en sistemas de seguridad, en instrumentación y adquisición de datos, en modems, etc. Aquí ilustramos los conceptos sobre generación DTMF por software, haciendo uso de microcontroladores. Como presenta la tabla 2, un tono DTMF esta asociado con una fila y una columna de un teclado de teléfono. Un tono DTMF consiste en la suma de la frecuencia de una fila con la frecuencia de una columna, transmitida por período mínimo de 50ms, seguido de un periodo de silencio de al menos 50ms. Tabla 2 DTMF Frecuencias filas y columnas Filas Teclado Columnas Teclado 1209 Hz 1336 Hz 1477 Hz 1633 Hz 697 Hz 1 2 3 A 770 Hz 4 5 6 B 852 Hz 7 8 9 C 941 Hz * 0 # D La especificación industrial de DTMF requiere de un error en frecuencia de menos del 1%, y una distorsión armónica total de menos de 10%. Adicionalmente, la respuesta en frecuencia de una línea telefónica, atenúa las frecuencias altas, por lo que la transmisión del grupo de frecuencias altas, requiere de mayor amplitud que el grupo de bajas frecuencias. Generación DTMF por Software En este proyecto se usa una tabla de seno con dos apuntadores, una para el tono columna y otro para el tono fila. Cada apuntador tiene su propio valor de incremento, tal que se puede generar tonos de diferentes frecuencias. A fin de reducir el contenido armónico al mínimo, la salida debe ser muestreada a una rata alta para así filtrar el ruido introducido por la frecuencia de muestreo. Un período de 125us, se escogió en este proyecto, el cual es un período estándar de la industria de telecomunicaciones. Calculando el incremento para los apuntadores La forma general de la ecuación es: Fsalida = incremento * Fs TamañoTabla

Donde, Fsalida: frecuencia a generar Fs: Frecuencia de muestreo TamañoTabla: Número de muestra en tabla seno para un ciclo completo Incremento: valor en que debe ser incrementado el apuntador para cada período de muestreo. Despejando incremento tenemos: incremento = Fsalida * TamañoTabla Fs Por ejemplo, para generar la frecuencia 697Hz, si la tabla de seno tiene 256 entradas, el valor de incremento es: incremento = 697 * 256 7812 = 23 Como no podemos usar un intervalo en fracción, lo redondeamos a 22. Introduciendo este valor en la ecuación, obtenemos como frecuencia generada: Fsalida = 23 * 7812 256 = 701. 86Hz Lo cual da un error en frecuencia de 0.7% lo cual es aceptable. La tabla 3, resume los cálculos realizados para una frecuencia de muestreo de 7812 Hz y una tabla de 256 entradas. Tabla 3 Cálculos Tonos DTMF Período de Muestreo 128us (7812,5Hz) Tamaño tabla 256 Frecuencia 697 770 852 941 Incremento 23 25 28 31 Frecuencia actual 701.86 763 854 946 % Error 0.7-0.92 0.29 0.53 Frecuencia 1209 1336 1477 1633 incremento 40 44 48 54 Frecuencia actual 1221 1343 1465 1648 % Error 0.96 0.5-0.83 0.91

Implementando Pre-énfasis de los tonos altos A fin de compensar la atenuación de las frecuencias altas, lo cual es característica de la mayoría de las líneas telefónicas, la amplitud de estos tonos deben estar de 1 a 3dB por encima de la amplitud de las frecuencias bajas, eso equivale a multiplicar la amplitud actual por valores entre 1.12 a 1.41. Un valor apropiado es 1.25, ya que 0.25 puede ser obtenido dividiendo la unidad entre 4 que a su vez equivale a realizar desplazamiento a la derecha de 2 bits. Cuando una frecuencia del grupo alto es leída de la tabla de seno, esta es desplazada a la derecha 2 bits (dividida por 4), entonces el mismo valor del seno es agregado al resultado, produciendo la multiplicación por 1.25. La pre-énfasis es: db = 20 log( V 2 V1) = 20 log(1.25) = 1. 94dB Calculando los valores de seno para evitar desbordamiento Los valores de la tabla seno deben ser calculados para evitar error por desbordamiento cuando dos muestras son sumadas. Si por ejemplo, se usan 16 bits para almacenar los valor de la tabla, el rango a representar esta entre 32768 y +32767. Para evitar desbordamiento, los valores deben se escalados tal que el rango esté entre 16384 y +16383. Ya que a los tonos de las columnas se le aplica pre-énfasis, el valor debe ser algo menor que el máximo. MaxSalida = MaxSin *(1 + preenfasis) Resolviendo para MaxSin, MaxSin = MaxSalida * (1 + preenfasis) = 32767 (1 + 1.259) = 14563.11 De tal manera que los valores en la tabla seno deben estar entre 14563 y +14563. Filtro Pasa Bajos Es necesario agregar un filtro pasa bajos que opere como integrador a la salida PWM del microcontrolador. En este proyecto se uso un filtro activo Butterworth de 3 orden con frecuencia de corte de 1.7 Khz, diseñado utilizando el programa FilterLab de Microchip. Este filtro utiliza un integrado LM324 alimentado con fuente de poder unipolar de 5 voltios, la misma que utiliza el resto del circuito. La fig. 5 muestra el filtro pasa bajos diseñado.

Hardware VCC 10K 10K KB1 1 2 3 4 5 6 7 8 9 * 0 # VCC Key board 10K U2 1N4148 100 S1 33pf 20Mhz 2 3 4 5 6 7 21 22 23 24 25 26 27 28 9 1 20 RA0/AN0 RA1/AN1 RA2/AN2/VREF- RA3/AN3/VREF+ RA4/T0CKI RA5/SS/AN4 RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD OSC1/CLKIN MCLR/VPP/THV VDD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT OSC2/CLKOUT 11 12 13 14 15 16 17 18 10 Salida al Filtro pasa bajos 33pf PIC16F873 Fig. 4 Diagrama Esquemático del Generador de Tonos DTMF

+5VDC 0.1uF 1K 0.1uF 3 2 + - 4 LM324 1 1K 8.2K 0.01uF 5 6 + - 7 11 Fig. 5 Diagrama Esquemático del Filtro Pasa bajos Software /*************************************************************************/ /* DTMF.C */ /* */ /* Programa para generar tonos DTMF a partir de un teclado 4x4. */ /* Usa el módulo de Captura CCP1 en modo PWM */ /* */ /* Autor: Carlos A. Narváez */ /* Fecha: Septiembre, 2005 */ /*************************************************************************/ #include <16F873.h> #fuses HS,NOWDT,PUT, NOPROTECT, NOBROWNOUT,NOLVP,NOCPD #use delay(clock=20000000) #include <kbd.c> #byte PORTA = 5 CONST unsigned int SINE_WAVE[256] = { 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174, 177,179,182,185,187,191,193,196,199,201,204,206,209,211,213,216, 218,220,222,224,226,228,230,232,233,235,237,239,240,241,243,244, 245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255, 255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246, 245,244,243,241,240,239,237,235,234,232,230,228,226,224,222,220, 218,216,213,211,209,206,203,201,199,196,193,191,188,185,182,179, 177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131, 128,125,122,119,116,112,109,106,103,100,97,94,91,88,85,82,79,76, 74,71,68,65,63,60,57,54,52,49,47,45,43,40,38,36,34,32,30,28,26, 24,22,21,19,17,16,15,13,12,11,10,8,7,6,6,5,4,3,3,2,1,1,1,1,1,1, 1,1,1,2,2,2,3,3,4,5,6,6,7,8,10,11,12,13,15,16,17,19,21,24,26,28, 30,32,34,36,38,40,43,45,47,50,52,55,57,60,63,65,68,71,74,77,79, 82,85,88,91,94,97,100,103,106,109,112,116,119,122,125,128; unsigned long index1,index2; int inc1,inc2;

#INT_TIMER2 void timer2_isr(void) { int wave = 0; wave = ((long)sine_wave[index1]+(long)sine_wave[index2])/2; set_pwm1_duty(wave); index1 += inc1; index2 += inc2; if(index1 >= 256) index1 -= 256; if(index2 >= 256) index2 -= 256; #define DTMF_ROW1 #define DTMF_ROW2 #define DTMF_ROW3 #define DTMF_ROW4 #define DTMF_COLA #define DTMF_COLB #define DTMF_COLC 23 // incremento para 700 Hz, cada 128us 26 // incremento para 750 Hz, cada 128us 28 // incremento para 850 Hz, cada 128us 31 // incremento para 950 Hz, cada 128us 40 // incremento para 1200 Hz, cada 128us 44 // incremento para 1350 Hz, cada 128us 49 // incremento para 1500 Hz, cada 128us void generate_dtmf_tone(char keypad, long duration) { index1=0; index2=0; inc1=0; inc2=0; if((keypad=='1') (keypad=='2') (keypad=='3')) inc1=dtmf_row1; else if((keypad=='4') (keypad=='5') (keypad=='6')) inc1=dtmf_row2; else if((keypad=='7') (keypad=='8') (keypad=='9')) inc1=dtmf_row3; else if((keypad=='*') (keypad=='0') (keypad=='#')) inc1=dtmf_row4; if((keypad=='1') (keypad=='4') (keypad=='7') (keypad=='*')) inc2=dtmf_cola; else if((keypad=='2') (keypad=='5') (keypad=='8') (keypad=='0')) inc2=dtmf_colb; else if((keypad=='3') (keypad=='6') (keypad=='9') (keypad=='#')) inc2=dtmf_colc; enable_interrupts(int_timer2); enable_interrupts(global); while(duration-- > 0) { delay_ms(1); disable_interrupts(global); disable_interrupts(int_timer2); set_pwm1_duty(0x80);

void main() { char k; setup_ccp1(ccp_pwm); // Configure CCP1 as a PWM // El tiempo que dura un ciclo de PWM es:(1/clock)*4*t2div*(periodo+1) // En este programa: clock=20000000 y periodo=127 // entonces el periodo PWM es: // (1/20000000)*4*1*128 = 25.6 us ó 39.06 khz // Fs = 25.6 * 5 = 7812.5 Hz. set_pwm1_duty(0x80); setup_timer_2(t2_div_by_1, 127, 5); // Timer2 se incrementa cada 200nseg // overflow cada 25.6 useg // y genera una interrupción cada // 25.6 * 5 = 128; Fs = 7812.5 Hz kbd_init(); while(true) { k=kbd_getc(); if(k!=0) generate_dtmf_tone(k, 5000);