cancel
Showing results for 
Search instead for 
Did you mean: 

Audible DAC/DualModeDMA_SineWave?

antonius
Senior
Posted on January 29, 2014 at 08:27

Guys,

I've tried :

DAC/DualModeDMA_SineWave/main.c   

* @author  MCD Application Team

From Standard peripheral library, I can see it already on the osciloscope,

how can I make it audible ? How can I adjust the frequency ?

thanks
10 REPLIES 10
chen
Associate II
Posted on January 29, 2014 at 13:32

Hi Rick

You appear to be a busy person - so many posts, so many questions.

I am not familiar with the ''DAC/DualModeDMA_SineWave'' code that you mentioned.

I am also not familiar with the DAC peripheral.

''I can see it already on the osciloscope,

how can I make it audible ?''

Most people's audiable range is between 30Hz up to 16KHz

You need to change the frequency of the wave you are seeing on the oscilloscope so that it falls in the range I said.

''How can I adjust the frequency ?''

I infer from the title that the DAC is being driven by DMA. The data that is being transferred into the DAC should form the pattern/waveform that you are seeing on the oscilloscope.

Get the source data that is being DMAed, turn it into a comma separated value and import into Excel (or some other spreadsheet). Plot the data and you should see the same waveform.

To change the frequency - you need to change the source data so that the waveform changes - increase or decrease number of 'sine waves' you see.

Another way to change the frequency is to change the rate at which the DAC outputs the values.

antonius
Senior
Posted on January 30, 2014 at 00:38

Here's the complete code, which one is for changing the frequency ? thank you


/**

******************************************************************************

* @file DAC/DualModeDMA_SineWave/main.c 

* @author MCD Application Team

* @version V3.5.0

* @date 08-April-2011

* @brief Main program body.

******************************************************************************

* @attention

*

* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS

* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE

* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY

* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING

* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE

* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

*

* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>

******************************************************************************

*/


/* Includes ------------------------------------------------------------------*/

#include ''stm32f10x.h''


/** @addtogroup STM32F10x_StdPeriph_Examples

* @{

*/


/** @addtogroup DAC_DualModeDMA_SineWave

* @{

*/


/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define DAC_DHR12RD_Address 0x40007420


/* Init Structure definition */

DAC_InitTypeDef DAC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

uint32_t Idx = 0; 


/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

const
uint16_t Sine12bit[32] = {

2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,

3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 

599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};


uint32_t DualSine12bit[32];


/* Private function prototypes -----------------------------------------------*/

void
RCC_Configuration(
void
);

void
GPIO_Configuration(
void
);

void
Delay(__IO uint32_t nCount);


/* Private functions ---------------------------------------------------------*/


/**

* @brief Main program.

* @param None

* @retval None

*/

int
main(
void
)

{

/*!< At this stage the microcontroller clock setting is already configured, 

this is done through SystemInit() function which is called from startup

file (startup_stm32f10x_xx.s) before to branch to application main.

To reconfigure the default setting of SystemInit() function, refer to

system_stm32f10x.c file

*/



/* System Clocks Configuration */

RCC_Configuration(); 


/* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 

connected to the DAC converter. In order to avoid parasitic consumption, 

the GPIO pin should be configured in analog */

GPIO_Configuration();


/* TIM2 Configuration */

/* Time base configuration */

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 

TIM_TimeBaseStructure.TIM_Period = 0x19; 

//TIM_TimeBaseStructure.TIM_Period = 0x20; 

TIM_TimeBaseStructure.TIM_Prescaler = 0x0; 

TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


/* TIM2 TRGO selection */

TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);


/* DAC channel1 Configuration */

DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;

DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;

DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

DAC_Init(DAC_Channel_1, &DAC_InitStructure);


/* DAC channel2 Configuration */

DAC_Init(DAC_Channel_2, &DAC_InitStructure);


/* Fill Sine32bit table */

for
(Idx = 0; Idx < 32; Idx++)

{

DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);

}


#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL

/* DMA2 channel4 configuration */

DMA_DeInit(DMA2_Channel4);

#else

/* DMA1 channel4 configuration */

DMA_DeInit(DMA1_Channel4);

#endif

DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_Address;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

DMA_InitStructure.DMA_BufferSize = 32;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;


