域名分析网站市场营销说白了就是干什么的
STM32定时器定时及其应用
- 定时器概述
 - ☆定时器相关配置
 - CubeMX工程配置及程序实现
 - 固件库程序设计及实现
 
定时器概述
-  
1. 工作原理
使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器

 -  
2. 定时器分类
基本定时器(TIM6~TIM7)
通用定时器(TIM2~TIM5)
高级定时器(TIM1和TIM8)定时器类型 主要功能 基本定时器 没有输入输出通道,常用作时基,即定时功能 通用定时器 具有多路独立通道,可用于输入捕获/输出比较,也可用作时基 高级定时器 除具备通用定时器所有功能外,还具备带死区控制的互补信号输出刹车输入等功能  -  
3. STM32F103C8T6资源

 -  
4. 通用定时器介绍
- 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。
 - 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
 - 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
A.输入捕获
B.输出比较
C.PWM 生成(边缘或中间对齐模式)
D.单脉冲模式输出 - 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
 - 如下事件发生时产生中断/DMA:
A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
C.输入捕获
D.输出比较 
 -  
5. 定时器计数模式
计数模式 计数器溢出值 计数器重装值 向上计数 CNT = ARR CNT = 0 向下计数 CNT = 0 CNT = ARR 中心对齐计数 CNT = ARR - 1 CNT = ARR CNT = 1 CNT = 0  

-  
6. 定时器时钟源
- 时钟源:定时器时钟TIMxCLK,即内部时钟CK_INT,经APB预分频后分频提供
 - 计数器时钟:定时器时钟经过PSC预分频器之后,即CK_CNT,用来驱动计数器计数。
 - 计数器CNT:是一个16位/32的计数器
 - 自动重装载寄存器:这里面装着的计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。
 - 计数中断时间:1/(TIMxCLK/(PSC+1))*(ARR+1))

 
 -  
7. 定时器溢出时间公式☆

例如,要定时500ms,则:PSC=7199,ARR=4999,Tclk=72M 
☆定时器相关配置
- 使能时钟配置
 - 定时器参数配置
 - NVIC中断配置
 - 中断服务函数
 
CubeMX工程配置及程序实现
-  
时钟配置
- 采用外部高速晶振

 - 时钟树配置

 
 - 采用外部高速晶振
 -  
定时器配置
-  
开启定时器

 -  
参数设置

 -  
使能中断NVIC

 
 -  
 -  
程序设计
//初始化TIM2用于计时 HAL_TIM_Base_Start_IT(&htim2); //定时器中断服务程序 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if( htim->Instance == TIM2){HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);} } 
固件库程序设计及实现
-  
使能时钟配置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //初始化定时器时钟 -  
定时器结构体配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器结构体定义TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置预分频系数TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure ); //初始化结构体TIM_ITConfig( TIM2, TIM_IT_Update, ENABLE); //使能中断 允许更新中断源TIM_Cmd( TIM2, ENABLE); //使能定时器2 -  
NVIC中断配置
NVIC_InitTypeDef NVIC_InitStructure; //NVIC结构体定义//NVIC初始化NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //中断通道 TIM2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级NVIC_Init(&NVIC_InitStructure); //初始化NVIC结构体 -  
定时器2初始化函数设计
void TIM2_Init(u16 psc, u16 arr) //500ms{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //初始化定时器时钟//定时器初始化 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频TIM_TimeBaseStructure.TIM_Prescaler = psc;TIM_TimeBaseStructure.TIM_Period = arr;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure ); //初始化结构体TIM_ITConfig( TIM2, TIM_IT_Update, ENABLE); //使能中断 允许更新中断源//NVIC初始化NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd( TIM2, ENABLE); //使能定时器2} -  
中断服务函数
//TIM2 中断服务函数 void TIM2_IRQHandler(void) {if( TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET ) //中断标志位判断,确认进入中断{LED1 = !LED1;TIM_ClearFlag(TIM2, TIM_IT_Update); //清除中断标志位} } 
