This project explores the STM32 Timer for One-Pulse PWM Input Capture in Proteus simulation. We will demonstrate how to configure the timer to generate One-Pulse PWM signals and capture input effectively.
Things used in this project
Software apps and online services:
1-Â STMicroelectronics STM32CubeMX
2-Â STMicroelectronics STM32CubeIDE
3-Â Proteus 8
STM32 Timer Modes and Simulation with Proteus
This project focuses on the different timer modes of the STM32 microcontroller and how to simulate them using Proteus software. Specifically, we will explore three timer modes: One-Pulse, PWM Output, and Input Capture.
Generating Single Pulses for Event Triggering:
In the One-Pulse mode, the STM32 Timer generates a single pulse when the timer reaches a specific value. This is useful for generating events such as triggering a sensor or actuator.
Controlling Duty Cycle for LED Brightness or Motor Speed :
In the PWM Output mode, the STM32 Timer generates a pulse-width modulated signal to control the duty cycle of an output signal, which can be used to adjust the brightness of an LED or the speed of a motor.
Measuring Period and Frequency of Input Signals :
Finally, the Input Capture mode allows the STM32 Timer to measure the period and frequency of an input signal, which is essential for detecting the frequency of an input signal or measuring the speed of a motor.
Through this project, we will learn how to configure the STM32 Timer One-Pulse PWM Input Capture modes for various applications. Additionally, we will discover how to simulate our designs using Proteus software, enabling us to test our circuits before implementing them in hardware.
STM32CubeMX Configuration:
- Open CubeMX & Create New Project Choose The Target MCUÂ STM32F103C6Â & Double-Click Its Name
- Go To The Clock Configuration & Set The System Clock To 60MHz
Configuration for the TIMER One-Pulse Mode:
- In the Categories tab, select the TIM3 then (enable Internal Clock & One Pulse Mode & PWM Generation Channel 3)
- In the Parameter settings tab, set the (Prescaler = 6000 & Counter Peroid = 10)Â The purpose of this settings is to generate a periodic time event with a 1ms interval which represents the length of the pulse.
- In the PWM Generaion Channel 3, set the (Mode = PWM mode 2 & Pulse 2=1)
- In the NVIC setting tab, Enable TIM3 global interrupt
Configuration for the TIMER PWM Output Mode:
- In the Categories tab, select the TIM2 then (enable Internal Clock & PWM Generation Channel 3 and 4)
- In the Parameter settings tab, set the (Prescaler = 60 & Counter Peroid = 100)
Configuration for the TIMER Input Capture Mode:
- In the Categories tab, select the TIM1 then (enable Internal Clock & Input Capture direct mode Channel 4)
- In the Parameter settings tab, set the (Prescaler =60 & Counter Peroid= 65535)
- In the Inpute Capture Channel 4 set Rising Edge
- In the NVIC setting tab, Enable TIM1 capture compare interrupt
- Generate The Initialization Code & Open The Project In CubeIDE
- Write The Application Layer Code
STM32CubeIDE Configuration:
In file name :main.c
#include "main.h" /* USER CODE BEGIN PFP */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim == &htim3) { pulseEND = 1 ; } } /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ #define TIMCLOCK 60000000 #define PRESCALAR 60 #define ERRUR 416 // ERRUR Simulation is not running in real time uint32_t IC_Val1 = 0; uint32_t IC_Val2 = 0; uint32_t Difference = 0; uint8_t MSG[50]; int Is_First_Captured = 0; float frequency = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) { if (Is_First_Captured==0) // if the first rising edge is not captured { IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4); // read the first value Is_First_Captured = 1; // set the first captured as true } else // If the first rising edge is captured, now we will capture the second edge { IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4); // read second value if (IC_Val2 > IC_Val1) { Difference = IC_Val2-IC_Val1; } else if (IC_Val1 > IC_Val2) { Difference = (0xffffffff - IC_Val1) + IC_Val2; } float refClock = TIMCLOCK/(PRESCALAR); frequency = refClock/Difference; int x = frequency; x-=ERRUR; sprintf(MSG,"result = %d \n\r",x); HAL_UART_Transmit(&huart1,MSG, sizeof(MSG), 100); __HAL_TIM_SET_COUNTER(htim, 0); // reset the counter Is_First_Captured = 0; // set it back to false } } } /* USER CODE END 0 */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM1_Init(); MX_TIM2_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); while (1) { if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)==GPIO_PIN_SET) { HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); //start the TIMER 3 in PWM MODE HAL_Delay(1000); //1 second delay TIM3->ARR = 1 ; // signal period of the PWM __HAL_TIM_ENABLE(&htim3); //ENable TIM3 while(!pulseEND){}; pulseEND=0; } else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14)==GPIO_PIN_SET) { HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); //start the TIMER 2 in PWM MODE uint32_t CH1; while (CH1 < 99 ) { TIM2->CCR2 = CH1; CH1+= 1 ; HAL_Delay(1); } while (CH1 > 0 ) { TIM2->CCR2 = CH1; CH1-= 1 ; HAL_Delay(1); } } else if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15)==GPIO_PIN_SET) { TIM2->CCR3 = 50; //set the PWM duty cycle of TIMER2 to 50% HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //start the PWM signal on TIM2 HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_4);//starts an interrupt input capture } else { HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2); HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2); HAL_TIM_IC_Stop_IT(&htim1, TIM_CHANNEL_4); } } /* USER CODE END 3 */ }
Proteus Configuration :
- Open Proteus & Create New Project and click next
- Click on Pick Device
- Search for STM32F103C6 & SW-SPDT(switch) &LED_RED, ORANGE, YELLO
- Click on Virtual Instruments Mode then choose (VIRTUAL TERMINAL & OSCILLOSCOPE)
- Click on Terminal Mode then choose (DEFAULT & POWER &GROUND)
- finally make the circuit below and start the simulation
That’s all!
If you have any questions or suggestions don’t hesitate to leave a comment below
6 comments
[…] STM32 […]
[…] implement this system, we can use three different methods to read the ADC result and set the PWM duty cycle using ADC Polling, Interrupt, and DMAÂ modes […]
[…] with the HX711 load cell, ensuring accurate weight measurement. We’ll then enable the TIM1 timer to create precise microsecond delays for the HX711 communication protocol, crucial for […]
[…] Pulse Width Modulation (PWM) is a method used to create analog signals from digital sources by adjusting the duration of pulses […]
[…] learn how to control servo motors using STM32 microcontrollers by utilizing Pulse Width Modulation (PWM) to achieve precise positioning. Servo motors are crucial components in robotics and automation due […]
[…] your firmware, configure the GPIO pins as outputs and utilize Pulse Width Modulation (PWM) for speed control. This configuration allows efficient management of the motor’s direction […]