Grabar audio y reproducir en Mini DK2

Buenas tardes estoy realizando un proyecto con la tarjeta Mini DK2 LPC1768, en concreto una estación meteorológica que contiene varios sensores (temperatura, presión, viento). El problema es que no se muy bien como grabar un audio mediante un micrófono (pines de alimentación a 5V, GND y Tout) y reproducirlo (utilizando el integrado LM386), ya que luego utilizaré este audio a modo de alarma si se supera el valor de alguno de los sensores. Estoy trabajando con KEIL uvision4. Les aporto el código que ya tengo a ver si alguien me puede echar una mano.

Código:
#include <LPC17xx.H>
#include "ADC.h"
#include "Timer3.h"

#define F_cpu 100e6										// Defecto Keil (xtal =12Mhz)
#define F_pclk F_cpu/4 // Defecto despues del reset




float voltios, TempLM35, voltiosh, Humedad;
uint8_t voltiosm;

float mem_LM35 [Tiempo_almacenamiento/Periodo_almacenamiento];
float mem_Hum [Tiempo_almacenamiento/Periodo_almacenamiento];
uint8_t sonido [muestras_audio];

int k=0,i=0,g=0;

// CONFIGURACION TIMER1 SENSORES //
void init_TIMER1(void)
{
	  LPC_SC->PCONP|=(1<<2);						// Alimentacion Timer1
 
    LPC_TIM1->PR = 0x00;							// Prescaler Register: pclk 
    LPC_TIM1->MCR = 0x2;   						// Tras Match: Reset del contador 
    LPC_TIM1->MR0 = (F_pclk/2)-1;			// Frecuencia de Match: 0.5 s
		   
		LPC_TIM1->TCR = 0x01;     				// Iniciar timer 
		LPC_TIM1->EMR = 0x0031;						// External Match Register: Toggle

}	
		void ADC_IRQHandler(void) 
{
	//// TEMPERATURA INTERIOR. LM35 ////
	voltios= ((LPC_ADC->ADDR2>>4)&0xFFF)*3.3/4095; 		// Lectura de conversion canal 2. 
	TempLM35 = voltios*100;														// Relacion voltios - temperatura	
	mem_LM35[i]=TempLM35;															// Almacenamiento en memoria
	

	//// HUMEDAD. HIH4000 ////
	voltiosh= ((LPC_ADC->ADDR1 >>4)&0xFFF)*3.3/4095;	// Lectura de conversion canal 1. 
	Humedad = (voltiosh-0.826)/0.0315;								// Relacion voltios - humedad
	mem_Hum[i]=Humedad;																// Almacenamiento en memoria

	//// Frecuencia de almacenamiento sensores////
		if (k<Periodo_almacenamiento-1) k++;
		else{
			k=0;
			if (i<Tiempo_almacenamiento/Periodo_almacenamiento-1) i++;
			else i=0;
		}
		
	//// MICROFONO ///
	voltiosm= ((LPC_ADC->ADDR5 >>4)&0xFFF);						// Lectura de conversion canal 5. 
	sonido[g]=voltiosm;																// Almacenamiento en memoria

		if (g<muestras_audio-1) g++;
		else {g=0; }
	
}	
// CONFIGURACION ADC SENSORES //
void init_ADC(void) 
{	
	LPC_SC->PCONP|= (1<<12);						// Alimentación del ADC
	LPC_PINCON->PINSEL1|= (101<<16);  	// Pines: P0.24 y P0.25     Funcion: AD0.1 y AD0.2
	LPC_PINCON->PINMODE1|= (1111<<16); 	// Deshabilita pullup/pulldown
	LPC_SC->PCLKSEL0|= (0x00<<8); 			// Reloj del periferico = F_pclk = F_cpu/7 = 25 MHz

	LPC_ADC->ADCR= (0x03<<1)|		  	  	// Canal 1 y 2 activados
								 (0x01<<8)|		  	  	// Reloj del ADC = 12.5 MHz
								 (0x01<<21)|			 		// PDN=1   Activar conversor
								 (6<<24);				    	// Inicio de conversión con el Match 0 del Timer 1 --- MAT1.0
	
	LPC_ADC->ADINTEN= (11<<1);					// Hab. interrupción fin de conversión canal 1 y 2. 
																	
  NVIC_EnableIRQ(ADC_IRQn);						// Habilita la interrupcion del ADC. 
	NVIC_SetPriority(ADC_IRQn,2);				// Prioridad: 2
}	

