cancel
Showing results for 
Search instead for 
Did you mean: 

Made an ISD1820 Voice Recorder and Player Module with a single board stm32f401 is posible?

angeliran
Senior

I want to made a simple Voice Recorder and Player Module, i found an interesting article here:

https://community.st.com/s/article/how-to-play-audio-files-using-stm32-part-1?t=1675535162773 

But it´s focused to STM32G0, and i have stm32f401, i´have tried to follow the steps presented there, without luck...

So, i´ve decided, to make more simple (i think =/)

 I know the stm32f401 only have adc, but not dac, so, i´ll use pwm to reproduce small audio´s, stores in internal memory

4 REPLIES 4
AScha.3
Chief II

shure. just depends on : how much time will you invest and what quality you expect.

i made a audio player, plays wav or MP3 files from USB stick to a dac by I2S. (dac can be TDA1387 , some 30 ct . on Ali.)

i remember a program on an AVR (8bit, 20MHz) that records and plays back low quality audio just by using the pins and a R-C filter, some sigma-selta modulation without complex compression.

If you feel a post has answered your question, please click "Accept as Solution".
angeliran
Senior

Thx for your answer AScha.3!

Initially, only want to do it, without extra periferialls, only internal memory, stm32f401 don´t have dac, only adc, for record some seconds with an analog mic, and reply later, via pwm, can you please, show me some link to the avr program?

AScha.3
Chief II

it was long time ago...so i am not shure...maybe:

http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/s2005/ik48_ua22/mysite/sw_hw.htm

http://ww1.microchip.com/downloads/en/appnotes/atmel-42777-digital-sound-recorder-using-dac-with-attiny817_applicationnote_avr42777.pdf

https://hackaday.com/2011/09/03/pic-based-voice-recorder/

 https://320volt.com/en/pic16f876a-sandisk-sd-kart-ses-kayit-calma/

// Sound Recorder using SD card and PIC16F876A, by www.moty22.co.uk
//
// File will compile with the free Hi-Tech C compiler.
// Recording is done by the ADC using only the LSB. Bytes are written to the SD
// at the rate of 20KHz. It is similar to the format of .wav sound files.  
// For playback CCP is used as a DAC (Digital to Analogue Converter).
   
#include <htc.h>
 
__CONFIG(LVPDIS & WDTDIS & UNPROTECT & HS);
 
#define CS RC0		//chip select input
#define Stop RB0	//stop pushbutton
#define Play RB1	//play PB
#define Rec RB2		//record PB
#define Pause RB3	//pause PB
#define RecLED RB5
#define errorLED RB4
 
unsigned long loc;	//pause location
 
unsigned char SPI(unsigned char data)		// send character over SPI
{
	SSPBUF = data;			// load character
	while (!BF);		// sent
	return SSPBUF;		// received character
}
 
char Command(unsigned char frame1, unsigned long adrs, unsigned char frame2 )
{	
	unsigned char i, res;
	SPI(0xFF);
	SPI((frame1 | 0x40) & 0x7F);	//first 2 bits are 01
	SPI((adrs & 0xFF000000) >> 24);		//first of the 4 bytes address
	SPI((adrs & 0x00FF0000) >> 16);
	SPI((adrs & 0x0000FF00) >> 8);
	SPI(adrs & 0x000000FF);	
	SPI(frame2 | 1);				//CRC and last bit 1
 
	for(i=0;i<10;i++)	// wait for received character
	{
		res = SPI(0xFF);
		if(res != 0xFF)break;
	}
	return res;	  
}
 
void InitSD(void)
{
	unsigned char i;
	
	for(i=0; i < 10; i++)SPI(0xFF);		// min 74 clocks
	CS=0;			// Enabled for SPI mode
 
	if (Command(0x00,0,0x95) !=1) errorLED = 1;	// Reset SD command
 
	while (Command(0x01,0,0xFF) !=0) {} //wait for idle state
	
	SSPM1 = 0;	// full speed 2MHz
	CS = 1;
}
 
void WriteSD(void)	
{
	unsigned int r,i;
	CS = 0;	
	ADON = 1;
	RecLED = 1;
	
	r = Command(25,loc,0xFF);	//multi sector write
	if(r != 0)
	{
		errorLED = 1;
		ADON = 0;
		RecLED = 0;
	}
	SPI(0xFF);
	SPI(0xFF);
	SPI(0xFF);
	
	while(Stop && Pause)
	{
		SPI(0xFC);	//multi sector token byte
		for(i=0;i<512;i++)
		{
			GODONE = 1;			//ADC input sample
			while(!TMR2IF){}	//20KHz clock
			SPI(ADRESL);		//send analogue byte
			TMR2IF = 0;
				//play while record
			CCP1X = ADRESL & 1;	//shift byte to get the required PWM duty cycle 
			CCPR1L = (ADRESL >> 1);
		}
 		SPI(0xFF);	// CRC
		SPI(0xFF);	// CRC
	
	if((r=SPI(0xFF) & 0x0F) == 0x05){	//data accepted	= 0101		
		for(i=10000;i>0;i--){				
			if(r=SPI(0xFF))	break;
		}	
	}
	else{
		errorLED = 1;
	}
	while(SPI(0xFF) != 0xFF);	// while busy
	loc += 512; 		
	}
	SPI(0xFD);	//stop transfer	token byte
			
	SPI(0xFF);
	SPI(0xFF);
	while(SPI(0xFF) != 0xFF);	// while busy
	
	CS = 1;
	ADON = 0;
	RecLED = 0;
}
 
void ReadSD(void)
{
	unsigned int i,r;
	unsigned char data;
	CS = 0;
	r = Command(18,loc,0xFF);	//read multi-sector
	if(r != 0)errorLED = 1;			//if command failed
 
	while(Stop && Pause)
	{
		while(SPI(0xFF) != 0xFE);	// wait for first byte
		for(i=0;i<512;i++){
			while(!TMR2IF){}
			data = SPI(0xFF);
			CCP1X = data & 1;	//shift byte to get the required PWM duty cycle 
			CCPR1L = (data >> 1);
			TMR2IF = 0;
		}
		SPI(0xFF);	//discard of CRC
		SPI(0xFF);
		loc += 512;	
	}
	
	Command(12,0x00,0xFF);	//stop transmit
	SPI(0xFF);
	SPI(0xFF);
	CS = 1;
}
 
void main(void)
{
//	unsigned char Pause = 0;
//	unsigned int i;
	loc = 512;
	
	// PIC I/O init
	TRISC = 0b10010000;		// sck rc3, sdo rc5, sdi rc4, CS rc0, rc2 CPP1.
	TRISB = 0b1111;   	// switches
	RBPU = 0;		//pullup on
	RecLED = 0;
	errorLED = 0;
		
	//analogue init
	CCP1CON = 0B1100;	//PWM mode
	PR2 = 100;	//20KHz
	T2CON = 0B100;	//prescale 1, post scale 1, timer2 on
	ADCON1 = 0B11001110;		// Fosc/16, ch1, ref=Vdd, right just. 
	ADCON0 = 0B1000000;	// Fosc/16.
	
	//SPI init
	SSPCON = 0B110010;	//low speed osc/64(125kHz),enabled,clock idle=H
	CS = 1; 		// disable SD	
 
	InitSD();
	
	while(1) {
	if(!Rec) WriteSD();	
	if(!Play) ReadSD();
	if(!Stop) loc = 512;
 
	}		
}
 

If you feel a post has answered your question, please click "Accept as Solution".
angeliran
Senior

Thx for your time AScha.3!!!

I'll check your suggestions!!!