Introduction
The advanced-control timers (TIM1&TIM8) consist of a 16-bit auto-reload counter driven by
a programmable prescaler ,
The general-purpose timers (TIM2 to TIM5) consist of a 16-bit or 32-bit auto-reload counter driven by a
programmable prescaler
The TIM9 to TIM14 general-purpose timers consist of a 16-bit auto-reload counter driven by
a programmable prescaler
It may be used for a variety of purposes, including measuring the pulse lengths of input signals (input capture) or generating output waveforms (output compare, PWM,
complementary PWM with dead-time insertion). Pulse lengths and waveform periods can be modulated from a few microseconds to several milliseconds using the timer prescaler and the RCC clock controller prescalers
The basic timers TIM6 and TIM7 consist of a 16-bit auto-reload counter driven by a
programmable prescaler. They may be used as generic timers for time-base generation but they are also specifically used to drive the digital-to-analog converter (DAC). In fact, the timers are internally
connected to the DAC and are able to drive it through their trigger outputs.
The timers are completely independent, and do not share any resources
TIMER Generic features
The Timer features include:
1. 16-bit up, down, up/down auto-reload counter.
2. 16-bit programmable prescaler allowing dividing (also on the fly) the counter clock frequency either by any
factor between 1 and 65536.
3. Up to 4 independent channels for:
– Input Capture
– Output Compare
– PWM generation (Edge and Center-aligned Mode)
– One-pulse mode output
4. Synchronization circuit to control the timer with external signals and to interconnect several timers together.
5. Supports incremental encoder for positioning purposes
How to use this driver
1. Initialize the TIM low level resources by implementing the following functions depending on the selected
feature:
– Time Base : HAL_TIM_Base_MspInit()
– Input Capture : HAL_TIM_IC_MspInit()
– Output Compare : HAL_TIM_OC_MspInit()
– PWM generation : HAL_TIM_PWM_MspInit()
– One-pulse mode output : HAL_TIM_OnePulse_MspInit()
– Encoder mode output : HAL_TIM_Encoder_MspInit()
2. Initialize the TIM low level resources :
a. Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
b. TIM pins configuration
◦ Enable the clock for the TIM GPIOs using the following function:
__HAL_RCC_GPIOx_CLK_ENABLE();
◦ Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
3. The external Clock can be configured, if needed (the default clock is the internal clock from the APBx), using the following function: HAL_TIM_ConfigClockSource, the clock configuration should be done before any start function.
4. Configure the TIM in the desired functioning mode using one of the Initialization function of this driver:
– HAL_TIM_Base_Init: to use the Timer to generate a simple time base
– HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an Output
Compare signal.
– HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a PWM signal.
– HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an external signal.
– HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer in One Pulse
Mode.
– HAL_TIM_Encoder_Init: to use the Timer Encoder Interface.
5. Activate the TIM peripheral using one of the start functions depending from the feature used:
– Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT()
– Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT()
– Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT()
– PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT()
– One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT()
– Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(),
HAL_TIM_Encoder_Start_IT().
6. The DMA Burst is managed with the two following functions: HAL_TIM_DMABurst_WriteStart()
HAL_TIM_DMABurst_ReadStart()
For this blog we are going to use timer in output compare mode
Creating STM32 executable projects steps are available on this link , please follow steps 1 to 9 as per blog, here we will start from step 11. PA9 & PA10 Pin used for debugging purpose as UART Tx & UART Rx respectively. this blog is specially to demonstrate timer in output compare mode, output will be available in serial terminal.
to learn more about timer in output PWM mode click here
10. Clock configuration
System clock: 16 MHz , APB2 timer & peripheral clock 16 MHz, APB1 timer clock 16 MHz & APB1 peripheral clock 8 MHz
11. Timer Configuration
Go to System mode > Timers > TIM2 > Clock Source > Internal Clock
Channel 1 > Output Compare mode
12. Parameter settings >
Prescaler : 2047 & Counter period : 15625 , Pulse: 7813, duty Cycle: 50%
APB1 clock : 16MHz, Interrupt time interval after calculation : 2 Seconds
13. Pin configuration
Enable TIM2 Interrupt
14. Press below icon for code generation
15. Sample Code:
uint8_t aShowTime[50] = {0}; uint8_t aShowDate[50] = {0}; /* USER CODE BEGIN PV */ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { if ( htim->Instance == TIM2) { RTC_CalendarShow(aShowTime, aShowDate); printf(GRN"aShowTime %s\n",aShowTime); } } int main(void) { MX_RTC_Init(); MX_TIM2_Init(); // For PWM Without Interrupt use this function HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_1); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate) { RTC_DateTypeDef sdatestructureget; RTC_TimeTypeDef stimestructureget; /* Get the RTC current Time */ HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN); /* Get the RTC current Date */ HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN); /* Display time Format : hh:mm:ss */ sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds); /* Display date Format : mm-dd-yy */ sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year); }
16. Output is available at PA5 pin, connect this pin to oscilloscope probe to verify output.
17. configure all channels as output compare mode.
Channel 1, Channel 2, Channel 3, Channel 4 > Output Compare mode
Configure compare channel: Pulse: 3000, 6000, 9000, 12000.
uint8_t aShowTime[50] = {0}; uint8_t aShowDate[50] = {0}; /* USER CODE BEGIN PV */ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { if ( htim->Instance == TIM2) { RTC_CalendarShow(aShowTime, aShowDate); printf(GRN"aShowTime %s\n",aShowTime); } } int main(void) { MX_RTC_Init(); MX_TIM2_Init(); // For PWM Without Interrupt use this function HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_1); HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_2); HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_3); HAL_TIM_OC_Start_IT(&htim2,TIM_CHANNEL_4); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } } static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate) { RTC_DateTypeDef sdatestructureget; RTC_TimeTypeDef stimestructureget; /* Get the RTC current Time */ HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN); /* Get the RTC current Date */ HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN); /* Display time Format : hh:mm:ss */ sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds); /* Display date Format : mm-dd-yy */ sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year); }
18. Output is available at PA5, PA3, PA2, PA1 pins, connect this pins to oscilloscope probe to verify output.
Software Tools:
- STM32CubeIDE
- STM32CubeMx
- Teraterm
Hardware Setup:
- STM32F429IDISCOVERY board
- Mini USB Cable
- Jumper wire
Conclusion:
Successfully demonstrated timer in output compare mode.
If you enjoyed this article, share your feedback.
References:
- STM32 HAL Library
- STM32 UM1718 document