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.

72 lines
1.9 KiB
Markdown

# 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:
```cpp
RCC->APB1ENR1 |= RCC_APB1ENR1_DAC1EN;
```
Then, just enable DAC channel one. This will output over pin PA4:
```cpp
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.
```cpp
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`:
```cpp
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.
```cpp
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.
```cpp
for (int i = 0; i < 100; ++i);
}
```