Hardware Configuration for Blue Bridge Foundation (4) - Configuration of Ordinary (Universal) Timers (1)
~QQ: 3020889729
~Xiao Cai
Simple explanation: the general timer part will be divided into three parts (1)3 blog) - the first part (1 blog) is the general initialization, just the general timer interrupt; the second part (2 blog) is the general output configuration of PWM; and the third part (3 blog) is the configuration of input capture.
The main function of a normal timer (when neither output nor input is needed): is a normal timer unit, where a cycle count is completed and returns to zero to begin counting - but interruption of service is involved.
Normal (Universal) Timer Initialization Configuration
Step 1. Understanding common timer initialization structure parameters:
(Specific comments are in the code)
Timer Initialization Parameter Structures
TIM_TimeBaseInitTypeDef - Can be used to create timer initialization structure - Part necessary to use a timer
Enabling the function of the clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx, ENABLE); //Enable the appropriate clock to use the timer //Similarly, when using other functions, you need to enable the corresponding clock
Below are the initialization parameters for the timer
TIM_TimeBaseInitStructure.TIM_Period=per; //TIM_Period - Timer Count Period - Preloaded Value //Timer Count Cycle - Time spent in a cycle: 1000000/per //That is, count the working frequency/per to get a frequency, and then the reciprocal of the frequency is the period TIM_TimeBaseInitStructure.TIM_Prescaler=71; //TIM_Prescaler--Frequency dividing factor of timer's actual working frequency--Determining working frequency //Count operation frequency is: current clock source frequency/(71+1) TIM_TimeBaseInitStructure.TIM_ClockDivision=0; //TIM_ClockDivision - Clock Division Factor, choose clock division here TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM_CounterMode - refers to the counting mode, where the count is up (more common, generally unchanged)
Ordinary timers have so many initialization parameters - here's the initialization timer
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //Timer Initialization Function - Initialization data comes from our configured initialization parameter structure
Enable Clock to be turned on
TIM_Cmd(TIM3, ENABLE); //In order to use a timer, we must finally enable the timer to be turned on //The last step for most functionality to work properly is to turn it on
Step 2. Configuration of normal timer initialization
(The configuration is as follows: first create an initialization parameter structure, then enable the timer function clock, then configure the initialization parameters for the movie timer, and finally enable the corresponding timer to be opened)
//Default crossover is 71 - get count frequency 1000000hz // per: is the entry parameter - the timing period that needs to be set void Timer_Init(u32 per ) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//Timer Initialization Parameter Structures RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enabling the corresponding function clock TIM_TimeBaseInitStructure.TIM_Period=per;//Timer Count Cycle - Time spent in a cycle: 1000000/per TIM_TimeBaseInitStructure.TIM_Prescaler=71;//1us count once TIM_TimeBaseInitStructure.TIM_ClockDivision=0;//Clock does not split TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//Count Up TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//Initialization timer TIM_Cmd(TIM3, ENABLE);//Enable Clock to be turned on }
Step 3. Initial use of common timer interrupts
(interrupts are used here to implement timed tasks in interrupt service functions)
//I'm going to explain the timer configuration first, then the interrupt service function, then the effect #include "led.h" //Suppose there is a function in this function about the light going on and off, and it flips between lights every time it is used //LED_Toggle(void); #include "timer.h"//where timer functions are declared //Default crossover is 71 - get count frequency 1000000hz // per: is the entry parameter - the timing period that needs to be set void Timer_Init(u32 per ) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//Timer Initialization Parameter Structures NVIC_InitTypeDef NVIC_InitStructure;//Interrupt Initialization Parameter Structures RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enabling the corresponding function clock TIM_TimeBaseInitStructure.TIM_Period=per;//Timer Count Cycle - Time spent in a cycle: 1000000/per TIM_TimeBaseInitStructure.TIM_Prescaler=71;//1us count once TIM_TimeBaseInitStructure.TIM_ClockDivision=0;//Clock does not split TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//Count Up TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//Initialization timer //Interrupt Configuration NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//Interrupt Channel - Interrupt Source - Interrupt of Timer 3 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//Interrupted preemption priority configuration NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//Interrupted subpriority configuration NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//Interrupt Enabling NVIC_Init(&NVIC_InitStructure);//Interrupt Initialization Processing TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//To use interrupts, you also need to interrupt enablement - update interrupts are used here //That is, one update at the end of a cycle, with an interruption TIM_Cmd(TIM3, ENABLE);//Enable Clock to be turned on } void TIM3_IRQHandler(void)//The interrupt service function must be selected correctly { if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=Reset)//Enter when update interrupt occurs { TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//Interrupt generation needs to be cleared in time - otherwise it will get stuck in the interrupt LED_Toggle();//Enter interrupt, light out, flip once } }
The interrupt cycle control light can now be turned on or off by simply exporting it in the main function
(The general format of the code is as follows)
#include "stm32f10x.h" #include "led.h" #include "timer.h" //Main Body int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//Group 2 LED_Init();//LED Initialization Timer_Init(50000);//50,000 cycles, 500 ms while(1); } //That's when the timer flickers 500ms //Timer runs after initialization and does not need to be placed in While to be reused //And you should know that there should be no more functions or statements in the interrupt service function. //This will get stuck too - it's best to turn off such instantaneous functions with some simple judgment statements or the most common lights
Possible problems in timer
(1) Most likely, the calculation of the periodic frequency of the timer:
Timing Cycle (T) =1/(72Mhz/((crossover factor+1)* (preload value+1)) - Get Timing Cycle Timing frequency (F) = (72Mhz/((crossover factor+1)* (preload value+1)) - get timing frequency
(2) When using a timer interrupt, remember to turn the interrupt on at initialization.
(3) Timer interrupt service - remember to clear the interrupt mark in time:
Every interrupt occurs, after entering the service function to determine the interrupt occurs, clear the flag bits in time to avoid getting stuck in the interrupt (code below)
void TIM3_IRQHandler(void)//The interrupt service function must be selected correctly { if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=Reset)//Enter when update interrupt occurs { TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//Interrupt generation needs to be cleared in time - otherwise it will get stuck in the interrupt LED_Toggle();//Enter interrupt, light out, flip once } }
End
This is a simple general timer initialization configuration (1) and I hope it will be helpful for everyone - after the game, if you are still interested, use the other on When you start out, the configuration methods are very similar - generally, you look at the schematic diagram and function parameters before you start the configuration.