目录

一、定时器资源

二、LPTIM

(1)LPTIM 介绍

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

三、踩坑日记


一、定时器资源

        🔵超低功耗的 STM32L071xx 器件包括三个通用定时器,一个低功耗定时器,一个基本定时器,两个看门狗定时器和 SysTick 定时器。

图1        定时器资源
  • 计数器分辨率:决定计数的范围,16位计数器计数范围为(0-65535)
  • 计数器类型:向上计数、向下计数、向上/向下计数
  • 预分频系数:1-65536,对输入定时器的时钟进行分频
  • 捕捉/比较通道:捕获外部触发信号、PWM 输出、单脉冲输出等 
表1 定时器特征比较
定时器 计数器分频率 计数器类型 预分频系数 DMA请求产生 捕获/比较通道数 互补输出

TIM2

TIM3

16位

向上、向下、向上/向下

1-65536 允许 4 不能

TIM21

TIM22

16位 向上、向下、向上/向下 1-65536 不允许 2 不能

TIM6

TIM7

16位 向上 1-65536 允许 0 不能

1. 4个可同步的通用定时器(TIM2TIM3TIM21TIM22

  • 其中 TIM3 的通道3(即引脚 PB0),可用于拓展的脉冲模块作输入捕获通道;

2. LPTIM 低功耗定时器(下文介绍);

3. SysTick Timer: 这个定时器专门用于操作系统,但也可以用作标准的计数器。它是基于一个24位的自动重新加载能力和一个可编程的时钟源。当计数器到达0时,它具有可掩蔽的系统中断生成功能。


二、LPTIM

(1)LPTIM 介绍

        低功耗计时器有一个独立的时钟,如果它被 LSELSL 或外部时钟锁定,它也处于停止模式。它能够从停止模式唤醒设备。 

        这个低功耗计时器支持以下功能:

  • 具有 16 位自动重载寄存器的 16 位上计数器
  • 16位比较寄存器
  • 可配置的输出: (脉冲、PWM)
  • 连续/一次模式
  • 软件触发/硬件触发
  • 可选择时钟来源:

        - 内部时钟来源(LSELSIHSIAPB

        - 外部时钟源通过 LPTIM 输入(即使没有内部时钟源运行,脉冲计数器应用程序也使用)

  • 可编程数字故障滤波器
  • 编码器模式


(2)STM32CubeMX 软件配置

🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置”【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出  一文中有讲解,这里不再赘述❗️

1️⃣点击引脚 PC15 → 选择 GPIO_Output 模式(此处默认为推挽输出);

图2        LD5引脚配置

2️⃣点击 "GPIO" → 点击引脚 PC15 → 将 "GPIO output level" 栏修改为 "High",即将 PC15 引脚初始化为高电平;

⚠️此处修改不是必须的,应当根据题意要求进行配置,这里默认为上电熄灭;

图3        LD5 初始化配置

3️⃣点击 "Timers" → 选择 "LPTIM1" → 在模式一栏中选择 "Counts internal clock events"

  • 此处使能低功耗定时器 LPTIM1,并将模式配置为"计数内部时钟",LPTIM1 的时钟源为内部时钟;
图4        LPTIM1 使能

4️⃣点击 "Clock Configuration" 栏 → 配置 LPTIMCLK (低功耗定时器时钟源)为 "PCLK1" (外设时钟1);

图5        LPTIM 时钟源配置

5️⃣返回 "Pinout & Configuration" 栏,对 LPTIM 参数进行配置;

  • 时钟分频配置为32分频,即 LPTIM 时基时钟为1MHz
  • 预装载更新模式配置为 "Update End Of Period",即在周期结束时更新;
图6        LPTIM 参数配置

6️⃣在 "NVIC Settings" 栏,使能 LPTIM 中断;

图7        LPTIM 中断使能

7️⃣生成代码即可;

(3)代码编写

🟢️main函数

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define PERIOD	1000
/* USER CODE END PD */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LPTIM1_Init();
  /* USER CODE BEGIN 2 */
  /* 启动定时器并设置周期,此处设置为1000,即1ms中断一次 */
  HAL_LPTIM_Counter_Start_IT(&hlptim1, PERIOD);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

        在 while(1) 死循环之前,调用函数

HAL_LPTIM_Counter_Start_IT(&hlptim1, PERIOD);

以中断的方式启动 LPTIM 开始计数,此处周期设置为1000;

由于 LPTIM 时基时钟为 1MHz,则1000个周期为1ms,即1ms中断一次;

🟠️中断回调函数

/* USER CODE BEGIN 0 */
/* LPTIM 自动重载匹配回调函数 - 1ms进入一次 */
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
	/* 静态变量定义,用于1s计数 */
	static uint16_t cnt_1s = 0;
	/* 计数满1000次即1s */
	if(++cnt_1s == 1000)
	{
		/* 变量清零,用于下一次计数 */
		cnt_1s = 0;
		/* LD5状态翻转,便于观察现象 */
		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
	}
}
/* USER CODE END 0 */

        ⚠️查阅头文件 "stm32l0xx_hal_lptim.h" → 在第618行,查找中断回调函数声明;

        声明函数 void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim);

        该函数每 1ms 进入一次,在函数内部声明静态变量用于 1s 计数,当时间达到 1s 时,将变量清零,并翻转 LD5 状态,便于现象观察;

(4)实验现象

  • LD5 状态每间隔 1s 取反;

三、踩坑日记

        🔅使用中断回调函数,一定要在进入死循环之前调用定时器中断方式启动函数,否则中断无法工作;

图8        LPTIM 启动函数调用
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