Pedro Ribeiro, Rafael Sartor e Ronaldo Campos
A sinalização DTMF - Dual-tone multi-frequency – permite trocar dados de controle dentro da banda de voz das linhas telefônicas analógicas. Cada tom gerado nesse tipo de sinalização é a composição de duas freqüências distintas não-relacionadas.
A Figura mostra quais são essas freqüências para os diferentes dígitos
utilizados para sinalizações no estabelecimento/progresso de ligações telefônicas
É interessantes vermos essas freqüências organizadas relativamente ao formato
de teclado telefônico original da Bell, como mostrado na Figura . Da figura
podemos notar que as interseções das linhas e colunas definem o par de
freqüências que formam cada dígito.
O algoritmo de busca direta (direct look-up) para geração dinâmica de formas de onda [1] sugere um algoritmo para a geração dinâmica de formas de onda. O algoritmo de busca direta proposto utiliza uma tabela com N entradas dos valores da senóide como base para produzir qualquer das freqüências utilizadas no DTMF.
Uma freqüência de amostragem (Fs) define a freqüência com que novas amostras da tabela são obtidas e enviadas para o conversor A/D. Um registrador denominado Acumulador de fase é utilizado para indicar a linha da tabela que deve ser acessada na presente amostragem (fase corrente) e na freqüência Fs o Acumulador é incrementado de um valor Delta. O Acumulador é utilizado “módulo N” para que os acessos que ultrapassem o tamanho da tabela sejam feitos no seu inicio.
O valor de Delta define então o intervalo entre uma e a próxima amostra tomadas da tabela. Fazendo Delta igual a 1 o algoritmo percorrerá todas as N entradas da tabela, o que resultaria na reprodução da forma de onda da senóide na freqüência Fs de amostras. O tempo Tgen para geração de um período da forma de onda seria então o tempo para percorrer todas as N amostras na freqüência Fs:
![]() |
(1) |
Se fizermos Delta igual a 2, somente metade das amostras na tabela serão percorridas e portanto, percorrendo-as na mesma freqüência Fs, o tempo Tgen para gerar um período da forma de onda cai pela metade:
![]() |
(2) |
A freqüência gerada (Fgen) é 1/Tgen e portando:
![]() |
(3) |
Pelo critério de Nyquist (a freqüência no sinal analógico não pode ter componentes de freqüência maior que metade da taxa de amostragem) Delta é uma quantia fracionária válida no intervalo:
![]() |
(4) |
Assim, para produzir uma data frequência o algoritmo segue os seguintes passos:
Como DTMF utiliza a síntese simultânea de dois tons, o algoritmo acima deve ser estendido para fazê-lo. Para isso são utilizados acumuladores e deltas separados para cada uma das freqüências. Em cada amostra são calculados os valores dos deltas separadamente para cada freqüência desejada e incrementados os acumuladores. São extraídos então dois valores da tabela seno. Esses valores são somados algebricamente e o resultado é enviado para o decodificador D/A. É preciso, no entanto, tratar ou evitar a ocorrência de um possível overflow nesta soma.
A plataforma alvo é o microcontrolador MC9S12NE64 da Motorola. Este microcontrolador é composto de uma unidade de processamento de 16 bits (HCS12), 64Kbytes de FLASH EEPROM , 8K bytes de RAM e um conjunto de periféricos e está instalado sobre a placa de demonstração da Motorola EVB9S12NE64.
Os dispositivos utilizados no projeto estão instalados no kit AXM-232 da Motorola fabricada pela Axiom. O AXM-232 não possui um microcontrolador, é basicamente um conjunto de dispositivos de I/O independentes e as portas para controlá-los. A Figura X mostra a placa destacando os componentes utilizados: um teclado telefônico, um display LCD, um auto-falante e um decodificador D/A.
O keypad existente no kit AXM-232 é um padrão telefônico com 3 colunas e 4 linhas. Com essa configuração ele utiliza 7 pinos para interface com o controlador, um para cada linha e coluna.
A EVB9S12NE64 possui um conector para keypad de 8 pinos, suportando dispositivos com 16 teclas ( 4 linhas e 4 colunas). Os pinos 1 a 4 desse conector estão ligados aos pinos 0 a 3 da porta H da MCU, e os pinos 5 a 8 do conector aos pinos 0 a 3 da porta J.
O funcionamento do keypad ocorre da seguinte forma, os quatro primeiros pinos são de saída e servem para alimentar as linhas da matriz que serão escaneadas, logo se quiser escanear todas as linha deve-se ativar os 4 pinos. Os pinos 5 a 8 são de entrada, e servem para ver qual coluna de uma linha está ativa, indicando a tecla que está pressionada. O nosso algoritmo funciona dessa forma. Primeiro ativamos todas as linhas para ver se alguma possui um botão apertado. Se lermos um valor diferente de zero em um dos pinos de entrada então passamos a buscar em qual linha ele está localizado, ativando uma de cada vez, até que seja lido um valor diferente de zero em um dos pinos. Para falsos contatos nas teclas um mecanismo simples de debounce foi utilizado, é verificado oito vezes se a mesma tecla está pressionada antes de passar para o próximo estágio, display e ativação do áudio.
O kit AXM-232 também possui um display de LCD, de 16 caracteres e 2 linhas. Cada caractere pode ser mostrrado com uma resolução de 5x7 ou 5x10 pontos. A largura de barramento de dados utilizada é de 4 bits, o que implica no fato de cada escrita de um caractere ter que ser feita em duas partes, primeiro os 4 bits mais significantes e depois os 4 menos.
Para transmitir os dados é utilizada a interface SPI (Serial Peripheral Interface) do controlador. O próprio EVB possui um conversor de serial para paralelo que transforma as transações SPI para a pinagem utilizada pelo LCD. Os pinos do LCD usados são:
Cada escrita no LCD necessita de 3 tranferências do SPI, a primeira deve conter os dados e a seleção do registrador (RS), a segunda os mesmos dados com EN ativo e a terceira os dados com EN desativado.
A inicialização do LCD deve ocorrer seguindo a sequência de comando ilustrada na figura :
Seguimos a implementação sugerida em [1].
Delta é representado por um valor de 2 bytes referido como Dreg. O byte superior armazena a porção inteira e o byte inferior a porção fracionária.
O valor decimal de Delta é então:
![]() |
(5) |
e portanto
![]() |
(6) |
O valor de 16 bits do Dreg é então adicionado ao acumulador em cada período de amostragem para gerar o índice da tabela.
Uma das decisões de projeto é a definição do tamanho da tabela seno. É preciso definir tanto o número de entradas na tabela como o tamanho dos valores armazenados nela. Por limitações de espaço os valores terão tamanho de 1 byte. A tabela terá 256 entradas; com igual a 256 o índice da tabela necessita ter 8 bits, o que é muito conveniente nessa arquitetura e dispensa a necessidade de mascaramento do acumulador (é somente necessário utilizar o byte da parte inteira do acumulador, o que pode ser feito diretamente). Como o firmware é pequeno o tamanho de 256 bytes da tabela é tranqüilamente viável.
Exemplo:
Dados: ,
, e
(a DTMF freqüência mais alta)
da equação 1, isolamos ,
![]() |
(7) |
As partes inteira e fracional (byte alto/byte baixo) são representados como:
Inteira = 0
Fracionária = 0.4180 * 256 = 107.008 (arredondado para o inteiro mais próximo) = $6B
Dreg = $006B
O byte alto (da parte inteira) do acumulador é então utilizado para indexar a tabela do seno de 256 bytes.
No caso de DTMF o procedimento anterior seria realizado para duas frequências distintas e os dois valores retirados da tabela necessitaria
O problema do overflow na soma dos dois valores D/A das duas frequências pode ser facilmente contornado nesta arquitetura executando um ROR no registrador que contém o resultado da soma. A instrução ROR rotaciona os bits para a direita (dividindo o valor por dois) carregando no bit mais significativo o valor do carry (1 no caso de overflow).
Como a AXM-232 possui um conversor D/A (LTC161), optamos pela conversão direta ao utilizar PWM, o que diminui a complexidade do código no firmware.
O LTC161 é um 10 bits de entrada serial.
Sua função de transferência é dada por:
![]() |
(8) |
Sua interface serial recebe palavras de 16 bits, sendo quatro do código de controle, 10 bits do código de entrada e 2 bits don't care.
A frequencia de amostragem Fs, necessita ser tal que o decodificador D/A seja capaz de decodificá-las na mesma frequência.
Supomos que o decodificador trabalhe de maneira correta na mesma frequência do barramento do microcontrolador que é de 16MHz apesar da proximidade deste valor com a frequência máxima nominal do dispositivo de 16.7MHz.
Calculamos o período para essa frequencia:
![]() |
(9) |
Calculamos então o número de períodos necessários para um ciclo completo de decodificação.
O tempo de setup (100ns) e o tempo necessário para o envio do código de 16bits (1us) podem ser desconsiderados perto dos 30us necessários para o fim da decodificação.
São então necessários
![]() |
(10) |
Uma frequência de amostragem viável é então:
![]() |
(11) |
![]() |
(12) |
Este valor é razoável pois ultrapassa em muito o mínimo definido pelo critédio de Nyquist para a frequencia máxima que desejamos gerar (1.633Hz). Utilizaremos o valor conveniente de 31,25KHz para Fs, já que é o resultado na divisão da frequencia do barramento do microcontrolador por 29 o que nos permite utilizar um divisor facilmente.
main.asm Código fonte do programa principal
Project.zip Projeto para o CodeWarrior
Pedro Ribeiro 2009-07-08