DDS function generator implemented with STM32 BluePill board, based on STM32F103C8T6 microcontroller, 8-bit R-2R ladder DAC and additional circuitry for removing the DC offset.
The user interface is realized with OLED display based on SSD1306 controller and incremental rotary encoder.
Goal specs:
- Waveforms: sine, square, triangle, sawtooth (arbitrary waveforms can easily be added)
- Frequency: 0 - 35 kHz, frequncy resolution is variable
- Amplitude: 500 - 3000 mV (software control)
Additional tests and modifications should be done to reach the specs.
The MCU generates the data for the 8-bit R-2R ladder D/A converter.
Two of the op amps inside TL084 are used as voltage buffers, one for the output of the DAC and the second one for the variable voltage generated by filtering PWM signal outputed by the MCU. This variable voltage is used to remove the DC offset of the generated waveform. Removing the DC offset is realised with the third op amp, which subtracts the output of the DAC and the variable voltage and multiplies this difference by 1.82 so the output signal has maximum amplitude of 3 V.
To generate the data for the DAC, each waveform has lookup table stored in the Flash memory of the MCU, with 256 elements with size 1 byte. The values stored in the table are actually the data that need to be fed into the DAC. During runtime, whole or part of the table is copied into SRAM of the MCU, based on the frequency of the waveform. By changing the LUT, arbitrary periodic waveforms can be generated.
Timer 2 of the MCU is configured to generate DMA request. It has base clock of 14.4 MHz and the value stored in the Auto-Reload Register (ARR) depends on the frequency of the waveform. The value for ARR is calculated using the following formula:
ARR=TIM2\_BaseClock/(L\*f) - 1where L is the size of the LUT stored in SRAM and f is the frequency of the waveform.
The DMA unit transfers data from the LUT in SRAM to the GPIOA output data register. The pins PA0-PA7 are used to output the data to the DAC. Because the output data register of GPIOA is used, the pins PA8-PA15 can not be used as general purpose outputs, but can be used in the other modes. This problem can be resolved by writing to the bit set reset register instead of the output data register.
The software was written in C, using STM32 HAL library, in STM32CubeIDE.
I have also written SSD1306 driver which can be further developed to include more functionalities.
The code also includes isntantenous rotational speed measurement for the rotary encoder with goal to change the values for frequency and amplitude based on the rotational speed, i.e. faster turning of the encoder results in greater change of the value. This part of the code should also be improved, for better user experience.
The following waveforms are measured with DSO150 oscilloscope.
- Additional tests and calibration to conclude the frequency and amplitude resolution
- USB virtual serial port to transfer LUT data for arbitrary waveform
- Low-pass filter after DAC output