注:
因为本次是使用TIM3,所以所有代码都是配置TIM3;
本次使用到的库函数有:"stm32f10x_rcc.h"和"stm32f10x_rcc.c"时钟库
"stm32f10x_tim.h"和"stm32f10x_tim.c"定时器库
"misc.h"和"miscc"中断库
1)TIM3时钟使能
TIM3 是挂载在 APB1 之下
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
2)复位TIM3
很多时候都没写这一步,不过建议还是写上。
TIM_DeInit(TIM6);//复位
3)初始化定时器参数 数, 设置 自动重装值 , 分频系数 ,计数方式
主要通过使用定时器库函数中,定时器初始化函数
voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//第一个参数是定位到某个定时器上,第二个参数是初始化结构体指针
typedef struct
{
uint16_t TIM_Prescaler;//设置分频系数
uint16_t TIM_CounterMode;//用来设置计数方式
uint16_t TIM_Period;//设置自动重载计数周期值
uint16_t TIM_ClockDivision;//是用来设置时钟分频因子
uint8_t TIM_RepetitionCounter;//重装载定时的次数,高级定时器才有用的
} TIM_TimeBaseInitTypeDef;
T ( 一 次 中 断 的 时 间 ) = ( 设 置 的 初 值 T I M P e r i o d + 1 ) ∗ ( 设 置 的 分 频 系 数 T I M P r e s c a l e r + 1 ) 时 钟 频 率 T(一次中断的时间)=\frac { (设置的初值TIM_Period+1)*(设置的分频系数TIM_Prescaler+1) }{时 钟 频 率} T(一次中断的时间)=时 钟 频 率 (设置的初值TIMPeriod+1)∗(设置的分频系数TIMPrescaler+1)
时钟频率根据TIM_ClockDivision的值来计算,在APB1时钟线上初始为72MHZ
4)设置 TIM3_DIER 允许更新中断
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
//第一个参数是定位到某个定时器上、第三个就是失能还是使能ENABLE或NABLE
/*第二个用来指明我们使能的定时器中断的类型,定时器中断的类型有很多种,
包括更新中断 TIM_IT_Update,触发中断 TIM_IT_Trigger,以及输入捕获中断等。*/
5)居然使用中断,就得初始化线上中断,设置触发条件等。
//系统初始化就为2组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//设置 NVIC 中断分组 2: 2 位抢占优先级, 2 位响应优先级
//中断优先级 NVIC 设置
NVIC_InitTypeDef NVIC_ITDef_TIM6;
NVIC_ITDef_TIM6.NVIC_IRQChannel = TIM6_IRQn; //TIM6 中断
NVIC_ITDef_TIM6.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 0 级
NVIC_ITDef_TIM6.NVIC_IRQChannelSubPriority = 3; //从优先级 3 级
NVIC_ITDef_TIM6.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_ITDef_TIM6); //初始化 NVIC 寄存器
6)许允许TIM3工作能 ,也就是使能TIM3 。
也就相当于开定时器。
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
//第一个参数是定位到某个定时器上、第二个就是失能还是使能ENABLE或NABLE
7 )编写中断服务函数。
//先判断这种中断是否使能,再判断标志位
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t);
//直接判断标志位
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
//主要有这几个中断标志位
#define TIM_IT_Update/*TIM中断源*/
#define TIM_IT_CC1/*TIM捕获/比较1中断源*/
#define TIM_IT_CC2/*TIM捕获/比较2中断源*/
#define TIM_IT_CC3/*TIM捕获/比较3中断源*/
#define TIM_IT_CC4/*TIM捕获/比较4中断源*/
#define TIM_IT_Trigger/*TIM触发中断源*/
//判断定时器溢出中断方法:
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
注:使用的TIM_GetITStatus()函数判断标志位,就用TIM_ClearITPendingBit()函数清标志位。
//定时器 3 中断服务程序
//TIM3_IRQHandler在“USART1_IRQHandler”固件库给好了的名字
void TIM3_IRQHandler(void) //TIM3 中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查 TIM3 更新中断发生与否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除 TIM3 更新中断标志
}
}
/*
主要实现LED间隔1s闪烁,其时间用定时器定时中断完成
*/
#include "stm32f10x.h" // Device header
//初始化LED灯 -> PB5推挽输出、高电平
void LED_Init_PB5(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_ITDef_PB5;
GPIO_ITDef_PB5.GPIO_Pin = GPIO_Pin_5;
GPIO_ITDef_PB5.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_ITDef_PB5.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB,&GPIO_ITDef_PB5);
GPIO_SetBits(GPIOB,GPIO_Pin_5);// 置为高电平
}
void TIM6_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//挂载tim6时钟
TIM_DeInit(TIM6);//复位
TIM_TimeBaseInitTypeDef TIM_TITDef_TIM6;
TIM_TITDef_TIM6.TIM_Prescaler = 7199;//72MHz
TIM_TITDef_TIM6.TIM_Period = 9999;// 1S
TIM_TITDef_TIM6.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TITDef_TIM6.TIM_ClockDivision = TIM_CKD_DIV1;//自动重载计数周期值
TIM_TimeBaseInit(TIM6,&TIM_TITDef_TIM6);
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);//更新中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置 NVIC 中断分组 2:2 位抢占优先级,2 位响应优先级
//中断优先级 NVIC 设置
NVIC_InitTypeDef NVIC_ITDef_TIM6;
NVIC_ITDef_TIM6.NVIC_IRQChannel = TIM6_IRQn; //TIM6 中断
NVIC_ITDef_TIM6.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 0 级
NVIC_ITDef_TIM6.NVIC_IRQChannelSubPriority = 3; //从优先级 3 级
NVIC_ITDef_TIM6.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_ITDef_TIM6); //初始化 NVIC 寄存器
TIM_Cmd(TIM6,ENABLE);//使能 TIM6
}
void TIM6_IRQHandler(void) //TIM6 中断
{
if (TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET) //检查 TIM6 更新中断发生与否
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))//读取PB5当前状态
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5);// 置0
}else {
GPIO_SetBits(GPIOB,GPIO_Pin_5);// 置1
}
TIM_ClearITPendingBit(TIM6,TIM_IT_Update ); //清除 TIM6 更新中断标志
}
}
int main(void)
{
LED_Init_PB5();
TIM6_Init();//1s
while(1)
{
;
}
}
STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)
链接:STM32固件库使用手册的中文翻译版 提取码:4lkx