STM32: How to implement a Closed-Loop DAC and ADC

STM32 HAL Tutorial: Feedback Control Using DAC and ADC

Abstract

Learn how to implement closed-loop control on STM32 using DAC and ADC with HAL. Step-by-step guide for real-time analog feedback systems.

1. Introduction

Closed-loop control uses ADC measurements to adjust a DAC output dynamically:

  • Example: Voltage regulator, motor control, or sensor calibration
  • ADC reads the system output
  • MCU adjusts DAC to achieve target value

By the end of this episode, you’ll be able to:

  1. Read analog input via ADC
  2. Adjust DAC output based on feedback
  3. Implement a simple control loop

2. Prerequisites

  • STM32 board with ADC and DAC
  • STM32CubeIDE installed
  • Knowledge of HAL, DMA, and timers

3. Basic Closed-Loop Flow

1. Initialize ADC and DAC

2. Set target analog value

3. In a loop:

  • Read ADC
  • Compare to target
  • Compute error
  • Adjust DAC output
				
					uint16_t adcValue = HAL_ADC_GetValue(&hadc1);
uint16_t dacValue = target + Kp * (target - adcValue);
HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dacValue);

				
			
  • Kp is proportional gain for simple feedback

4. Using DMA for Continuous Feedback

  • Use ADC + DAC in DMA mode to reduce CPU load
  • Circular buffer can hold multiple ADC samples
  • Update DAC continuously based on buffer average
				
					HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcBuffer, BUFFER_SIZE);
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);

				
			
  • Loop computes average of ADC buffer → sets DAC

5. Hands-On Lab Example

1. Connect DAC output to the ADC channel

2. Initialize ADC to read input signal (make sure to click on the GPIO and + ADC)

3. Implement feedback loop to create a saw tooth waveform

				
					/* USER CODE BEGIN PV */
uint32_t value_adc;
uint32_t value_dac=0;
/* USER CODE END PV */

				
			
				
					 /* USER CODE BEGIN 2 */
 HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);
 HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value_dac);
 HAL_ADCEx_Calibration_Start(&hadc1);
 HAL_ADC_Start(&hadc1);
 /* USER CODE END 2 */

				
			
				
					 /* USER CODE BEGIN WHILE */
 while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
	  HAL_ADC_Start(&hadc1);
	  HAL_ADC_PollForConversion(&hadc1,10);
	  value_adc=HAL_ADC_GetValue(&hadc1);
	  HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value_dac);
	  value_dac++;
	  if(value_dac>4095){
		  value_dac=0;
	  }
	  HAL_Delay(1);
 }
 /* USER CODE END 3 */

				
			

4. Observe ADC and DAC registers, variables and the wave form using the scope

6. Advantages

  • Real-time analog feedback without external circuitry
  • Low CPU overhead if DMA is used
  • Can implement sensor calibration, voltage control, or analog signal tracking

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top