一.定时器分类![](https://i-blog.csdnimg.cn/blog_migrate/de36112cf73a1633da64aed80ef81fcb.png)
定时器资源:F103有2个高级,4个通用,2个基本
二.基本定时器
1.功能简介
基本定时器可以触发DAC的同步电路,也可以在更新事件(计数器溢出)时产生中断和DMA请求
基本定时器只能使用内部时钟
2.框图分析
计数器的溢出频率 = CK_CNT/(ARR+1)
= CK_PSC/(PSC+1)/(ARR+1)
基本定时器只能使用内部时钟
- 时基:预分频器PSC(16位),计数器CNT(16位),自动重装载寄存器(16位),计数时钟CK_CNT = CK_PSC/(PSC+1),PSC是16位的,所以可取值0~65535,则分频系数就是1~65536,
注意:当使能了计数器后,CK_CNT才有效
- 影子寄存器: 起到缓冲寄存器, 有一个缓冲的功能, 用户值->寄存器->影子寄存器->起作用, 不使用的话用户的值写到之后起作用, 使用的话这一周期计数完成之后起作用,影子寄存器是实际上起作用的寄存器, 并且是不可直接访问的,一般是一个事件以后才会进行写入。
- U->Update更新事件, 除了溢出更新还可以通过UG位进行软件更新, 会把预装载的值加载到影子寄存器
- UI-更新中断,产生后会进入NVIC,配置好NVIC的定时器通道就可以产生中断了
- 计数模式分为 递增,递减,中心对齐模式 ,基本定时器只有递增计数模式
3.基本定时器完成延时
1`定时时间的计算
2`结构体
3`实际应用
#include "bsp_tim.h"
static void TIM_NVIC()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM6_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void BASIC_Time_Config()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);//开启定时器的时钟
//CK_INT = 72M
TIM_TimeBaseInitTypeDef TIM_Time_Struct;
//CK_CNT = CK_INT/(PSC+1)/(ARR+1)
TIM_Time_Struct.TIM_Prescaler = 7200-1;//时钟预分频数
TIM_Time_Struct.TIM_Period = 10000-1;//ARR的值
//我这里是进行了1s计数器溢出一次
/*
TIM_Time_Struct.TIM_CounterMode
TIM_Time_Struct.TIM_ClockDivision
TIM_Time_Struct.TIM_RepetitionCounter
基本定时器只能向上计数,没有时钟分频因子,没有重复计数器
*/
TIM_TimeBaseInit(TIM6,&TIM_Time_Struct);//初始化
TIM_ClearFlag(TIM6,TIM_FLAG_Update);//先清除更新中断标志位,即计数器溢出中断标志位
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);//使能事件更新中断
//使能NVIC
TIM_NVIC();
TIM_Cmd(TIM6,ENABLE);//使能定时器
}
//中断服务函数
void TIM6_IRQHandler()
{
//先获取中断标志位
if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET)
{
Num++;
//清楚中断标志位
TIM_ClearITPendingBit(TIM6,TIM_FLAG_Update);
}
}
extern uint16_t Num;//定时器都是16位的
int main()
{
BASIC_Time_Config();
LED_GPIO_Config();
while(1)
{
if(Num == 5)
{
LED_R_TOGGLE;//翻转红灯的IO电平
Num = 0;
}
}
}
关于TOGGLE的使用:
以绿灯PB0为例
#define LED_G_TOGGLE GPIOB->ODR ^= GPIO_Pin_0
ODR复位值为0,所以0^1=1,LED灭;然后再1^1 = 0,LED亮,再0^1 = 1一直延续下去....