STM32使用定时器(标准库)

默认APB1时钟频率(PCLK1)=AHB时钟频率(HCLK)/2

默认APB2时钟频率(PCLK1)=AHB时钟频率(HCLK)

话不多说,先上代码

所有定时器都需要使能,使能后开始计时

TIM_Cmd(TIMx, ENABLE);

计算公式为:普通定时器定时时长=

(1/(APB1时钟频率×2)/(TIM_Prescaler+1)×(TIM_Period+1)

为什么APB1时钟频率×2,因为当默认APB1时钟频率(PCLK1)=AHB时钟频率(HCLK)/2时,根据时钟树,普通定时器的时钟频率=APB1时钟频率×2

所以当RCC_HCLK_Div1RCC_HCLK_Div2对于普通定时器的时钟频率来说都是AHB时钟频率(HCLK),而选择RCC_HCLK_Div4

普通定时器的时钟频率=(AHB时钟频率(HCLK)/4)×2

/**
  * @brief  Configures the Low Speed APB clock (PCLK1).
  * @param  RCC_HCLK: defines the APB1 clock divider. This clock is derived from 
  *   the AHB clock (HCLK).
  *   This parameter can be one of the following values:
  *     @arg RCC_HCLK_Div1: APB1 clock = HCLK
  *     @arg RCC_HCLK_Div2: APB1 clock = HCLK/2
  *     @arg RCC_HCLK_Div4: APB1 clock = HCLK/4
  *     @arg RCC_HCLK_Div8: APB1 clock = HCLK/8
  *     @arg RCC_HCLK_Div16: APB1 clock = HCLK/16
  * @retval None
  */
void RCC_PCLK1Config(uint32_t RCC_HCLK)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_RCC_PCLK(RCC_HCLK));
  tmpreg = RCC->CFGR;
  /* Clear PPRE1[2:0] bits */
  tmpreg &= CFGR_PPRE1_Reset_Mask;
  /* Set PPRE1[2:0] bits according to RCC_HCLK value */
  tmpreg |= RCC_HCLK;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}

/**
  * @brief  Configures the High Speed APB clock (PCLK2).
  * @param  RCC_HCLK: defines the APB2 clock divider. This clock is derived from 
  *   the AHB clock (HCLK).
  *   This parameter can be one of the following values:
  *     @arg RCC_HCLK_Div1: APB2 clock = HCLK
  *     @arg RCC_HCLK_Div2: APB2 clock = HCLK/2
  *     @arg RCC_HCLK_Div4: APB2 clock = HCLK/4
  *     @arg RCC_HCLK_Div8: APB2 clock = HCLK/8
  *     @arg RCC_HCLK_Div16: APB2 clock = HCLK/16
  * @retval None
  */
void RCC_PCLK2Config(uint32_t RCC_HCLK)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_RCC_PCLK(RCC_HCLK));
  tmpreg = RCC->CFGR;
  /* Clear PPRE2[2:0] bits */
  tmpreg &= CFGR_PPRE2_Reset_Mask;
  /* Set PPRE2[2:0] bits according to RCC_HCLK value */
  tmpreg |= RCC_HCLK << 3;
  /* Store the new value */
  RCC->CFGR = tmpreg;
}

此代码用TIM2做定时器,计时1s

void TIM2_run(void)
{
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
		NVIC_InitTypeDef TIM_NVICinitStucture;
	
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 时钟使能

        NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);
	
		TIM_NVICinitStucture.NVIC_IRQChannel = TIM2_IRQn;//中断通道,选择串口中断
		TIM_NVICinitStucture.NVIC_IRQChannelPreemptionPriority = 0;//配置中断优先级
		TIM_NVICinitStucture.NVIC_IRQChannelCmd	= ENABLE;//使能打开
		TIM_NVICinitStucture.NVIC_IRQChannelSubPriority	= 2;//配置中断子优先级

		NVIC_Init(&TIM_NVICinitStucture);//串口结构体初始化

	
		TIM_TimeBaseStructure.TIM_Period = 10000-1;
//设置自动重装载计数值,可以设置的值为0x0000-0xFFFF,即0到65535
//但由于从0开始计数,所以设置值=实际所需重载值-1
		TIM_TimeBaseStructure.TIM_Prescaler =7199;
//设置预分频,可以设置的值为0x0000-0xFFFF,即0到65535
//但由于没有0分频的说法,所以设置值=实际所需分频值-1
		TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟不分频
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
		TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//根据指定参数初始化TIMx
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
		TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
		
}

上述定时器是通用定时器的定时方法

使用高级定时器TIM1或TIM8做定时器时,可以根据需要定义TIM_RepetitionCounter的值

高级定时器定时时长=

(1/APB2时钟频率/(TIM_Prescaler+1)×(TIM_Period+1)

代码如下(此代码实现了计时3s)

void TIM1_run(void)
{
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
		NVIC_InitTypeDef TIM_NVICinitStucture;
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 时钟使能

        
		NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);
	
		TIM_NVICinitStucture.NVIC_IRQChannel = TIM1_UP_IRQn; //中断通道,选择串口中断
		TIM_NVICinitStucture.NVIC_IRQChannelPreemptionPriority = 0;//配置中断优先级
		TIM_NVICinitStucture.NVIC_IRQChannelCmd	= ENABLE;//使能打开
		TIM_NVICinitStucture.NVIC_IRQChannelSubPriority	= 2;//配置中断子优先级

		NVIC_Init(&TIM_NVICinitStucture);//串口结构体初始化

	
		TIM_TimeBaseStructure.TIM_Period = 10000-1;
//设置自动重装载计数值,可以设置的值为0x0000-0xFFFF,即0到65535
//但由于从0开始计数,所以设置值=实际所需重载值-1
		TIM_TimeBaseStructure.TIM_Prescaler =7199;
//设置预分频,可以设置的值为0x0000-0xFFFF,即0到65535
//但由于没有0分频的说法,所以设置值=实际所需分频值-1
		TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟不分频
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
		TIM_TimeBaseStructure.TIM_RepetitionCounter=2;   
//该参数设定溢出多少次才触发中断,可以设置的值为0x00-0xFF
//但由于从0开始计数,所以设置值=实际所需溢出次数-1           
		TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);//根据指定参数初始化TIMx
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
		TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE );


}

中断函数

void TIM2_IRQHandler()
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
	{
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

void TIM1_UP_IRQHandler()
{
	
	if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  //判断TIM3更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM1, TIM_IT_Update  );  //清除TIMx更新中断标志 
		}

}	

高级定时器有四个中断入口

TIM1_BRK_IRQn               = 24,     
/*!< TIM1 Break Interrupt                                 */
  TIM1_UP_IRQn                = 25,     
/*!< TIM1 Update Interrupt ,该中断入口可用于定时器        */
  TIM1_TRG_COM_IRQn           = 26,     
/*!< TIM1 Trigger and Commutation Interrupt               */
  TIM1_CC_IRQn                = 27,     
/*!< TIM1 Capture Compare Interrupt                       */

四个中断入口各自对应着中断函数

具体可以查看startup_stm32f10x_hd.s 文件

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32的1S #include "stm32f10x_it.h" /** @addtogroup STM32F10x_StdPeriph_Template * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ extern u32 SystickCounter; extern u8 KeySwitch_Press; extern u8 KeyAdjust_Press; #define TRUE 1 #define FALSE 0 /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************/ /* Cortex-M3 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. * @param None * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. * @param None * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. * @param None * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @ret

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值