table of Contents
General timer interrupt experiment
Timer interrupt clock source analysis
Teach you how to look at the logic signal diagram
Up-counting mode (clock division factor = 1)
Center-aligned counting mode (clock division factor=1, ARR=6)
Introduction to related registers
Event generation register (TIMx_EGR)
Auto reload register (TIMx_ARR)
Use library functions to configure general-purpose timers with interrupts
Introduction to library functions
Step 2: Initialize Timer 3 (configure the value of ARR and PSC)
Step 3: Initialize the NVIC embedded interrupt vector
Step 4: Configure the interrupt of TIMX
Step 5: Enable TIMX peripheral
Step 6: Write the corresponding interrupt service function
General timer interrupt experiment
Timer interrupt clock source analysis
Our experiment uses the clock from the APB1 bus (AHB clock frequency is 72MHz). We noticed that in AHB->APB1 divider->APB1, if the division factor of the APB1 prescaler is 1, then the clock frequency of TIMXCLK is " TIMCLK=APB1=AHB", if the division factor of the APB1 prescaler is N (N is not 1), then the clock frequency of TIMXCLK is "TIMCLK=2xAPB1=2xAHB/N".
But when we call the initialization clock source library function provided by ST, the default division factor of the APB1 divider is 2, so the final TIMXCLK=2xAPB1=2xAHB/2=AHB.
TIMXCLK clock frequency = CLK_INT clock frequency, and then passed to CK_PSC through the trigger controller for the second frequency division processing, the final clock pulse received by the CNT counter is "CLK_INT/(CK_PSC+1)", (why the frequency division factor is CK_PSC +1 we will talk about it later)
Teach you how to look at the logic signal diagram
Up-counting mode (clock division factor = 1)
First, CK_INT is the initial clock source of TIMER, CNT_EN represents TIMER enable, CK_CNT is the pulse frequency received by the counter (after the frequency is divided in the CK_PSC register), the reload value of the counter register is 36, "interrupt event update" It is synchronized with "timer overflow" and "update interrupt flag set to 1," but we see that if we do not manually clear the interrupt flag, the system will always be in the execution interrupt regardless of whether the interrupt condition is met.
Center-aligned counting mode (clock division factor=1, ARR=6)
The center-aligned counting mode is somewhat different in that the interrupt is triggered when the up-count overflow and the down-count overflow respectively, and if we do not clear the interrupt flag after each interrupt, the interrupt behavior will always exist regardless of whether the interrupt condition is met.
Introduction to related registers
Event generation register (TIMx_EGR)
The update event interrupt is an ordinary interrupt executed by the general-purpose timer.
Status register (TIMx_SR)
Counter (TIMx_CNT)
Prescaler (TIMx_PSC)
Auto reload register (TIMx_ARR)
This register is used to reload the overflow value of the counter after the count value of the counter overflows.
Control register 1 (TIMx_CR1)
This register is used to request interrupts and configure the counter mode. Once the interrupt is triggered, all registers will be updated.
Use library functions to configure general-purpose timers with interrupts
Introduction to library functions
Library function name |
Features |
Used to initialize the TIMX timer |
|
TIM_Cmd |
Enable or disable TIMx peripheral |
TIM _ITConfig |
After configuring the corresponding parameters of the NVIC, enable or disable the specified TIM interrupt |
TIM_PrescalerConfig |
Set TIMx prescaler |
TIM_CounterModeConfig |
Set TIMx counter mode |
TIM_GetITStatus |
Check whether the specified TIM interrupt occurs or not |
TIM_ClearITPendingBit |
Clear the interrupt pending bit of TIMx |
TIM_GetFlagStatus |
Check whether the specified TIM flag is set or not |
TIM_ClearFlag |
Clear the pending flag of TIMx |
The difference between TIM_ClearITPendingBit and TIM_ClearFlag function
TIM_ClearITPendingBit clears some interrupt flag bits, and TIM_ClearFlag clears timer status flags, such as timer capture status bit timer trigger flag bit.
Selection of timer parameters
The general timer parameters mainly have two PSC prescaler coefficients and ARR counter reload value. The overflow time refers to "the time from 0x00 to TOP".
Design requirements
Through the timer interrupt configuration, interrupt once every 500ms, and then control the LED in the interrupt service function to realize the inversion (flashing) of the LED1 state.
TIMX programming flow
Step 1: Initialize TIMER3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能APB1的外设时钟
Step 2: Initialize Timer 3 (configure the value of ARR and PSC)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStructure.TIM_Period = 0x1C20; // 5000
TIM_TimeBaseInitStructure.TIM_Prescaler = 0x1388; // 7200
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); // 初始化TIMER3
Step 3: Initialize the NVIC embedded interrupt vector
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC嵌入式外部中断
Why do we configure the NVIC interrupt vector grouping before the NVIC initialization?
The NVIC interrupt vector grouping is used to constrain all interrupt vectors. If we put it in a header file alone, we can’t express this meaning, and if we declare different interrupt vector groups in different header files, it will be messy. of.
Step 4: Configure the interrupt of TIMX
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 配置TIMER3的具体中断行为
Why the TIM interrupt channel of NVIC has been opened, and why do we also configure the TIMX interrupt?
What we enable at the beginning is the TIMX interrupt channel. The TIMX interrupt mode is very complicated and there are multiple interrupt modes. Therefore, we first enable the total interrupt channel of TIMX, and then further configure the attributes of the TIMX interrupt, such as different interrupt conditions: Up counting overflow, down counting overflow....
Step 5: Enable TIMX peripheral
TIM_Cmd(TIM3, ENABLE); // 使能TIMER3外设
Step 6: Write the corresponding interrupt service function
void TIM3_IRQHandler() // 应该在相应的中断文件内编写中断服务函数
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) // 由于定时器有多个中断模式,因此我们一定要检查相应的中断标志位
{
LED0 = !LED0;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 由于定时器有多个中断模式,因此我们一定要清除相应的中断标志位
}
Code example
Main.c
#include "led.h"
#include "timer.h"
#include "stm32f10x.h"
#include "delay.h"
int main()
{
delay_init(); // 只有初始化系统systick时钟,我们才能调用delay系列函数
LED_InitConfig(); // LED初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // NVIC中断向量分组应该先于NVIC初始化
TIMER_InitConfig(0x1C20, 0x1388); // 初始化TIMER3,其中PR=7200,ARR=5000
while(1)
{
LED1 = !LED1;
delay_ms(250);
}
}
Led.c
#include "led.h"
#include "stm32f10x.h"
void LED_InitConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); // 使能LED0,LED1的时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置LED0的GPIO输出属性
GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 初始化PB5为低电平
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure); // 配置LED1的GPIO输出属性
GPIO_ResetBits(GPIOE, GPIO_Pin_5); // 初始化PE5为低电平
}
Led.h.
#ifndef _LED_H
#define _LED_H
#include "sys.h"
void LED_InitConfig();
#define LED0 PBout(5)
#define LED1 PEout(5)
#endif
Timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIMER_InitConfig(u16 ARR, u16 PR);
#endif
Timer.c
operation result