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 }
View more

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

thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

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

View solution in original post

6 REPLIES 6
mÆŽALLEm
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 III

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 }

 

waclawek.jan
Super User

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.