2024-08-28 06:39 AM - last edited on 2024-08-28 06:47 AM by SofLit
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.
2024-08-28 06:46 AM
Hello,
Please use </> button to paste your code. I'm editing it then ..
and review our tips on how to post a thread here.
2024-08-28 06:59 AM
Ahhh sir, are you sure sin is calculated quicker as tim period ?
float sine_value = sin((theta*2*pi)/1000);
2024-08-28 10:58 PM
sir, can you please elaborate how to go about this problem?
2024-08-28 11:18 PM
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
}
2024-08-29 12:32 PM
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
2024-08-29 04:41 PM
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.