目录
定时器的配置步骤
初始化代码
中断函数
主函数
寄存器代码
库函数代码
以STM32F103RCT6 定时器2为例,配置一个简单的定时器程序
RCC->APB1ENR |= (1<<0); //TIM2,通用定时器
预分频PSC是16位寄存器,它的最大值是2^16,也就是65535
//要注意,PSC是16位寄存器,固它的最大值应该是65535
TIM2->PSC = PSC; //配置预分频器
ARR和PSC一样,也是最大数值位65535
TIM2->ARR = ARR; //自动重装载寄存器
DIER寄存器第0位为允许更新中断,也就是在计数器溢出的时候会产生中断,在计数器达到重装载数时,产生中断。配置优先级直接使用了野火的函数,抢占优先级0,响应优先级0,组0,最高优先级。
//允许中断
TIM2->DIER |= (1<<0);
//配置优先级
MY_NVIC_Init(0,0,TIM2_IRQn,0);
//使能计数器,开始计数
TIM2->CR1 |= (1<<0);
void TIM2_init(void)
{
RCC->APB1ENR |= (1<<0); //TIM2,通用定时器
TIM2->ARR = 5000; //自动重装载寄存器,计数5000次
TIM2->PSC = 7200; //预分频器设置
TIM2->DIER |= 1<<0; //允许更新中断
MY_NVIC_Init(0,0,TIM2_IRQn,0);
TIM2->CR1 |= 0x01; //使能定时器2
}
TIM2的中断函数是
void TIM2_IRQHandler(void);
例如,想要在TIM2产生中断时翻转IO口电平
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0x01)//溢出中断
{
PAout(0) = !PAout(0);
}
TIM2->SR&=~(1<<0);//清除中断标志位
}
在主函数里不要忘记配置时钟,初始化IO口
int main(void)
{
Stm32_Clock_Init(9); //9倍频,外部8Mhz,主频72Mhz
TIM2_init(); //TIM2初始化
MY_LED_Init(); //IO口初始化
while(1)
{
}
}
#include "stm32f10x.h"
#include "sys.h"
#include "MY_LED.H"
void TIM2_init(void)
{
RCC->APB1ENR |= (1<<0); //TIM2,通用定时器
TIM2->ARR = 10000; //自动重装载寄存器,计数5000次
TIM2->PSC = 7200; //预分频器设置
TIM2->DIER |= 1<<0; //允许更新中断
TIM2->CR1 |= 0x01; //使能定时器2
MY_NVIC_Init(0,0,TIM2_IRQn,0);
}
int main(void)
{
Stm32_Clock_Init(9);
TIM2_init();
MY_LED_Init();
LED_on;
while(1)
{
}
}
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0x01)//溢出中断
{
PAout(0) = !PAout(0);
}
TIM2->SR&=~(1<<0);//清除中断标志位
}
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "sys.h"
#include "bsp_usart.h"
void TIM2_IRQHandler(void)
{
printf("中断一次\n");
TIM_ClearFlag(TIM2 , TIM_FLAG_Update);
if(TIM_GetFlagStatus(TIM2 , TIM_FLAG_Update) == SET)
{
}
}
void TIM2_TimBaseInit(void) //基本计数器模式
{
TIM_TimeBaseInitTypeDef TIM_TimBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
TIM_InternalClockConfig(TIM2); //使用 TIM2 内部时钟
//定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例。
TIM_TimBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimBaseInitStructure.TIM_Period = 5000-1;
TIM_TimBaseInitStructure.TIM_Prescaler = 7199;
TIM_TimBaseInitStructure.TIM_RepetitionCounter = 0; //TIM1 和 TIM8用的
TIM_TimeBaseInit(TIM2 , &TIM_TimBaseInitStructure);
TIM_ITConfig(TIM2 , TIM_IT_Update , ENABLE); //使能更新中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2 , ENABLE);
}
int main(void)
{
//SystemInit();
Stm32_Clock_Init(9);
USART1_Init();
TIM2_TimBaseInit();
while(1)
{
printf("%d" , TIM_GetCounter(TIM2));
Delay_ms(500);
}
}