+ Post New Thread
Results 1 to 11 of 11
  1. #1
    Newbie level 6
    Points: 1,680, Level: 9
    Achievements:
    7 years registered

    Join Date
    Mar 2011
    Posts
    14
    Helped
    0 / 0
    Points
    1,680
    Level
    9

    Generating Sine Wave Through External DAC (STM32)

    Hello guys,

    Now I try to generate a sine wave with STM32F7 microprocessor with using external 8 bit DAC (DAC082S085). The microprocessor and DAC is communicated each other with SPI transmit only master mode. Now, there is a generated sine wave which looks like an interrupted shape. Do you have any idea to solve this problem?

    Thank you,

    Here is my code:

    Code:
    uint8_t DAC_A_Write = 0x1; // DAC's A output is selected 0 0 0 1
    uint16_t DACA_Buf; // Output A of the DAC
    short a;
    
    double I;
    uint16_t s[512];
    uint16_t m=0;
    
    for (I = 0 ; I < 512 ; I++)
    		{
    				
    			s[m] = 127+round((sin( I * 6.28/360))/0.02); // 0.02 is the step size
    			if (m <= 512) m++;
    			HAL_GPIO_WritePin(DAC_CS_GPIO_Port, DAC_CS_Pin, GPIO_PIN_RESET);
    			DACA_Buf = DAC_A_Write<<12 | s[m]<<4;
    			HAL_SPI_Transmit(&hspi2,(uint8_t*)&DACA_Buf,2,100);
    			HAL_GPIO_WritePin(DAC_CS_GPIO_Port, DAC_CS_Pin, GPIO_PIN_SET);
    		}
    Click image for larger version. 

Name:	sine wave with sine function 0.png 
Views:	2 
Size:	24.9 KB 
ID:	156379

  2. #2
    Super Moderator
    Points: 32,144, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,434
    Helped
    1742 / 1742
    Points
    32,144
    Level
    43

    Re: Generating Sine Wave Through External DAC (STM32)

    The equation is the problem.
    sin( I * 6.28/360)

    Try plotting it in excel or something.

    sine has a full cycle from 0 to 2pi. You are indexing from 0-511 and end up going from 0 to 511/360*2pi which is past a full cycle, that is you restart your cycle every 360 counts, i.e. cycle restarts early by 152 counts (512-360).

    You need to either change the indexing form 0 to 359 or change the equation to sin( I * 6.28/512).



    •   AltAdvertisement

        
       

  3. #3
    Advanced Member level 2
    Points: 2,903, Level: 12

    Join Date
    Jan 2019
    Posts
    526
    Helped
    139 / 139
    Points
    2,903
    Level
    12

    Re: Generating Sine Wave Through External DAC (STM32)

    s[m] = 127+round( ( sin( I * 6.28/360) ) /0.02 )
    1 2 3 3 2 1

    by counting parenthesis, you can see that the division by 0.02 is outside the parenthesis surrounding sin and amounts to a multiply by 50

    you have a for loop - I from 0 to 512 so sin runs 512/360 or 1.42 cycles and restarts - which is what you are seeing

    m is initialized before the for loop and increments inside the for loop but never re-initialized. I do not understand what you are doing with m

    recommend you run I from 0 to 359 for 1 cycle of sin in 1 degree steps
    or 0 to 719 in 1/2 degree steps



  4. #4
    Newbie level 6
    Points: 1,680, Level: 9
    Achievements:
    7 years registered

    Join Date
    Mar 2011
    Posts
    14
    Helped
    0 / 0
    Points
    1,680
    Level
    9

    Re: Generating Sine Wave Through External DAC (STM32)

    Thank you guys for your quick responds!

    Now I realized my mistake and fix it.

    Code:
    for (I = 0 ; I < 359 ; I++)
    		{
    			s[m] = 127+round((sin( I * 6.28/360))/0.02); // 0.02 is the step size
    			m++;
    			m=0;
    			HAL_GPIO_WritePin(DAC_CS_GPIO_Port, DAC_CS_Pin, GPIO_PIN_RESET);
    			DACA_Buf = DAC_A_Write<<12 | s[m]<<4;
    			HAL_SPI_Transmit(&hspi2,(uint8_t*)&DACA_Buf,2,100);
    			HAL_GPIO_WritePin(DAC_CS_GPIO_Port, DAC_CS_Pin, GPIO_PIN_SET);
    		}
    m is initialized before the for loop and increments inside the for loop but never re-initialized. I do not understand what you are doing with m
    I tried the fixed this issue too. With m variable, I plan to make indexing of the s array.

    I get a result but there is a short delay before starting the sine function. Why is this reason and fix it?

    Click image for larger version. 

