Primeiro, desculpem a demora.
Vamos aos acontecimentos.
Este assunto de som por pwm e pic, tem diversos pontos a se levar em consideração, mais como me falta conhecimento técnico vou me abster para não falar m... .
Consegui fazer com que o pic reproduzisse os dados que queria, próximo ao que esperava.
Depois de diversas tentativas, fiz esse programinha de teste.
- Código: Selecionar todos
#include <18F2620.h>
//#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES MCLR //Master Clear pin enabled
#use delay(clock=32000000)
#define TIME 64536 // seta o timer1 para overflow a cada 125us
#define MAX_BUFFER "NUMERO DE BYTES DO BUFFER"
const unsigned int som[MAX_BUFFER] = {XXXXX DADOS A PROCESSAR XXXXXXX};
short term = FALSE;
long increment = 0;
int x = 0;
int cont_T = 0;
int cont = 0;
/*O timer foi configurado para que o overflow ocorra a cada 1seg / 8khz = 125us, sendo assim a cada 125us o dado do pino PWM será atualizado*/
#int_timer1
void timer1_isr(void)
{
output_high(PIN_A1); // apenas para controle
if(increment < MAX_BUFFER){ // para percorrer do inicio ao termino do buffer
x = som[increment++]; // o proximo byte
set_pwm1_duty(x); // atualiza o duty_cicle
}else{
set_pwm1_duty(0); // coloca a zero pois terminou o buffer
disable_interrupts(INT_TIMER1); // para evitar uma reentrada
increment = 0; // zera o contador
term = TRUE; // coloca a flag de termino como verdadeira
}
set_timer1(TIME);
output_low(PIN_A1); // apenas para controle
}
void aux(void){
while(cont < cont_T){
output_high(PIN_A3);
delay_ms(500);
output_low(PIN_A3);
delay_ms(500);
cont++;
}
cont = 0;
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
//! setup_timer_1(T1_DISABLED);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_timer_2(T2_DIV_BY_4,249,1); // 8khz
//! setup_timer_2(T2_DIV_BY_4,124,1); // 16khz
//! setup_timer_2(T2_DIV_BY_4,82,1); // 24khz
//! setup_timer_2(T2_DIV_BY_1,249,1); // 32khz
//! setup_timer_2(T2_DIV_BY_1,199,1); // 40khz
//! setup_timer_2(T2_DIV_BY_1,124,1); // 64khz
//! setup_timer_2(T2_DIV_BY_1,99,1); // 80khz
setup_ccp1(CCP_PWM);
set_pwm1_duty(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(TIME); // seta o timer1 para overflow a cada 125us
output_low(PIN_A3); // apenas para controle
while(TRUE){
if(term){
cont_T++;
switch (cont_T) {
case 1:
aux();
setup_timer_2(T2_DIV_BY_4,124,1); // 16khz
setup_ccp1(CCP_PWM);
break;
case 2:
aux();
setup_timer_2(T2_DIV_BY_4,82,1); // 24khz
setup_ccp1(CCP_PWM);
break;
case 3:
aux();
setup_timer_2(T2_DIV_BY_1,249,1); // 32khz
setup_ccp1(CCP_PWM);
break;
case 4:
aux();
setup_timer_2(T2_DIV_BY_1,199,1); // 40khz
setup_ccp1(CCP_PWM);
break;
case 5:
aux();
setup_timer_2(T2_DIV_BY_1,124,1); // 64khz
setup_ccp1(CCP_PWM);
break;
case 6:
aux();
setup_timer_2(T2_DIV_BY_1,99,1); // 80khz
setup_ccp1(CCP_PWM);
break;
default:
aux();
setup_timer_2(T2_DIV_BY_4,249,1); // 8khz
setup_ccp1(CCP_PWM);
cont_T = 0;
break;
}
output_toggle(PIN_A0);
delay_ms(1000);
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_TIMER1);
term = FALSE;
set_timer1(TIME);
}
}
}
Fatos que aconteceram:
1- Com a taxa de amostragem igual a 8khz. Consegue se ouvir a informação porem como disse no inicio do tópico com intenso chiado agudo.
2- Com a taxa de amostragem igual a 16khz. Só ruído.
3- Com a taxa de amostragem igual a 24khz. Só ruído.
4- Com a taxa de amostragem igual a 32khz. Ouço quase que da mesma forma, quando reproduzo a amostra com o Sound Forgt, porém com o volume um baixo e pouco mais grave.
5- Com a taxa de amostragem igual a 40khz. Foi parecido com o nº 4 com uma pequena melhora no volume e nitidez.
6- Com a taxa de amostragem igual a 64khz. Só ruído.
7- Com a taxa de amostragem igual a 80khz. Só ruído.
O filtro usado nos testes foi um passa-baixa com resistor 1k e capacitor 100nf, o que dá uma FC de aproximadamente 16khz, sei que não é o correto, mais como era necessário uma variedade de capacitores para os teste, então mantive esta configuração.
MOR_AL escreveu: Se este chiado tivesse uma frequência fundamental superior à frequência máxima do seu sinal, e você pudesse medi-la, além da amplitude média deste chiado e a amplitude média do seu sinal, talvez eu pudesse projetar um Filtro Passa-Baixas (FPB) para você.
Obs.:
Considerar que o seu sinal seja de voz (+/- de 300Hz a 3400Hz).
Como o seu sinal PWM possui apenas valores positivos, e o seu sinal possui valores positivos e negativos, seria necessário incluir um Filtro Passa-Altas (FPA) também.
Responda às minhas três perguntas que vamos ver o que se pode fazer.
Gostaria muito de te responder estas perguntas, mais pela minha falta de conhecimento e um osciloscópio, não sei como te responder.
Quanto ao FILTRO, gostaria muito de sua ajuda.
Marcelo Samsoniuk escreveu:vc nao pode configurar para o pic gerar continuamente a saida pwm independente de vc atualizar ou nao o valor do contador?
por exemplo, seta ele para gerar a saida na freqüência.....
Estou fazendo praticamente isso, porem alternado a freqüência para poder escutar e entender melhor o conceito.
BolhaDigital escreveu:HÁ RAPAZ, ACABOU DE PASSAR PELA MINHA CUCA UMA POSSÍVEL COISA PARA ESSE RUIDO, PODE SER, LÍ EM ALGUM LUGAR ISSO: É O SEGUINTE, QUANDO VC JOGA UMA WAVE COM O FORMATO .WAV DIRETAMENTE NUM DAC SEJA ELE PWM OU R2R OU CHIPADO, EXISTE O PROTOCOLO DO ARQUIVO .WAV JUNTO COM A AMOSTRA, ISSO PODERIA GERAR RUIDOS! LEVE ESSA OBSERVAÇÃO EM CONSIDERAÇÃO ANTES DE FAZER ALTERAÇÕES NO SEU SISTEMA, EXPERIMENTE PASSAR O SER ARQUIVO DO FORMATO .WAV PARA O FORMATO .PCM E REPRODUZA O TREM, VEJA SE O RUIDO NÃO SOME!
MAIS UMA VÊZ ESTA A SUA DISPOSIÇÃO ESSE PROGRAMINHA DA ACONAS É SÓ ME ENVIAR UM EMAIL QUE TE ENVIO O CARINHA...
Faço da seguinte maneira, gravo uma amostra com o SoundForge, há 8khz, 8bits, unsigned e mono e salvo com .RAW.
vtrx escreveu:Ivan,se voce tem capacidade de programar em ASM,tem uma 'brincadeirinha' aqui neste link...
Um dia ainda chego lá, irei me esforçar.
vtrx escreveu:Ivan, conseguiu resultado satisfatório?
Neste momento está do jeito que descrevi acima.
Quero agora entender como calcular o filtro e se possivel aumentar um pouco mais o que seria o "volume" do som
Mais uma vez, obrigado a todos.
"Mesmo o objeto mais inanimado tem movimento suficiente para ficar na sua frente e provocar um acidente."
"Even the most inanimate object has enough movement to stand in your way and cause an accident."