4 Generating Sine Wave Signal

The DAC can be used to obtain a sine wave signal by generating a defined number of discrete samples of the desired analog signal. Each sample is characterized by a voltage level and by a time duration. This mechanism provides an approximation of the desired sine wave signal.

In this application, the number of steps used is 100. To obtain a signal frequency of 50 Hz (translated into a period of 20 ms), the time duration between two signal samples will be (1000000/Desired Frequency)/Number of Steps [µs] = (1000000/50 Hz)/100 (steps) [µs] = 200 µs.

To generate the “steps” that approximate the sine wave, the integer values to be written to the DAC0.DATA register will be computed using the formula below:

sin e W a v e [ i ] = D C O f f s e t + A sin ( i 2 π N u m b e r o f S t e p s )

,where i is the sample index and takes values from 0 to Number of Steps, A is the signal amplitude (the maximum possible value is the DAC reference voltage), and the Number of Steps represents the number of samples used to construct the sine wave signal.

To generate a sine wave signal between 0V and 4.34V, the DAC must convert integers ranged between 0 and 255. Therefore, because the DAC will only generate positive voltage values, the DC Offset will be 128 (this is also the mean value of the sine wave signal). To obtain the maximum of 4.34V, the amplitude must be 127. The data to be written to the DAC0.DATA register is presented on the graph below.

Figure 4-1. DAC Input Digital Values

The ideal voltage values that will be available on the DAC output are presented on the graph below.

Figure 4-2. DAC Output Analog Values

To avoid spending time inside the infinite loop by computing the signal samples in real-time, the samples are computed at the beginning of the application and stored in a Look-up Table. The function implementation for this computation is presented below.

for(uint16_t i = 0; i < SINE_WAVE_STEPS; i++)
{
    sineWave[i] = SINE_DC_OFFSET + SINE_AMPLITUDE * sin(i * M_2PI / SINE_WAVE_STEPS);
}

The data is then written to the DAC0.DATA register inside the infinite loop using a 200 µs delay, as described above.

while (1)
{
    DAC0.DATA = sineWave[i++];    
    i = i % SINE_WAVE_STEPS;        
    _delay_us(STEP_DELAY_MICROS);
}
Tip: The full code example is also available in the Appendix section.

An MCC generated code example for AVR128DA48, with the same functionality as the one described in this section, can be found here: