STM32F103学习笔记(5.2)——定时器配置

目录

定时器的配置步骤

初始化代码

中断函数

主函数

寄存器代码

库函数代码


工程文件下载:简单定时器

以STM32F103RCT6 定时器2为例,配置一个简单的定时器程序

定时器的配置步骤

1.使能外设时钟

RCC->APB1ENR |= (1<<0);	//TIM2,通用定时器

2.设置预分频

预分频PSC是16位寄存器,它的最大值是2^16,也就是65535

//要注意,PSC是16位寄存器,固它的最大值应该是65535
TIM2->PSC = PSC;    //配置预分频器

3.配置自动重装载寄存器

ARR和PSC一样,也是最大数值位65535

TIM2->ARR = ARR;    //自动重装载寄存器

4.配置中断

DIER寄存器第0位为允许更新中断,也就是在计数器溢出的时候会产生中断,在计数器达到重装载数时,产生中断。配置优先级直接使用了野火的函数,抢占优先级0,响应优先级0,组0,最高优先级。

//允许中断
TIM2->DIER |= (1<<0);
	
//配置优先级
MY_NVIC_Init(0,0,TIM2_IRQn,0);

5.使能计数器开始计数

//使能计数器,开始计数
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);
	}
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天师电通电容爆破工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值