理论知识
定时器定时中断
接线图
定时器工作配置步骤
定时中断和内外时钟源选择
定时器中需要使用的函数
程序实现效果:
void TIM_DeInit(TIM_TypeDef* TIMx); **// 恢复定时器的缺省配置**
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct); // 时基单元初始化配置时基单元------>第一个参数表示的是选择某个定时器,第二个结构体包含配置时基单元的一些参数**
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);**// 给结构体变量赋一个默认的值**
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); **// 使能计数器,第一个参数表示选择计数器,第二个参数表示新的状态,也就是使能还是失能**
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); **// 使能中断输出信号,中断输出控制,参数第一个为选择定时器,第二个选择要配置哪一个中断输出,第三个新的状态表示使能还是失能**
以下的6个函数分别对应时基单元的时钟选择部分,可以选择RCC内部时钟,ETR外部时钟,TRX,其它定时器,TIX捕获通道,
void TIM_InternalClockConfig(TIM_TypeDef* TIMx); **// 选择内部时钟**
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); **// 选择其它定时器的时钟,第一个参数表示要配置的定时器,第二个参数为选择要接入那个其它的定时器**
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
uint16_t TIM_ICPolarity, uint16_t ICFilter);**// 选择TIX捕获通道的时钟,选择需要配置的定时器,第二个参数选择TIX具体需要配置的引脚,最后的两个参数表示的是输入的级性和滤波器**
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);**//选择ETR通过外部模式1输入的函数,第一个参数表示外部触发预蜂鸣器,级性和滤**波器
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);// 选择ETR通过外部时钟模式2输入的时钟,第一个参数和上面的一个函数是一样的
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);// 这个函数是用于单独配置ETR引脚的预分频器,极性,滤波器这些参数
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx); // 获取当前计数器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); //获取当前预分频器的值
// 以下的4个函数是用来获取标志位和清除标志位的函数
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
定时器配置
#include "stm32f10x.h" // Device header
/*
定时器中断的初始化代码
*/
void Timer_Init(void)
{
// 开启时钟,这里TIM2是通用寄存器
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
// 选择时基单元的时钟,选择内部时钟的模式,定时器默认使用的是内部单元的时钟
TIM_InternalClockConfig(TIM2);
// 配置时基单元,初始化结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
// 将结构体成员都引用出来放置在这个位置
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 配置参数是否分屏
TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up; // 选择计数的模式选择向上计数
TIM_TimeBaseInitStructure.TIM_Period = 10000 -1; // 表示ARR自动重装器的值,这两个参数的取值都要在0-65535之间
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1; // PSC预分频器的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; // 重复计数器的值
// 初始化结构体并将结构体的地址放置在init函数中
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
// TIM_ClearFlag(TIM2,TIM_FLAG_Update);手动清除更新中断标志位避免刚初始化玩就进中断标志位的问题
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
// 选择中断模式为更新中断,配置使能,开启更新中断到nvic的通路
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置nvic,配置nvic优先级分组,选择分组2的方式
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//初始化nvic的结构体
NVIC_InitTypeDef NVIC_InitStruct;
// 配置nvic结构体模式
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; // 表示中断通道,表示定时器2在nvic中的通道
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // 编写为使能ENABLE
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; // 抢占式优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority =1 ; // 响应式优先级
NVIC_Init(&NVIC_InitStruct);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
}
/*
// 编写定时器2的初始化函数
void TIM2_IRQHandler(void){
// 当定时器产生更新中断时这个函数会被执行TIM_GetITStatus
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){ // 判断中断标志位,如果中断的标志位等于SET就执行用户代码
// 清除中断标志位
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
*/
定时器头文件
主函数文件
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
uint16_t Num;
int main(void)
{
// 初始化oled
OLED_Init();
// 初始化定时器
Timer_Init();
// 使用OLED显示字符串
OLED_ShowString(1,1,"Num:");
while (1)
{
OLED_ShowNum(1, 5, Num, 5);
OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
Num++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
接线图2:
第二个程序效果展示: