Com apenas 16% de programa do microcontrolador, é possível realizarmos a leitura de uma memória externa pelo barramento I2C e jogar esses bytes para o registrador de PWM do PIC. Com a interrupção de TIMER 2, podemos configurar a frequência de amostragem para saída, tendo assim, uma demodulação em PCM com filtro passa-baixa (~3,4KHz) formado pelo resistor 470R e capacitor de 100nF.
Na memória, deve conter os dados de áudio vindos de um arquivo WAV. Para tanto, poderá ser gravado através de uma variedade de programas gravadores de EEPROM. Maiores detalhes nas próximas linhas.
A finalidade desse projeto, é demonstrar a possibilidade da reprodução do áudio pelo PIC. Por isso, o esquema está muito simples.
Devido a simplicidade do circuito, não irei disponibilizar lay out de PCB.
Preparando o Áudio
Como foi descrito acima, para que o PIC reproduza o som, precisamos tê-lo em memória. Para isso, irei demonstrar passo a passo tal função:
Em seu computador, escolha o arquivo de áudio desejado. Abra-o e o edite com o
Audacity (Clique aqui para baixá-lo). Remova os espaços de silêncio contidos no início e no fim do arquivo. Eles ocupam desnecessariamente, a memória.
Para obter melhores resultados, ajuste volume da faixa.
Na parte inferior esquerda do programa, ajuste a taxa de amostragem para 11025 Hz.
Agora vá em "Ficheiro >> Exportar Áudio". Na caixa de diálogo que se abre, selecione: "Outros ficheiros sem compressão". Em seguida, clique em "Opções". Em cabeçalho, deixe: "WAV". Em codificação, deixe: "Unsigned 8 bit PCM". Observe:
Clique em OK e Salvar. Na janela de edição de Metadados, clique em Limpar e OK.
Gravando a memória
Para saber se a capacidade da memória irá suportar nosso arquivo, abra suas propriedades e verifique seu tamanho. Guarde esse número. Você vai precisar dele mais tarde.
Agora, escolha a EEPROM. Lembrando que o sufixo da memória, é a capacidade dela em kbits. Para converter em Bytes, divida esse número por 8.
Por exemplo: a memória 24C256 tem 256 Kbits, que é o mesmo que 32 KBytes (256 / 8 = 32). Portanto, se caso queira usar essa memória, seu arquivos deverá ter menos que 32 KB (32 000 bytes).
Com qualquer gravador de EEPROM, abra o arquivo WAV e grave na memória.
OBS: Por padrão, todos os gravadores só 'enxergam' arquivos .hex ou .bin. Selecione 'todos os arquivos' quando for abrir o arquivo de áudio.
Pronto! Já temos assim, nosso 'disco'.
Código Fonte
O código fonte a seguir, foi compilado com PCHW da CCS. É apenas um código simples para tocar a mensagem da memória a cada segundo.
Você pode baixá-lo aqui.
Alterações poderão ser realizadas para melhor atender sua necessidade:
///////////////////////////////////////////////////////////////////////////////
// //
// PIC Player EEPROM //
// ================= //
// //
// Código simples para reproduzir som através de uma memória externa pelo //
// barramento I2C. A saida de som será decodificada por PCM. //
// //
// Autor: Valdir Silva Data: 01/04/2016 - 17:35 //
// Email: valdir.st@gmail.com Versão: 1.0 //
// //
////////////////////////////////////////////////////////////////////////////////
#include <C:\Program Files (x86)\PICC\Devices\16F628A.h>
#use delay (clock=20000000)
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOCPD, NOMCLR
#use i2c (master, sda=PIN_B4, scl=PIN_B5, FAST=500000) // Configura I2C com 500 KHz
#use fast_io(A)
#use fast_io(B)
// Define taxa de amostragem
#define FOSC 20000000
#define T2_FREQ 22050 // 22 KHz
#define PR2 FOSC/4/T2_FREQ
// --------------------------------------------------------------------------
// Global variables
int wait;
byte buffer_pwm;
// --------------------------------------------------------------------------
// Endereça e aponta o dispositivo com seu respectivo endereço
void set_start(int16 start_eeprom)
{
i2c_start(); // Start
i2c_write(0xa0); // Endereço da categoria do dispositivo
i2c_write(start_eeprom >> 8); // Endereço Alto de Dados
i2c_write(start_eeprom); // Endereço Baixo de Dados
i2c_start(); // Start
i2c_write(0xa1); // Endereço do dispositivo
}
// --------------------------------------------------------------------------
// Lê sequencialmente, todos os endereços entre end_inicial ao end_final
void play (int16 end_inicial, int16 end_final)
{
int16 i;
set_start(end_inicial);
for(i=0; i < end_final; i++)
{
buffer_pwm = i2c_read(1); // ACK
wait=1;
while(wait);
set_pwm1_duty(buffer_pwm);
}
buffer_pwm = i2c_read(0); // NOACK - para finalizar
i2c_stop(); // Stop
}
// --------------------------------------------------------------------------
#INT_TIMER2
void int_tmr2()
{
if(wait) wait--;
}
// --------------------------------------------------------------------------
// Direciona as portas do PIC e configura Interrupção de Timer 2
void main(void)
{
delay_ms(10);
set_tris_a(0b11111111);
set_tris_b(0b11110011);
setup_timer_2(T2_DIV_BY_1, PR2, 1);
setup_ccp1(CCP_PWM);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER2);
// --------------------------------------------------------------------------
// Loop principal
while(1)
{
play(60, 31618); // o endereço final, é o mesmo que o tamanho do arquivo obtido nas propriedades do mesmo.
delay_ms(1000);
}
}
// --------------------------------------------------------------------------
Nota: Na chamada da função 'play' são passados 2 parâmetros; o endereço inicial e o endereço final de reprodução. Não é recomendável que se use '0' no endereço inicial, isso porque, os primeiros 60 bytes de um arquivo WAV são apenas informações dele mesmo, como taxa de amostragem, nome, número de canais, etc. e essas informações não são últeis pra nós. Pelo menos nesse projeto. Além que evita de ouvir aquele clic no início da reprodução. Já o endereço final, deve ser aquele obtido nas propriedades do arquivo.
Futuramente, caso seja necessário, poderemos adicionar mais memórias com endereços diferentes configurados em hardware, pelos pinos A0, A1, A2 ou usar até a memória 24C512. Assim, teríamos mais capacidade de armazenamento. Lembrando que o objetivo, é de usar pequenas mensagens, para avisos, alertas, campanhias, etc.
Algumas sugestões para alterações podem ser bem vindas. Por exemplo: usar um PIC de 8 pinos (12F752) poderia deixar a placa final mais compacta.
Incrementar um amplificador de áudio com LM386 por exemplo, poderia ser muito bom para falar um número digitado numa tecla.
Enfim, são várias as aplicações.
Só depende da sua imaginação e capacidade.
Imagine.
Acredite em você.
E crie com Eletrônica.
Forte abraço a todos!