This project will cover the configuration and implementation of an STM32 system where an Analog-to-Digital Converter (ADC) reads a potentiometer's voltage and uses that value to control the duty cycle of a Pulse Width Modulation (PWM) signal, effectively dimming an LED. It demonstrates the interaction between analog input, digital conversion, and timer-based output control using three distinct ADC data handling methods.
In Polling Mode, the CPU manually initiates each analog conversion and then idles in a busy-loop, continuously checking the status register until the conversion is complete. This approach is simple but inefficient, as it fully occupies the CPU during the entire conversion process, making it suitable only for applications where the microcontroller has no other tasks to perform.
In Interrupt Mode, the ADC is configured to generate an interrupt request upon the completion of a conversion. This allows the CPU to perform other meaningful work in the main program loop and only be diverted to handle the new ADC result when it is ready. This method is far more efficient than polling and is ideal for systems that must respond to other events while sampling analog sensors.
In DMA Mode, the Direct Memory Access controller is configured to manage the data transfer from the ADC's data register directly to a memory variable. This completely offloads the data handling task from the CPU, which is free to execute complex code without interruption. The DMA operates in the background, providing seamless and efficient data flow for high-performance or continuous sampling applications.
In PWM Generation Mode, a timer is configured to output a periodic square wave on a GPIO pin. The duty cycle is dynamically updated by the main application based on the latest ADC reading, providing real-time control of the LED's brightness.
STM32CubeMX Configuration- Create new STM32F103C6 project.
- Set system clock to 8 MHz (HSI for ADC stability).
- Configure ADC1:
-In the Categories tab, select ADC1.
-Enable IN7 (Channel 7 on PA7) for the potentiometer.
- In the NVIC Settings tab, enable ADC1 and ADC2 global interrupts.
- In the DMA Settings tab, click Add and select ADC1.
_ Set Mode to Normal. && Set Data Width to Half Word (for both Peripheral and Memory).
- Configure TIM2 for PWM:
- In the Categories tab, select TIM2.
- Select Internal Clock as the clock source.
- Enable PWM Generation CH2 (Channel 2 on PA1).
- In the Parameter Settings tab:
_ Set the Prescaler to achieve a desired frequency (e.g., 8-1 for ~1kHz with a 8MHz clock).
_Set the Counter Period to 65535 (for maximum resolution).
- Generate the initialization code.
- Open generated project
- Add application logic in main.c (e.g.,
HAL_ADC_Start_DMA,HAL_TIM_PWM_Start
) - Build and debug
- Add STM32F103C6 to schematic.
- Add components:
- A potentiometer (POT-HG) connected to PA7 and 3.3V.
- Three PWM outputs (PWM0, PWM1, PWM2) are connected to a rotary switch (SW1),The selected PWM signal is routed to PA1.
- Load the compiled .hex file into the MCU.
- Start the simulation and rotate the potentiometer to see the LED brightness change and the PWM duty cycle adjust on the oscilloscope.
If you have any questions or suggestions don't hesitate to leave a comment below
Comments