#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL

DMA_Init(DMA2_Channel4, &DMA_InitStructure);

/* Enable DMA2 Channel4 */

DMA_Cmd(DMA2_Channel4, ENABLE);

#else

DMA_Init(DMA1_Channel4, &DMA_InitStructure);

/* Enable DMA1 Channel4 */

DMA_Cmd(DMA1_Channel4, ENABLE);

#endif


/* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is 

automatically connected to the DAC converter. */

DAC_Cmd(DAC_Channel_1, ENABLE);

/* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is 

automatically connected to the DAC converter. */

DAC_Cmd(DAC_Channel_2, ENABLE);


/* Enable DMA for DAC Channel2 */

DAC_DMACmd(DAC_Channel_2, ENABLE);


/* TIM2 enable counter */

TIM_Cmd(TIM2, ENABLE);


while
(1)

{

}

}



/**

* @brief Configures the different system clocks.

* @param None

* @retval None

*/

void
RCC_Configuration(
void
)

{ 

/* Enable peripheral clocks ------------------------------------------------*/

#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL

/* DMA2 clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

#else

/* DMA1 clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

#endif

/* GPIOA Periph clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/* DAC Periph clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

/* TIM2 Periph clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

}



/**

* @brief Configures the different GPIO ports.

* @param None

* @retval None

*/

void
GPIO_Configuration(
void
)

{

GPIO_InitTypeDef GPIO_InitStructure;


/* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 

connected to the DAC converter. In order to avoid parasitic consumption, 

the GPIO pin should be configured in analog */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}


/**

* @brief Inserts a delay time.

* @param nCount: specifies the delay time length.

* @retval None

*/

void
Delay(__IO uint32_t nCount)

{

for
(; nCount != 0; nCount--);

}


#ifdef USE_FULL_ASSERT


/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void
assert_failed(uint8_t* file, uint32_t line)

{ 

/* User can add his own implementation to report the file name and line number,

ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */


/* Infinite loop */

while
(1)

{

}

}


#endif


/**

* @}

*/


/**

* @}

*/


/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

Posted on January 30, 2014 at 01:18

Ok, so you're pacing the DMA with a timer, the UPDATE periodicity is a function of the Prescaler and Period, and then that is further divided down by the length of the sample table.

The basic math here is Divisor = ((0 + 1) * (0x19 + 1) * 32) Divisor= 1 * 26 * 32 Divisor= 26 * 32 Divisor= 832 The TIMCLK, I presume, is 72 MHz, so Freq = 72,000,000 / 832 Freq= 86,5462 Hz So ~ 87 KHz currently

TIM_TimeBaseStructure.TIM_Period = 0x19;

TIM_TimeBaseStructure.TIM_Prescaler = 0x0;

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on January 30, 2014 at 01:27

So for 500 Hz, say

TIM_TimeBaseStructure.TIM_Period = (uint16_t)(72000000 / (32 * 500)) - 1;

If the period value exceeds 65535 (Frequency less than 35 Hz), then obviously you're going to have factor the numbers, and adjust the Prescaler.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on January 30, 2014 at 09:26

So

1.

TIM_TimeBaseStructure.TIM_Period = 0x1193;

for 500Hz ?

antonius
Senior
Posted on January 30, 2014 at 09:37

I can see about 500Hz on Osciloscope but it can't drive speaker / buzzer direclty,

Do I need an amplifier for it ? So I can hear the tone ?

thanks

frankmeyer9
Associate II
Posted on January 30, 2014 at 10:11

I can see about 500Hz on Osciloscope but it can't drive speaker / buzzer direclty,

 

Do I need an amplifier for it ? So I can hear the tone ?

 

I'd suggest to learn some basics about electrotechnics, and how to read datasheets.

chen
Associate II
Posted on January 30, 2014 at 10:54

Hi

''I can see about 500Hz on Osciloscope but it can't drive speaker / buzzer direclty,

Do I need an amplifier for it ? So I can hear the tone ?''

That would be a YES.

antonius
Senior
Posted on January 30, 2014 at 11:44

I've tried with LM386, but 1kHz frequency sounds like on and off (1kHz) in a fast way, not full 1khz beep.....any work arounds?