一、stm32f103c8t6定时器
stm32f103c8t6含三个通用定时器(TIM2\TIM3\TIM4)一个高级定时器(TIM1)。
定时器.PNG
二、定时器配置
2.1、项目中的SystemClock、PCLK1、PClK2配置
// SystemClock、PCLK1、PClK2配置
void STM32F103C8T6_PERIPHERAL_CLOCK_Init(st_u32 RCC_HCLK)
{
RCC_PCLK1Config(RCC_HCLK); // APB1 4分频 PCLK1 = HCLK/4 = 18MHz 定时器TIM2~7挂载的时钟,此时钟倍频后得到TIMx_ClK
RCC_PCLK2Config(RCC_HCLK); // APB2 4分频 PCLK(APB) AHB(HCLK)
}
2.2、定时器配置
void TIMx_Config(TIM_TypeDef* TIMx)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructrue; // 定时器结构体
if(TIMx==TIM2)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2外设时钟
else if(TIMx==TIM3)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
else if(TIMx==TIM4)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
uint16_t PrescalerValue = 0; // specifies the Prescaler Register value
PrescalerValue = (uint16_t) (72000000 / 12000000) -1; // TIM_TimeBaseStructrue.TIM_Prescaler = 5;
TIM_TimeBaseStructrue.TIM_Period = 6000; // 定时器周期 自动装载的值,每计数6000次,产生一个更新事件
TIM_TimeBaseStructrue.TIM_Prescaler = 0; // 定时器预分频器
TIM_TimeBaseStructrue.TIM_ClockDivision = 0; // 时钟分频 0表示滤波器与定时器频率一样
TIM_TimeBaseStructrue.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructrue); // 将配置应用到TIM2
TIM_PrescalerConfig(TIMx, PrescalerValue, TIM_PSCReloadMode_Immediate); // 及时装入PrescalerValue的值
TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE); // 配置TIM2中断类型,并使能
TIM_Cmd(TIMx, ENABLE); // 使能TIM2通用定时器
}
【注意】
1、定时器计数频率 = 内部时钟源频率(APB1倍频器送出的时钟)/(TIM_Prescaler+1) = 36KHz/6 = 6MHz
2、 计数周期T = ((per)(psc+1))/定时器时钟频率 = 60006 /36KHz = 1000微妙 = 1ms
3、 计数6000次用时1ms 产生1次中断TIM_IT_Update
4、预分频寄存器TIMx_PSC用于对计数器时钟频率进行分频,它是一个16位的寄存器
取值范围ox00 ~ 0xFFFF 转换为十进制 0 ~ 65535,分频系数时除数分母不能为0所以会自动加1,最后实现1~65536分频
2.3、定时器初始化与中断配置
// TIM2 1ms 中断定时器配置
void TIM2_Init(void)
{
STM32F103C8T6_PERIPHERAL_CLOCK_Init(RCC_HCLK_Div4); // AHB=systemclock = 72M PCLK=72/4=18M 定时器时钟=36M
// HSE_SetSysClock(RCC_PLLMul_9);
NVIC_Config(TIM2_IRQn,0x00,0x01); // 中断优先级设置
TIMx_Config(TIM2);
}
void NVIC_Config(st_u8 IRQn,st_u8 IRQChannelPriority,st_u8 IRQChannelSubPriority)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =IRQChannelPriority; // 抢占式优先级 0~15
NVIC_InitStructure.NVIC_IRQChannelSubPriority =IRQChannelSubPriority ; // 子优先级 0~15
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
2.4、中断服务函数
unsigned char T_10ms
unsigned char T_100ms
unsigned char T_1s
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 1ms 延时
T_10ms++;
if(T_10ms >= 10)
{ // 10ms延时
T_10ms = 0;
T_100ms++;
}
if(T_100ms >= 10)
{
// 100ms延时
T_100ms = 0;
TimerCount();
T_1s++;
}
if(T_1s >= 10)
{// 1s延时
T_1s = 0;
}
}
}
100ms级延时
extern short int L_Timer;
void TimerCount(void)
{
L_Timer++;
if(L_Timer>1000)L_Timer=0;
}