STM32L475定时器实验

配置定时器TIM2

配置项解释:
Slave Mode : 正常情况下, TIM2的启动通过代码 HAL_TIM_Base_Start() 来控制, 但是开启Slave Mode之后, TIM2的核心操作将由外部信号触发, 如另一个定时器, GPIO电平等等, 外部触发源通过Trigger Source 来配置

Prescaler(PSC - 16 bits value) 通过设置PSC值, 确定定时器分频后的频率

这个值的目的是为了将输入到TIM2的时钟频率分频, 计算公式为
定时器计数频率 = 定时器输入频率 / (PSC值 + 1)

要确定定时器输入频率, 需要先看系统框图, 如下:

通过这里可以看到, TIM2定时器挂在APB1总线上, 而我们通过时钟树可知, APB1总线时钟为80MHz.

我们需要将TIM2的输入时钟设置为10kHz, 那么 10kHz = 80,000kHz / 8000

所以PSC = 8000 - 1 = 7999, 我们填写7999即可.
Counter Mode : 计数模式, Up Mode, 计数器从0开始, 每来一个计数时钟脉冲, CNT加1, 当计数器到达Auto-reload-value(ARR)是触发更新事件. Down Mode, 计数器从ARR值开始, 每个脉冲减1, 当CNTV减到0时, 触发更新事件
Counter Period (AutoReload Register - 32 bits value) : 计数边界, 这个值减到0时触发一次定时事件.

这个值和PSC共同确定了定时时长, 公式如下:
定时时长 = (PCS + 1) x (ARR + 1) / 输入时钟 = 8000 x 5000 / 80000000 = 0.5s

也就是说, 每0.5秒触发一次定时事件

开启定时器中断
生成代码

tim.h

c 复制代码
#ifndef __TIM_H__
#define __TIM_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"

extern TIM_HandleTypeDef htim2;

void MX_TIM2_Init(void);

#ifdef __cplusplus
}
#endif

#endif /* __TIM_H__ */

tim.c

c 复制代码
#include "tim.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

TIM_HandleTypeDef htim2;

/* TIM2 init function */
void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7999;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 4999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM2)
  {
    /* TIM2 clock enable */
    __HAL_RCC_TIM2_CLK_ENABLE();

    /* TIM2 interrupt Init */
    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);
  }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM2)
  {
    /* Peripheral clock disable */
    __HAL_RCC_TIM2_CLK_DISABLE();

    /* TIM2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(TIM2_IRQn);
  }
}

stm32l4xx_it.h

c 复制代码
void TIM2_IRQHandler(void);

stm32l4xx_it.c

c 复制代码
extern TIM_HandleTypeDef htim2;
/**
  * @brief This function handles TIM2 global interrupt.
  */
void TIM2_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim2);
}

stm32l4xx_hal_conf.h

c 复制代码
#define HAL_TIM_MODULE_ENABLED

main.c

c 复制代码
#include "tim.h"
int main(void)
{
	// ...
  MX_TIM2_Init();
  // ...
}
编写中断处理代码定时器翻转LED灯

main.c

c 复制代码
  // 测试定时器反转电平
  HAL_TIM_Base_Start_IT(&htim2);
  TRACE_INFO("Tagged the LED pin in interrupt");
  while(1){
    //...
  }

tim.h

clike 复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

tim.c

c 复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  if (htim->Instance == TIM2) {
    HAL_GPIO_TogglePin(GPIOE, LED_R_Pin); // 翻转红色LED电平
  }
}
运行效果

使用定时器反转LED效果演示

相关推荐
天空'之城5 小时前
单片机基础核心知识点汇总(三)
单片机·嵌入式硬件
嵌入式阿蔡5 小时前
CAN总线入门:从协议帧到STM32实战
c语言·stm32·单片机·嵌入式硬件·嵌入式实时数据库
恒锐丰科技韩生6 小时前
率能 SS8847E|2.7~15V 双通道 H 桥电机驱动 ETSSOP16 散热封装 家电 / 打印 / 舞台灯光专用
嵌入式硬件·硬件工程
离凌寒6 小时前
一、对stm32mp157配置freertos后,任务挂掉无法启动问题总结
stm32·单片机·嵌入式硬件
消失的旧时光-19438 小时前
7-fix补充篇:机器人为什么需要多级控制仲裁?Cloud、Linux 与 MCU 分别管什么
linux·单片机·机器人·仲裁机制·安全保护机制
Hello_Damon_Nikola9 小时前
CH573从入门到精通
c语言·开发语言·单片机·嵌入式硬件
oshan20129 小时前
华大小华HC32F460单片机在线烧录
单片机·嵌入式硬件
LCG元10 小时前
STM32 USB HID 自定义免驱设备开发:从报告描述符到上位机 64 字节收发实战
stm32·单片机·嵌入式硬件
Hello_Damon_Nikola10 小时前
HT2813从入门到精通
单片机·嵌入式硬件·物联网
天空'之城10 小时前
单片机基础核心知识点汇总(二)
单片机·嵌入式硬件