BojanSof / BluePillWaveGen

DDS function generator build around STM32 BluePill board

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

STM32 BluePill DDS WaveGen

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.

Kicad PCB 3D view

Specs

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.

Working Principle

WaveGen circuit

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.

DAC data generation

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) - 1

where 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.

Software

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.

Experimental results

Protoboard version

The following waveforms are measured with DSO150 oscilloscope.

Sine 60 Hz 3000 mV Sine 60 Hz 2500 mV Sine 500 Hz 2100 mV Sine 2000 Hz 2000 mV Sine 5000 Hz 3000 mV
Sine 10000 Hz 2500 mv Sine 20000 Hz 3000 mv Sine 25000 Hz 1500 mv Sine 30000 Hz 1500 mv Sine 35000 Hz 1500 mv
Square 5000 Hz 3000 mv Triangle 5000 Hz 2500 mv Triangle 9000 Hz 2500 mv Sawtooth 15000 Hz 3000 mv Triangle 35000 Hz 2000 mv

Further improvements

  • 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

About

DDS function generator build around STM32 BluePill board


Languages

Language:C 97.6%Language:Makefile 2.1%Language:Assembly 0.2%