cancel
Showing results for 
Search instead for 
Did you mean: 

Sine wave generation using DAC

Yoshimitsu_Manji_clan
Associate II

Hello everyone, 

I am trying to generate sine wave using DAC and interrupts in my STM32F446 board. I want to do it without using array model. I am getting b infinite_loop when the program is run in debug mode. I have initialised "use float with printf/scanf" settings. The code is as follows:-

#include "stm32f4xx.h"

#include <math.h>

volatile float data;

#include "dac_sine.h"

#define pi 3.14159265359

volatile uint32_t theta = 0;

volatile uint32_t del_theta = 1;

float value;

 

void dac_sine_gpio_init(void)

{

 

RCC->AHB1ENR |= (1U<<0); //enable clock for GPIO Port A

GPIOA->MODER |= (0b11<<10); //setting PA5 in analog mode

GPIOA->MODER |= (0b11<<8); //setting PA4 in analog mode

 

}

void dac_sine_timer_init(void)

{

RCC->APB1ENR |= (1U<<29); //Clock access to DAC Enabled

RCC->APB1ENR |= (1U<<0); //clock access to Timer2 Enabled

TIM2->PSC = 1; //setting pre-scalar value

TIM2->ARR = 999; //setting ARR value

TIM2->CR1 = (1U<<0); //counter enabled

TIM2->DIER |= (1U<<0); //update interrupt enable

DAC->CR |= (1U<<0); //DAC Channel 1 is enable

NVIC_EnableIRQ(TIM2_IRQn);

}

 

void tim_callback(void)

{

theta = theta + del_theta;

if (theta > 999) {theta = 0;}

float sine_value = sin((theta*2*pi)/1000);

uint32_t dac_value = (uint32_t)((sine_value + 1)*999);

 

//if (theta > (2*pi)) {theta = 0;}

//data = sin (theta); //statement for sine waveform

//uint16_t dac_value = (uint16_t)((data+1)*0.5*4095);

DAC->DHR12R1 = theta; //statement to load the data in channel 1 of DAC

}

 

void TIM2_IRQHandler(void)

{

if (TIM2->SR & (1U<<0)) //check if update interrupt flag is raised

{TIM2->SR &=~ (1U<<0);} //clear the flag

tim_callback(); //go to this callback function

}

can someone pls help me getting sine values in live expression windows please.

thanks in advance.

6 REPLIES 6
SofLit
ST Employee

Hello,

Please use </> button to paste your code. I'm editing it then ..

and review our tips on how to post a thread here.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
MM..1
Chief II

Ahhh sir, are you sure sin is calculated quicker as tim period ?

float sine_value = sin((theta*2*pi)/1000);

 

sir, can you please elaborate how to go about this problem?

Your question is how live expression. Simply make it global variable not local, but for what?

And problem .... normal way to work with sine is precalculated tables in RAM. Create array DAC_value[1000] and fill it in main. 

void tim_callback(void)
{
theta = theta + del_theta;
if (theta > 999) {theta = 0;}

DAC->DHR12R1 = DAC_value[theta]; //statement to load the data in channel 1 of DAC
}

 

Use f suffix to the float constants (including pi). Otherwise the calculations are performed as double, which is very slow. 

Also make sure you have switched on the hardware floating point unit, and also have switched on compiler optimisations. 

JW

etheory
Senior II

It would be a LOT faster for you to use a complex phasor instead of a sine wave. sin(x) is one of the most expensive functions you can call. A complex phasor would do the same thing with a fraction of the processing power.