HAL DAC How to Use ¶
- group DAC_How_To_Use
-
DAC peripheral main features ¶
DAC channels ¶
On this STM32 series, DAC instances feature one or two channels depending on the device.
DAC channels have configurable resolution: 12-bit or 8-bit. They can be connected to device GPIO or on-chip peripherals.
DAC channel conversion can be triggered by:
External event: EXTI Line
Other peripherals (timers, low-power timers, …)
Software
DAC output buffer mode feature ¶
Each DAC channel integrates an output buffer that can be used to reduce the output impedance and drive external loads directly without adding an external amplifier. To enable the output buffer, use HAL_DAC_SetConfigChannel() to set HAL_DAC_OUTPUT_BUFFER_ENABLED.
Channel in separate mode, input and output operation ¶
to enable one channel and start conversion for this channel.
Caution: when software trigger is selected, the call to
HAL_DAC_StartChannel() starts the first conversion with the data previously present in DAC_DHRx register. Therefore, call HAL_DAC_SetChannelData() first to set the initial value of DAC_DHRx. Then subsequent conversions use data set with HAL_DAC_SetChannelData().Use HAL_DAC_StopChannel() to disable one channel and stop conversion for this channel.
Use HAL_DAC_StartChannel_DMA()
to enable one channel and start conversion for this channel using DMA to feed DAC converters.
Caution: the first issued trigger starts the conversion with the data previously present in DAC_DHRx register. Therefore, call
HAL_DAC_SetChannelData() first to set the initial value of DAC_DHRx.Use HAL_DAC_StopChannel_DMA() to disable the channel and stop conversion for that channel using DMA.
Use HAL_DAC_SetChannelData() to set digital data to be converted.
Use HAL_DAC_GetChannelData() to get digital data to be converted.
Dual-channel mode, input and output operation ¶
Dual mode allows the use of two DAC channels for simultaneous operation.
Use HAL_DAC_StartDualChannel() to enable both channels and start conversion for dual mode operation.
Caution: when software trigger is selected, the call to HAL_DAC_StartDualChannel() starts the first conversion with the data previously present in DAC_DHRx register. Therefore, a first call to HAL_DAC_SetDualChannelData is required in order to fix the initial value of DAC_DHRx. Then subsequent conversions use data set with HAL_DAC_SetDualChannelData().
Use HAL_DAC_StopDualChannel() to disable both channel and stop conversion for dual mode operation.
Use HAL_DAC_StartDualChannel_DMA() to enable both channels and start conversion for dual mode operation using DMA to feed DAC converters.
Caution: the first issued trigger starts the conversion with the data previously present in DAC_DHRx register. Therefore, a first call to HAL_DAC_SetDualChannelData is required in order to fix the initial value of DAC_DHRx. The same callbacks used in single mode are called in dual mode to notify transfer completion (half or complete), errors, or underrun.
Use HAL_DAC_StopDualChannel_DMA() to disable both channel and stop conversion for dual mode operation using DMA to feed DAC converters.
When dual-channel mode is enabled (i.e. DAC channel 1 and channel 2 are used simultaneously): use HAL_DAC_GetDualChannelData() to get digital data to be converted and use HAL_DAC_SetDualChannelData() to set digital data to be converted simultaneously in channel 1 and channel 2.
DAC sample and hold feature ¶
For each converter, two modes are supported: “normal mode” and “sample and hold” mode (i.e. low-power mode). In the “sample and hold” mode, the DAC core converts data and then holds the converted voltage on a capacitor. If the DAC output is connected to an on-chip peripheral, this capacitor is internal. If the DAC output is connected to a pin, an external capacitor must be connected to the output pin.
When not converting, the DAC cores and buffer are completely turned off between samples and the DAC output is tri-stated, therefore reducing the overall power consumption. A new stabilization period is needed before each new conversion.
The sample and hold mode allows setting internal or external voltage with a low-power consumption cost (output value can be changed at any given rate either by CPU or DMA).
The sample and hold block and registers use LSI and run in several power modes: run mode, sleep mode, low-power run, low-power sleep mode and stop1 mode.
Low power stop1 mode allows only static conversion.
To enable sample and hold mode, enable LSI using HAL_RCC_LSI_Enable().
Use HAL_DAC_SetConfigChannelSampleAndHold() to set sample_time_cycle, hold_time_cycle, and refresh_time_cycle. Use HAL_DAC_EnableChannelSampleAndHold() or HAL_DAC_DisableChannelSampleAndHold() to enable or disable sample and hold mode.
DAC calibration feature ¶
DAC channels have calibration capabilities: aim to correct some offset in the output buffer.
The DAC uses either factory calibration settings or user-defined calibration settings (i.e. trimming mode).
The user-defined settings can be determined using self-calibration handled by HAL_DAC_CalibrateChannelBuffer().
Use HAL_DAC_CalibrateChannelBuffer() to:
Calibrate one DAC channel and also to set automatically the trimming value.
Run the calibration automatically.
Enable the user trimming mode.
Update a structure with trimming values using fresh calibration results.
Use HAL_DAC_GetChannelBufferCalibrationValue() to retrieve the trimming value (the trimming factory setting after reset, or the user setting if HAL_DAC_SetChannelBufferCalibrationValue()
has been used at least once after reset).
The user might store the calibration results for later usage (for instance: monitoring the trimming as a function of temperature).
Use HAL_DAC_SetChannelBufferCalibrationValue() to set the trimming value.
DAC wave generation feature ¶
Both DAC channels can be used to add a noise wave or a triangle wave.
Use HAL_DAC_EnableChannelAddingTriangleWave() to enable adding triangle wave signal.
Use HAL_DAC_DisableChannelAddingTriangleWave() to disable adding triangle wave signal.
Use HAL_DAC_EnableChannelAddingNoiseWave() to enable adding noise wave signal.
Use HAL_DAC_DisableChannelAddingNoiseWave() to disable adding noise wave signal.
DAC data format ¶
The DAC data alignment format can be:
8-bit right alignment using HAL_DAC_DATA_ALIGN_8_BITS_RIGHT
12-bit left alignment using HAL_DAC_DATA_ALIGN_12_BITS_LEFT
12-bit right alignment using HAL_DAC_DATA_ALIGN_12_BITS_RIGHT
DAC data value to voltage correspondence ¶
The analog output voltage on each DAC channel pin is determined by the following equation: DAC_OUTx = (Vref+) x (DOR / 4095)
where DOR is the Data Output Register, and Vref+ is the input voltage reference (refer to the device datasheet)
e.g.:Assuming that Vref+ is equal to 3.3V, to set DAC_OUT1 to 0.7 V, set data value 868 in DOR register:
DAC_OUT1 = (3.3) x (868 / 4095) = 0.7 V
DMA requests ¶
A DAC channel can operate with data transfer by DMA using HAL_DAC_StartChannel_DMA(). DMA requests are generated when an external trigger (not a software trigger) occurs.
High frequency interface mode ¶
The high frequency interface informs the DAC instance about the bus frequency in use. This is mandatory information for the DAC (as internal timing of the DAC is bus-frequency-dependent). Provide this information with the high_frequency_mode parameter handled in HAL_DAC_SetConfig().
The optimum frequency interface mode for the DAC peripheral can be determined by calling HAL_DAC_GetOptimumFrequencyMode(). Then set the optimum high frequency interface mode (HFSEL bits) with HAL_DAC_SetConfig().
The high frequency mode is the same for all converters of the same DAC instance.
How to use the HAL DAC module driver ¶
The DAC HAL driver can be used as follows (in separate channel configuration): ¶
Initialize the DAC low-level resources: ¶
Enable the DAC APB clock to get write access to the DAC. Enable the DACx interface clock.
Note: the clock is enabled inside
HAL_DAC_Init() whenever USE_HAL_DAC_CLK_ENABLE_MODEL is not set to HAL_CLK_ENABLE_NO.Declare a hal_dac_handle_t handle structure, for example: hal_dac_handle_t hdac;
Initialize the DAC instance using HAL_DAC_Init().
Configure the DAC output GPIO pins for the used channels in analog mode.
Configure the DAC instance with HAL_DAC_SetConfig().
Configure the DAC channel with HAL_DAC_SetConfigChannel().
If needed, link the DAC to DMA with HAL_DAC_SetChannelDMA().
Enable the DAC channel with HAL_DAC_StartChannel() or HAL_DAC_StartChannel_DMA().
Polling mode, input and output operation ¶
Start the DAC peripheral on a given channel with HAL_DAC_StartChannel().
To change the data output value, use the HAL_DAC_SetChannelData() function.
To read the last DAC data output value, use the HAL_DAC_GetChannelData() function.
Stop the DAC peripheral on a given channel with HAL_DAC_StopChannel().
DMA mode, input and output operation ¶
Start the DAC peripheral on a given channel using DMA with HAL_DAC_StartChannel_DMA()
, and specify a data buffer and the data size to be converted through DMA.
Caution: when software trigger is selected, the call to HAL_DAC_StartDualChannel() starts the first conversion with the data previously present in DAC_DHRx register. Therefore, a first call to
HAL_DAC_SetChannelData() is required in order to fix the initial value of DAC_DHRx.At the midpoint of the data transfer, HAL_DAC_ConvHalfCpltCallback() function is executed (the user can add custom code by overriding this weak function).
At the end of the data transfer, HAL_DAC_ConvCpltCallback() function is executed (the user can add custom code by overriding this weak function).
If a transfer error occurs, HAL_DAC_ErrorCallback() function is executed (the user can add custom code by overriding this weak function).
If a DMA underrun occurs, a DAC interrupt triggers and executes the internal function HAL_DAC_IRQHandler(). HAL_DAC_ErrorCallback() function is executed (the user can add custom code by overriding this weak function).
Stop the DAC peripheral using HAL_DAC_StopChannel_DMA().
Callback registration ¶
The compilation define, “USE_HAL_DAC_REGISTER_CALLBACKS”, when set to 1, allows the user to configure driver callbacks dynamically.
Use HAL_DAC_RegisterConvHalfCpltCallback() to register HAL_DAC_ConvHalfCpltCallback(): callback when a half transfer is completed on a channel.
Use HAL_DAC_RegisterConvCpltCallback() to register HAL_DAC_ConvCpltCallback(): callback when a transfer is completed on a channel.
Use HAL_DAC_RegisterErrorCallback() to register HAL_DAC_ErrorCallback(): callback when an error occurs on a channel.
These functions take the HAL peripheral handle and a pointer to the user callback function as parameters.
By default, after the first HAL_DAC_Init(), all callbacks are reset to the corresponding legacy weak (overridden) functions. Register callbacks only in state HAL_DAC_STATE_SEPARATE_CHANNEL_CONFIGURED or HAL_DAC_STATE_DUAL_CHANNEL_CONFIGURED. When the compilation define USE_HAL_DAC_REGISTER_CALLBACKS is set to 0 or not defined, the callback registering feature is not available, and weak (overridden) callbacks are used.
Note
Differentiation is made by the literal DAC_NB_OF_CHANNEL (defined in the DFP of each device).
Note
The trigger selection depends on the PWR mode, in STOP modes, only the triggers relative to peripherals that are functional in STOP modes are possible (ex: EXTI and LPTIM).
Note
Refer to the device datasheet for more details about output impedance value with and without output buffer.
Note
A helper macro is available to calculate the DAC conversion data (unit: digital value) corresponding to a voltage (unit: mVolt). Refer to the LL DAC driver: LL_DAC_CALC_VOLTAGE_TO_DATA