You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Clyne de6256dd45 add DAC/IIR example 2 years ago
..
Makefile add DAC/IIR example 2 years ago
README.md add DAC/IIR example 2 years ago
main.c add DAC/IIR example 2 years ago

README.md

2. DAC output with an IIR filter

DAC initialization

This example uses the DAC with minimal configuration.

Enable the DAC's clock through the RCC:

RCC->APB1ENR1 |= RCC_APB1ENR1_DAC1EN;

Then, just enable DAC channel one. This will output over pin PA4:

DAC1->CR = DAC_CR_EN1;

We rely on the default/reset configuration of the other DAC registers. In this configuration, the DAC is running without a hardware or software trigger; instead, the DAC will update its output whenever we provide a new output value.

There is a variety of output registers available for different bit-sizes and alignments. We will stick to the basic 12-bit, right-aligned register DHR12R1.

IIR filter

The filter will run in a while loop, reading samples from the ADC and using them to produce new DAC output data.

The first-order recursive equation is y[n] = a*y[n-1] + b*x[n]. Constants a and b set the weights for the previous output sample and current input sample; their sum should not be greater than one.

const float a = 0.5f;
const float b = 0.5f;

In the while loop, we read our input sample from the ADC (x[n]) and calculate the new output value y:

unsigned int yprev = 0; // y[n-1]
while (1) {
    unsigned int x = adc_read();
    unsigned int y = a * yprev + b * x;

The new output value is then sent out over the DAC and stored in yprev for the next calculation/iteration.

    DAC1->DHR12R1 = y;
    yprev = y;

Finally, we add a small delay to have some basic control over the sampling rate. Increasing the loop's max value may make the filter's effect more visible, while decreasing it will minimize the observed effect.

Ideally, the sampling rate would instead be controlled by setting the speed of the clock given to the ADC and configuring the registers responsible for the conversion and sampling timings.

    for (int i = 0; i < 100; ++i);
}