HAL库定时器TIM基础配置 ing.....

定时器分类介绍(来自野火指南者开放板资料)

在这里插入图片描述

STM32CubeMX 配置文件

  1. 找到对应STM32型号,配置SYS和RCC串口烧录和外部晶振的选择
  2. 找到对应TIMx定时器,选择 internal clock (内部时钟源)一般均选择这个选项。其他都不需要选。
    在这里插入图片描述
    3.时钟配置
    一般均设为最大 72Mhz
    在这里插入图片描述

4.parameter Settings
PSC 预分频器值(PSC):0~65535 (分频值)
Counter Mode :UP (定时器计数模式)
Counter Period(ARR):1~65536 (自动重载值)
auto-reload preload:Enable (自动转入重载值?)

定时时间计算:
HCLK=72Mhz
定时时间(秒)=1/(HCLK)(PSC+1)(ARR+1)
最终计算出来的是
以秒为单位* 注意!!!

在这里插入图片描述 NVIC Setting 配置 (使能) 在这里插入图片描述

例程代码

HAL库TIM中断开启函数

  __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);//清除TIM定时器标志位
  HAL_TIM_Base_Start_IT(&htim3);//开启内部定时器tim3
  

TIM初始化函数

 void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_ON_GPIO_Port, LED_ON_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = LED_ON_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_ON_GPIO_Port, &GPIO_InitStruct);

}

HAL库TIM中断回调函数配置

//TIM定时返回函数
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim)//回调函数
{
	if(htim->Instance == TIM3)//判断进入回调函数方式?
	{
		__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);//清除标志位
		
		HAL_TIM_Base_Stop_IT(&htim3);//停止定时器
		
		printf("1");//测试USART打印函数
		HAL_GPIO_TogglePin(LED_ON_GPIO_Port, LED_ON_Pin);//LED端口反转
		
		HAL_TIM_Base_Start_IT(&htim3);//开启定时器
		 
	}
}

USART 打印函数配置

 int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);	
	return (ch);
}

HAL库———延时函数与计数函数以及实现准确延时功能的函数

__weak void HAL_Delay(uint32_t Delay)//延时函数
__weak uint32_t HAL_GetTick(void)//计时函数

HAL_Delay() 函数用于是程序主循环暂停一定时间,单位毫秒(mm)。
HAL_GetTick() 函数用于获取MCU自复位以来运行的时间,单位同样是毫秒(mm)。

其实HAL_Delay()也是靠HAL_GetTick()函数实现功能的。
代码如下:

__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

这两个函数使用起来非常方便,但是也有一定的不足。

HAL_Delay()不能满足精确延时需要,如微秒级延时。

这很好理解,上边我们说过HAL_Delay()是毫秒级延时。

HAL_Delay()函数在中断中使用,可能会卡死。

HAL_GetTick的替代函数getCurrentMicros

uint32_t getCurrentMicros(void)
{
 /* Ensure COUNTFLAG is reset by reading SysTick control and status register */
 LL_SYSTICK_IsActiveCounterFlag();           //清除计数器"溢出"标志位
 uint32_t m = HAL_GetTick();
 const uint32_t tms = SysTick->LOAD + 1;
 __IO uint32_t u = tms - SysTick->VAL;
 if (LL_SYSTICK_IsActiveCounterFlag()) {
 m = HAL_GetTick();
 u = tms - SysTick->VAL;
  }
 return (m * 1000 + (u * 1000) / tms);
}

__STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void)
{
  //判断COUNTFLAG位是否为1,1则计数器已经递减到0了至少一次。读取该位后该位自动清零。
  return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
}

getCurrentMicros()函数用于获取自MCU复位以来的运行时间,单位微秒,这个函数的实质还是使用了系统滴答定时器,只是在HAL_GetTick()函数的基础上使用了SysTick的当前计数值SysTick->VAL,根据这个数据和SysTick->LOAD重装载值的关系即可计算出不足1毫秒的那一部分时间,从而得到准确的以微秒为单位的时间。

LL_SYSTICK_IsActiveCounterFlag()函数时LL库的一个函数。

HAL_Delay的替代函数delayMicroseconds

//删减版delayMicroseconds函数原型
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
static inline void delayMicroseconds(uint32_t us)
{
  //方法一
  __IO uint32_t currentTicks = SysTick->VAL;
  /* Number of ticks per millisecond */
 const uint32_t tickPerMs = SysTick->LOAD + 1;
  /* Number of ticks to count */
 const uint32_t nbTicks = ((us - ((us > 0) ? 1 : 0)) * tickPerMs) / 1000;
  /* Number of elapsed ticks */
 uint32_t elapsedTicks = 0;
  __IO uint32_t oldTicks = currentTicks;
 do {
    currentTicks = SysTick->VAL;
    elapsedTicks += (oldTicks < currentTicks) ? tickPerMs + oldTicks - currentTicks :
                    oldTicks - currentTicks;
    oldTicks = currentTicks;
  } while (nbTicks > elapsedTicks);
}
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值