X1 / X2 / N (prescaler)
APB1 clock -------> F. (CK_PSC) ---------------> CK_CNT
If APB1 division factor is 1, the multiplication factor is CK_INT x1
if APB1 division ratio is not 1, CK_INT the multiplication factor is x2
|
|
|||||
SYSCLK | 72 | 168 | 216 | |||
AHB | 72 | 168 | 216 | |||
APB1 (AHB / 4) | 18 | 42 | 54 | |||
CK_INT(x1/x2) | 36 | 84 | 108 | |||
PSC prescaler |
Example: Implementing 0 .5s led flashing of currently used F7 so CK_INT = 108MHz the PSC prescaler: the Prescaler automatic reload registers: Period Time = (Period) (the Prescaler) / CK_INT 0.5 = (Period) (the Prescaler) / 108 000 000 prescaler Prescaler facilitate the calculation of the frequency is set to 108000 (divisible), auto-reload Period to 500 calculated as: 500 * 108,000 / 108,000,000 = 0.5 , however, since the 16-bit register to be bound, 108,000 exceeded 65,535 (2 to the power 16) so a little adjustment: 5000 * 10800 meet the same requirements. So the configuration: the Prescaler = 10800 Period = 5000 adjust timing requirements Time = (Period) (the Prescaler) / CK_INT
From int main () { } begin to understand the implementation of timers
// 1. Enable timer clock __HAL_RCC_TIM3_CLK_ENABLE (); // 2. if the initial timer, configured the Prescaler, Period HAL_TIM_Base_Init (); // 3. starts a timer / interrupt HAL_TIM_Base_Start (); HAL_TIM_Base_Start_IT (); // . 4 set interrupt priority HAL_NVIC_SetPriority (); HAL_NVIC_EnableIRQ (); // 5. write an interrupt service routine TIMx_IRQHandler (); // interrupt service routine HAL_TIM_IRQHandler (); // interrupt handler entry function HAL_TIM_PeriodElapsedCallback (); // timer update interrupt Callback
// started // 1. Custom a TIM initialization function void TIM3_Init () { // ... } int main () { TIM3_Init (); }
// Tim3_Init () do something? void TIM3_Init () { // 1. timer initialization function HAL_TIM_Base_Init (); // takes one parameter } // function prototype: HAL_StatusTypeDef HAL_TIM_Base_Init (TIM_HandleTypeDef * htim) // so set TIM handle TIM_HandleTypeDef htim3; // set up the handle, where necessary parameters are initialized htim3.Instance = TIM3; htim3.Init.Prescaler = 10800 - . 1 ; // prescaler htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // count mode htim3.Init.Period = 5000 - 1; // automatic loading value
@ Results: TIM_HandleTypeDef htim3; void TIM3_Init () { htim3.Instance = TIM3; htim3.Init.Prescaler = 10800 - . 1 ; // prescaler htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // count mode htim3.Init. = Period 5000 - . 1 ; // auto-reload value HAL_TIM_Base_Init (htim3); }
// 2. Then le would enable clock timer // in HAL_TIM_Base_Init (htim3) function there: HAL_TIM_Base_MspInit (htim); // This function Msp represents the callback function, usually in the file stm32f4xx_hal_msp.c file, and if not, own realization is the same // this function is mainly to achieve open clock, GPIO configuration, interrupt priority configuration void HAL_TIM_Base_MspInit (TIM_HandleTypeDef * htim_base) { IF (htim_base-> == Instance TIM3) { __HAL_RCC_TIM3_CLK_ENABLE (); } } // since this function is not only determined for HAL_TIM_Base_Init and TIM3, so Msp function, to perform IF htim_base-> == Instance TIM3 // in this function, a clock TIM open __HAL_RCC_TIM3_CLK_ENABLE ();
// 3. Tim3 open and interrupt void TIM3_Init () { htim3.Instance = TIM3; htim3.Init.Prescaler = 10800 - . 1 ; // prescaler htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // count mode htim3.Init = .Period 5000 - . 1 ; // auto-reload value HAL_TIM_Base_Init (htim3); // new new HAL_TIM_Base_Start_IT (htim3 &); // open timer interrupt }
// . 4 opens the interrupt, the interrupt priority must set the void HAL_TIM_Base_MspInit (TIM_HandleTypeDef * htim_base) { IF (htim_base-> == Instance TIM3) { __HAL_RCC_TIM3_CLK_ENABLE (); // interrupt priority HAL_NVIC_EnableIRQ (TIM3_IRQn); HAL_NVIC_SetPriority ( TIM3_IRQn, . 1 , . 3 ); } }
// 5. Write the interrupt service routine // in start.s file, interrupt trigger function list, find it. void TIM3_IRQHandler ( void ) { // to be written } // what to write it, api TIM, there are interrupt trigger function HAL_TIM_IRQHandler (& htim3); ---> void TIM3_IRQHandler ( void ) { HAL_TIM_IRQHandler ( & htim3); } / / continue to follow HAL_TIM_IRQHandler (& htim3);
/ * The TIM the Update Event * / IF (! __HAL_TIM_GET_FLAG (htim, TIM_FLAG_UPDATE) = the RESET) { IF (! __HAL_TIM_GET_IT_SOURCE (htim, TIM_IT_UPDATE) = the RESET) { __HAL_TIM_CLEAR_IT (htim, TIM_IT_UPDATE); #if (USE_HAL_TIM_REGISTER_CALLBACKS ==. 1) htim - > PeriodElapsedCallback (htim); #else HAL_TIM_PeriodElapsedCallback (htim); #endif / * * USE_HAL_TIM_REGISTER_CALLBACKS / } } // there are various interrupt, update interrupt here to achieve, called HAL_TIM_PeriodElapsedCallback (htim); // so rewrite callback function HAL_TIM_PeriodElapsedCallback (htim);
// Time Update callback function void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef * htim) { // the LED inverted }
#include <rtthread.h> #include <rtdevice.h> #include <board.h> #define LED0 GET_PIN(B,0) #define LED1 GET_PIN(B,1) static rt_uint8_t flag = 0; TIM_HandleTypeDef htim3; void TIM3_Init() { htim3.Instance = TIM3; htim3.Init.Prescaler = 10800-1; //预分频系数 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; //计数模式 htim3.Init.Period = 5000-1; // auto-reload value HAL_TIM_Base_Init ( & htim3); HAL_TIM_Base_Start_IT ( & htim3); // open tim3 interrupt // since opened interrupted, so to set the interrupt priority // supposed to implement their own interrupt function HAL_TIM_Base_MspInit, but in // stm32f7xx_hal_msp.c document has been written, so to write this document interrupt priority level } // after interrupt configuration, implement interrupt service routine // interrupt service function void TIM3_IRQHandler ( void ) { HAL_TIM_IRQHandler ( & htim3); } // Time updates The callback function void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim) { if(flag == 0) { rt_pin_write(LED0,PIN_LOW); flag = 1; return; } if(flag == 1) { rt_pin_write(LED0,PIN_HIGH); flag = 0; return; } } void LED_Init(void) { rt_pin_mode(LED0,PIN_MODE_OUTPUT); } int main(void) { LED_Init(); TIM3_Init(); return 0; }
htm32f7xx_hal_msp.c
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM3) { __HAL_RCC_TIM3_CLK_ENABLE(); //中断优先级 HAL_NVIC_EnableIRQ(TIM3_IRQn); HAL_NVIC_SetPriority(TIM3_IRQn,1,3); } }