Direct digital frequency synthesis technology and its implementation of C + +

Source: Internet
Author: User
Tags sin

The Ddfs-direct digital Frequency synthesizer Direct numerical frequency synthesis technique can be used to generate periodic signals of arbitrary waveforms. The so-called Ddfs is simply a look-up method that internally maintains a lookup table that stores a periodic waveform. So the lookup table actually gives a mapping of the phase-to-function value:


Here the phase ω is the linear function of the time t.


Adjusting the output frequency is actually the coefficient kδ of adjusting the phase function.

For example, for example, our lookup table stores a period of sine wave. The lookup table has a length of 1024. The phase of the sine wave is based on the 2π period, so the phase difference between two adjacent items of the lookup table is. This means that the phase of the lookup table is:


It is important to note that the last element corresponds to the phase is not 2π, because phase and phase 0 are actually the same, the lookup table can only appear once.

We also need a phase accumulator and a frequency register, which is used to record what the current phase value is. For example, we use a 16-bit unsigned integer register to record this phase value, then 0 to 65537 (note that this is 65537) corresponds to the phase period of 0 to 2π. The phase changes linearly with time, so we just need to add a fixed phase to the phase accumulator each time. The accumulated value exists in the frequency register, for example, the value of the frequency register is 5, then the value of the phase accumulator is: 0,5,10,15,20,..., 65530,65535,3,8,13,...。 Here more than 65536 of the value, such as 65537 automatic overflow becomes 0, just take advantage of the integer variable of this periodicity.

The value of the frequency register is set to what is appropriate, if our sampling frequency is Fs, we want the output frequency to be f. The length of the lookup table is m, the length of the phase accumulator is n, and the value of the frequency register is K. Then the minimum phase change of the phase accumulator is. The output waveform has a period of fs/f data points. The phase difference between data points is. Then there is the following equation:


The actual calculated k value is not necessarily an integer, rounding is possible. To give a specific example: the sampling frequency is 1kHz, we want to output a 10Hz sine wave, the phase accumulator length is 65536. Then the value of the frequency register should be.

It can be seen that the longer the length of the phase accumulator, the higher the frequency resolution. As a result, phase accumulators are typically designed to be 32-bit or higher in real-world use. The length of the lookup table is usually much shorter, typically 10-bit or 12-bit. At this point, we just need to use the top of the phase accumulator as an indicator of the lookup table.

Direct Digital Frequency Synthesis technology is not only used for hardware to generate a specific function waveform, but also in the field of numerical computing, this technology can be used. Take the example of generating a sine wave. Although the sin () and cos () functions are available in most programming languages, the function is relatively slow to calculate. If you need to call millions of times in your program, it will take a considerable amount of time. Also, as t increases, the computational accuracy of sin (t) decreases. At this point, the advantages of using DDS technology are reflected. First, the table method to ensure that it is faster than any of the existing trigonometric function calculation code is much faster, and secondly, all operations are integer operations to ensure that there is no cumulative calculation error.

Here is the implementation code, which can generate a variety of periodic function waveforms:

#ifndef dds_h_included#define dds_h_includedclass lookuptable{friend class dds;private:unsigned int m_length;    unsigned int m_shift;    Double *m_table;public:lookuptable ();    lookuptable (unsigned int N);    ~lookuptable ();    void sine (double amplitude = 1.0, double baseline = 0.0);    void rect (Double dutycircle = 0.5, double amplitude = 1.0, double baseline = 0.0);    void Sawtooth (Double dutycircle = 0.5, double amplitude = 1.0, double baseline = 0.0); void arbitrary (double table[]);};    Class Dds{private:lookuptable *m_plut;    unsigned int m_iter;    unsigned int m_stride;    unsigned int m_phase;public:dds (lookuptable *plut, unsigned int stride = 1, unsigned int phase = 0);    void Setphase (double phase = 0.0);    void Setfreq (double freq);    void Setfreq (double freq, double FS); Inline double value ();};    inline double dds::value (void) {unsigned int index = (m_iter + m_phase);    index = index >> m_plut->m_shift; Double value = m_plut->M_table[index];    M_iter + = M_stride; return value;} #endif//dds_h_included

#include "dds.h" #include <cstdlib> #include <cmath>lookuptable::lookuptable () {m_length = 0; m_table = NULL;} Lookuptable::~lookuptable () {delete[] m_table;}    lookuptable::lookuptable (unsigned int n) {if (n < 1) {n = 1;    } if (n >) {n = 16;    } m_length = 0x01 << N;    M_shift = 32-n; m_table = new Double[m_length];}  void Lookuptable::sine (double amplitude, double baseline) {if (m_length! = 0) {for (unsigned int i = 0; i < M_length;        i++) {M_table[i] = amplitude * SIN (2 * m_pi/m_length * i) + baseline; }}}void Lookuptable::rect (double dutycircle, double amplitude, double baseline) {if (m_length! = 0) {for ( unsigned int i = 0; i < m_length;             i++) {Double value = (1.0 * I/m_length < dutycircle)? 0:1;        M_table[i] = amplitude * value + baseline; }}}void Lookuptable::sawtooth (double dutycircle, double amplitude, douBle baseline) {double pos, value;            if (m_length! = 0) {for (unsigned int i = 0; i < m_length; i++) {pos = 1.0 * I/M_LENGTH;            if (Pos < dutycircle) {value = Pos/dutycircle;            } else {value = (1.0-pos)/(1.0-dutycircle);        } M_table[i] = amplitude * value + baseline; }}}void lookuptable::arbitrary (double table[]) {if (m_length! = 0) {for (unsigned int i = 0; i < M_leng Th        i++) {M_table[i] = Table[i];    }}}dds::D ds (lookuptable *plut, unsigned int stride, unsigned int phase) {M_iter = 0;    M_plut = Plut;    M_stride = Stride; M_phase = phase;} void Dds::setphase (double phase) {M_phase = round (phase/(2 * m_pi) * 4294967296.00);}    void Dds::setfreq (double omega) {Double stride = Omega/(2 *m_pi) * 4294967296.00; M_stride = round (stride);} void Dds::setfreq (double freq, doubleFS) {Double Omega = 2 *m_pi *freq/fs; Setfreq (Omega);}

#include <iostream> #include "dds.h" using namespace Std;int Main () {    lookuptable Sincos (ten);    LookupTable Sawtooth (ten);    Sincos.sine (2, 0);    Sawtooth.sawtooth (0.3, 1, 0);    DDS dds1 (&sincos);    DDS dds2 (&sincos);    DDS Dds3 (&sawtooth);    Dds1.setfreq (+);    Dds1.setphase (0.0);    Dds2.setphase (3.1415926/2);    Dds2.setfreq (+);    Dds3.setfreq (+);    for (int i =0; I <200; i++)    {        cout << i << "," << dds1.value () << ",";        cout << dds2.value () << "," << dds3.value () << Endl;    }    return 0;}

Plot the output as follows:


I hope this code is useful for everyone.


Direct digital frequency synthesis technology and its implementation of C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.