EmbeddedRelated.com

Playing sound in DAC using simple 8051 MCU

March 23, 20134 comments Coded in C for the SiliconLabs 8051
/*System reads wav files by SPI from external memory . Samples read are sent to external DAC by other SPI to be played. It's nedeed ISR reception (not included) of SPI to manage info of this file. At the beginnig, this timing is not important, but after all info of wav file is read, timming is fitted to sampling time of wav to play.

This Timer ISR manages read samples by SPI_Memory and write in SPI_DAC in 8051 MCU. Because this MCU has only one SPI,the info transmited to DAC is managed by simple GPIOs */
void Timer2_ISR (void) interrupt 5
{     
   char desp=0;
   char temp=0;
        
   SFRPAGE_save = SFRPAGE;

   //! buffer to store 1 or 0 in bit content audio to convert	
   if(TF2H == 1)
   {
		/*When system starts, only reads from memory, to get wav header (sampletime, length, and because
		there are more than one wav file in memory,  the starting address of wav, In "configurating" the 
		timer period is not sampleTime*/
		if (configurating==TRUE)
		{
			SPI_Read_Memory(); /*it's nedeed ISR to manage recepcion*/
		}
		else
		{	
			/*pread counts samples of wav file reading*/
			if (pread<(audioLength+1))
			{	
				/*wavSampleRead is the last sample stored by SPI, taken in SPI ISR*/
				PCA0CPH0=wavSampleRead;
				desp=4;
				MOSI_SPI_SW=0;
				
				index++;
				if (index==256)
				{
					index=0;
				}
				CS_DAC=0; /*Chip Select of DAC. This SPI is controlled by GPIOs*/
				while (desp!=0)
				{
					CLK_SPI_SW=0;
					CLK_SPI_SW=1;
					desp--;
				}
					
				desp=0;
				while (desp!=8)
				{
					CLK_SPI_SW=0;
					
					if ((wavSampleRead&0x80)!=0)
					{
						MOSI_SPI_SW=1;
					}	
					else
					{
						MOSI_SPI_SW=0;
					}
					CLK_SPI_SW=1;
					desp++;
					wavSampleRead=wavSampleRead<<1;
				}
				CLK_SPI_SW=0;
				MOSI_SPI_SW=0;
				CLK_SPI_SW=1;
				CLK_SPI_SW=0;
				CLK_SPI_SW=1;					
				CLK_SPI_SW=0;
				CLK_SPI_SW=1;
				CLK_SPI_SW=0;
				CLK_SPI_SW=1;
				CLK_SPI_SW=0;
				CS_DAC=1;
				MOSI_SPI_SW=0;	
			
				/* starts new transmision on SPI to read new sample from memory*/
				SFRPAGE = ACTIVE_PAGE;
				SPI_transferData = NO_OK;
				SPI0DAT = TRANSFER_MEMORY_COMMAND;
				SFRPAGE = SFRPAGE_save;
				
				buffer_Index=0;
				pread++;
			}
			else 
			{  
				/*in configurating mode is stored a buffer with some samples. This buffer
				it's used to allow "clac" noises to reproduce the audioagain  (becuase the audio is 
				playing periodically. The audios are siren sounds, and the last sample must linked whit 
				the first sample, having a compled wave form)*/
				PCA0CPH0=buffer[buffer_Index];
				temp=buffer[buffer_Index];

				buffer_Index++;
				
				if (buffer_Index==1)
				{
					looping=1;
				}
				else if (buffer_Index==BUFFER_SIZE)
				{
					pread=BUFFER_SIZE+1;
				}	
					desp=4;
					MOSI_SPI_SW=0;
				
					CS_DAC=0;
					while (desp!=0)
					{
						CLK_SPI_SW=0;
						CLK_SPI_SW=1;
						desp--;
					}
					desp=0;
					while (desp!=8)
					{
						CLK_SPI_SW=0;
						if ((temp&0x80)!=0)
						{
							MOSI_SPI_SW=1;
						}	
						else
						{
							MOSI_SPI_SW=0;
						}
						//CLK_SPI_SW=0;
						CLK_SPI_SW=1;
						desp++;
						temp=temp<<1;
					}
					desp=4;
					while (desp!=0)
					{
						CLK_SPI_SW=0;
						MOSI_SPI_SW=0;
						//CLK_SPI_SW=0;
						CLK_SPI_SW=1;
						desp--;
					}
					CLK_SPI_SW=0;
					CS_DAC=1;
					MOSI_SPI_SW=0;
					CS_DAC=1;
				}
				if (pread==BUFFER_SIZE+1)
				{			
					/*First sample to begin the cicle*/
					SFRPAGE = ACTIVE_PAGE;
					SPI_transferData = NO_OK;
					SPI0DAT = TRANSFER_MEMORY_COMMAND;
					SFRPAGE = SFRPAGE_save;
				}
			}

		}
		TF2H = 0;
   }
}