Name:	sine wave with sine function _2 0.png 
Views:	4 
Size:	23.3 KB 
ID:	156380



  5. #5
    Super Moderator
    Points: 32,144, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,434
    Helped
    1742 / 1742
    Points
    32,144
    Level
    43

    Re: Generating Sine Wave Through External DAC (STM32)

    Either what every you do outside the for loop takes too much time or starting up a new for loop takes a lot of time.

    I'm not a SW engineer so I don't know how long it takes SW to set up a new for loop. In HDLs the for loop is unrolled by the synthesis tools and it just replicates the logic. We have to use counters and FSMs to precisely time such loops and don't see these kinds of issues.

    Not sure why you both have an s array and compute the sine values on-the-fly. If you compute them in the loop why bother storing them in an array? I can understand computing them beforehand to create an array, which you can then index later in a loop to speed up the DAC output loop.



    •   AltAdvertisement

        
       

  6. #6
    Super Moderator
    Points: 264,284, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    46,184
    Helped
    14044 / 14044
    Points
    264,284
    Level
    100

    Re: Generating Sine Wave Through External DAC (STM32)

    You are asking about the timing of code that is not shown in your post. How can we know?



  7. #7
    Advanced Member level 4
    Points: 8,028, Level: 21
    Achievements:
    7 years registered

    Join Date
    Jan 2015
    Posts
    1,124
    Helped
    350 / 350
    Points
    8,028
    Level
    21

    Re: Generating Sine Wave Through External DAC (STM32)

    Quote Originally Posted by uranyumx View Post
    Code:
    			m++;
    			m=0;
    This part of your code makes no sense - it means that you are always using 's[0]' to hold the value. Therefore why create an array when all you need is a single variable.
    I suspect that you are getting a few things mixed up here.
    For a start, setting up a 'for' loop is trivial as far as the generated code is concerned. If there is a short delay before staring the sine wave generation it is more likely to come from some part of you r code that you are not showing us.
    Calculating a 'sine' value is expensive for any microcontroller (even if it does have an FPU) as it involves a lot of calculation for each value - and you are calculating 360 for each time you use this code. If you are worried about speed then there are a couple of things you could do.
    Firstly pre-calculate all of the sine values into an array and then just read from the array when they are needed. That way you do the expensive bit once at the start. If you want to you can skip the calculation part and just use constants - especially if you use the next 'idea'.
    Even better is to realise that you only need to calculate from 0 to 89 degrees - from 90-179 you walk back through the array of values; for 180 to 269 you walk forward through the array again but negate the values; and for 270 to 259 you both walk backwards and negate.
    Susan



  8. #8
    Advanced Member level 2
    Points: 2,903, Level: 12

    Join Date
    Jan 2019
    Posts
    526
    Helped
    139 / 139
    Points
    2,903
    Level
    12

    Re: Generating Sine Wave Through External DAC (STM32)

    you might calculate the values you want to send to the DAC external to the processor
    and program in 360 data points

    or as Susan has described, 90 points and be clever

    or, since powers of 2 are natural to a computer, you could use 256 data points, equally spaced
    or 512 data points, also equally spaced

    30 years ago, I used an 8 bit counter and 256 data points in a memory to produce
    a 60 hz signal

    you can do the same in your processor
    frequency depends on clock rate



    •   AltAdvertisement

        
       

  9. #9
    Newbie level 6
    Points: 1,680, Level: 9
    Achievements:
    7 years registered

    Join Date
    Mar 2011
    Posts
    14
    Helped
    0 / 0
    Points
    1,680
    Level
    9

    Re: Generating Sine Wave Through External DAC (STM32)

    Thank you for your responds!

    Actually, the problem is solved with two ways. The first one is that with disable the rest of the code in while loop except DAC command. But it is not an optimal solution. Because I have to call other codes in the rest of the while loop.

    The other solution is that I set a timer with interrupt mode. With each interrupt, the sine function 'I' variable is updated. With this way, I control the the sine wave frequency with adjusting the timer prescaler and counterperiod parameters.

    Generating sine wave with an array may be better option. Thanks for this advice but I plan to make an amplitude modulation as a next step. So with 'sine' function, my job would be easier. Otherwise, I have to calculate the array parameters for each modulation percentage case.

    Thanks for your time!



  10. #10
    Super Moderator
    Points: 81,147, Level: 69
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    16,457
    Helped
    3734 / 3734
    Points
    81,147
    Level
    69

    Re: Generating Sine Wave Through External DAC (STM32)

    Hi,

    --> "interrupt" method is the recommended method.

    ****
    Waveform/Amplitude modulation.
    * "Waveform" is one thing (lookup table is a good solution for a small microcontroller)
    * "Amplitude modulation" is another thing. Indeed itīs just a "multiply" function. Most microcontrollers can do this easily.

    My recommendation: Lookup_table --> multiply --> output.


    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  11. #11
    Newbie level 6
    Points: 1,680, Level: 9
    Achievements:
    7 years registered

    Join Date
    Mar 2011
    Posts
    14
    Helped
    0 / 0
    Points
    1,680
    Level
    9

    Re: Generating Sine Wave Through External DAC (STM32)

    Thank you, I will keep in mind that too!



--[[ ]]--