// CONFIGURACION ADC MICROFONO //
void init_adc2(void) 
{	
	LPC_SC->PCONP|= (1<<12);						// Power ON  ADC (habilita la alimentación del ADC
	LPC_PINCON->PINSEL3|= (3<<30);  		// Pin: P1.31    Funcion: AD0.5
	LPC_PINCON->PINMODE3|= (2<<30); 		// Deshabilita pullup/pulldown
	LPC_SC->PCLKSEL0|= (0x00<<8); 			// Reloj del periferico = F_pclk = F_cpu/7 = 25 MHz

	LPC_ADC->ADCR= (0x01<<5)|		  	 		// Canal 5 activado
								 (0x01<<8)|		  	 		// Reloj del ADC = 12.5 MHz
								 (0x01<<21)|			 		// PDN=1   Activar conversor
								 (6<<24);				   	 	// Inicio de conversión con el Match 0 del Timer 1 --- MAT1.0
	
  LPC_ADC->ADINTEN= (1<<5);						// Hab. interrupción fin de conversión canal 5

	NVIC_EnableIRQ(ADC_IRQn);						// Habilita la interrupcion del ADC
	NVIC_SetPriority(ADC_IRQn,2);				// Prioridad: 2
}	

// CONFIGURACION TIMER1 MICROFONO //
void init_TIMER1_2(void)
{
	  LPC_SC->PCONP|=(1<<2);							// Alimentacion Timer1
 
    LPC_TIM1->PR = 0x00;								// Prescaler Register: pclk  
    LPC_TIM1->MCR = 0x2;   							// Tras Match: Reset del contador 
    LPC_TIM1->MR0 = (F_pclk/8000/2)-1;	// Frecuencia de Match: 4 KHz
		   
		LPC_TIM1->TCR = 0x01;     					// Iniciar timer
		LPC_TIM1->EMR = 0x0031;							// External Match Register: Toggle
}
 
Última edición por un moderador:
Te doy la idea de lo que deberías hacer, después el código pelealo vos.

Si querés reproducir audio con ese uC, tenés que hacer 2 cosas:

1- Guardar los datos del audio en crudo, ya sea en la memoria flash o en una SD.
2- Usar el DAC o una salida de PWM.
3- Filtrar bien la salida en función de la frecuencia de muestreo.

El punto "1" lo podés resolver fácilmente grabando el sonido a una determinada frecuencia de muestreo (digamos 8kHz, alcanza para voz) usando una PC y generado un archivo "wav". Buscando un poco por internet, vas a conseguir programas que te pasan ese archivo "wav" a un vector de datos que serán justamente los datos que deberás usar en el punto "2".

Ese vector, lo podrías almacenar en la memoria flash como un dato estático o si hablamos de audios de mucho tamaño, podrías usar una memoria SD.

Como el muestreo es de 8kHz y si usas 8 bits de datos, vas a tener 8000 bytes por segundo de audio, con lo cual es algo a tener muy en cuenta.

En el punto "2", con los datos almacenados en el punto "1", simplemente tenés que configurar un timer para que c/125uS (T=1/8kHz) muestrees el valor a salida del DAC/PWM.

En el punto "3" vas a tener que agregar un filtro a la salida del DAC/PWM para que corte en la frecuencia útil que idealmente será fsample/2 (8kHz/2=4kHz), pero eso es ideal, te aconsejo que cortes un poco antes (por ej. en 3,5kHz). Si usas PWM, lo ideal es que configures su frecuencia muy por arriba de los 3,5kHz (35kHz o más). Este punto se resuelve con un simple circuito R-C.

Eso sería a groso modo lo que deberías hacer.
 
Atrás
Arriba