basic timer
Basic framework
Clock source
Because the basic timer can only select: internal clock.
In STM32F103, the basic timers TIM6 and TIM7 are mounted on APB1, so the clock is originally the clock frequency value of APB1: 36MHZ, but please see the clock tree in the data manual of STM32F103.
What can we see from this??? Even if we circle the part, if the clock prescaler coefficient is 1, then the frequency is based on the bus frequency × 2, i.e. 36 × 2==72Mhz.
Why know the size of this value?
When configuring the library function, we need to know which bus it is mounted on, so that we can turn on its clock. When configuring the counting frequency division factor and technical cycle, we need to know this value, so that we can calculate the final time value.
//Turn on timer clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); TIM_TimeBaseInitStructure.TIM_Period = (8000-1);//8000 TIM_TimeBaseInitStructure.TIM_Prescaler = (9000-1);//9000
Why subtract 1 here? Because: counting starts from 0, and there are actually 8000 values from 0 to 7999, so setting (8000-1) here is the same as frequency division. As for why this value is set here, it is based on actual needs. This is discussed below.
Counting part
According to the script timer function block diagram, you can see:
The first is CK_PSC, this value is actually the clock from the internal clock, that is, CK as we mentioned above_ PSC = clock of apb1 × 2==36 × 2=72Mhz.
Secondly, after a PSC prescaler, even if it is set in the firmware library, for example, below, we set it to (9000-1), and the maximum value is 0xFFFF.
TIM_TimeBaseInitStructure.TIM_Prescaler = (9000-1);//9000
Can we get CK according to this frequency division value_ CNT (counter clock frequency), yes, CK here_ CNT=CK_ PSC/PSC=72Mhz/9000=8Khz.
The meaning here is to count every 1 / 8kHz, because our basic timer can only count up, that is, the time required to count from 0 to 1 is 1 / 8kHz. Similarly, the time required for 1 to 2, 2 to 3... Is also 1 / 8kHz.
We know that the time of each count is 1/8khz. How many times?
TIM_TimeBaseInitStructure.TIM_Period = (8000-1);//8000
We can set the count 8000 times here. This value can be set according to the actual needs. The maximum value is the same as the above frequency division coefficient. For a 16 bit counter, the maximum value is 0xFFFF, that is 65535!
Each count is 1/8khz and 8000 times. Is the total time: 1/8khz × 8000==1s.
Yes, yes, it's 1s counting once, and then we let him generate an interrupt. Automatic reload register, advanced timer only, basic timer does not, so we stay in the advanced timer to explain.
To sum up, we set an interrupt every 1s.
The code is as follows:
BasicTime.c Documents
#include "./bsp_basictime/bsp_basictime.h" //Configure interrupt priority static void BasicTime_NVIC_Init(void) { NVIC_InitTypeDef NVIC_InitStructure = {0}; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//Configure the interrupt priority group. Since there is only one interrupt, you can configure it here NVIC_InitStructure.NVIC_IRQChannel = Basic_TIMx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void BasicTime_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0}; //Turn on timer clock Basic_TIMx_APBClockCmd(Basic_TIMx_APB_Periph,ENABLE); //Configure the timer accordingly TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//The basic timer can only count up TIM_TimeBaseInitStructure.TIM_Period = Basic_TIMx_Period;//8000 TIM_TimeBaseInitStructure.TIM_Prescaler = Basic_TIMx_Prescaler;//9000 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//Only advanced timers have this function. TIM_TimeBaseInit(Basic_TIMx,&TIM_TimeBaseInitStructure); //First clear the update interrupt flag bit of TIM to avoid affecting our update interrupt TIM_ClearFlag(Basic_TIMx,TIM_FLAG_Update); //Call interrupt priority function BasicTime_NVIC_Init(); //Start timer update interrupt TIM_ITConfig(Basic_TIMx,TIM_IT_Update,ENABLE); //Start timer TIM_Cmd(Basic_TIMx,ENABLE); }
BasicTime.h file
#ifndef __BSP_BASICTIME_H #define __BSP_BASICTIME_H #include "stm32f10x.h" //If you use the basic timer TIM7, you only need to use the following basic timer_ Change tim6 to Basic_TIM7 is enough #define Basic_TIM6 #ifdef Basic_TIM6 / / use basic timer 6 #define Basic_TIMx TIM6 #define Basic_TIMx_APBClockCmd RCC_APB1PeriphClockCmd #define Basic_TIMx_APB_Periph RCC_APB1Periph_TIM6 #define Basic_TIMx_IRQn TIM6_IRQn #define Basic_TIMx_IRQHandler TIM6_IRQHandler #define Basic_TIMx_Period (8000-1) #define Basic_TIMx_Prescaler (9000-1) #else // Use basic timer 7 #define Basic_TIMx TIM7 #define Basic_TIMx_APBClockCmd RCC_APB1PeriphClockCmd #define Basic_TIMx_APB_Periph RCC_APB1Periph_TIM7 #define Basic_TIMx_IRQn TIM7_IRQn #define Basic_TIMx_IRQHandler TIM7_IRQHandler #define Basic_TIMx_Period (8000-1) #define Basic_TIMx_Prescaler (9000-1) #endif extern void BasicTime_Init(void); #endif /* __LED_H */
Interrupt function file content
void Basic_TIMx_IRQHandler(void) { if(TIM_GetITStatus(Basic_TIMx,TIM_IT_Update) == SET)//If an update interrupt occurs, enter this function once { //1 s, reverse LED1 lamp once LED3_TOGGLE; TIM_ClearITPendingBit(Basic_TIMx,TIM_IT_Update);//Clear the interrupt flag bit to re-enter the interrupt next time } }
summary
The main function of the basic timer is timing. We can use it to accurately locate the time, and then do some operations, such as lighting a light, sending content through the serial port, variable increment and so on.
Readme: come on, boy, don't forget your original heart!
Learn something, in order to strengthen the country!