【STM32】HAL库学习笔记:定时器详解(超详细!)

stm32hal库–定时器

任务一:串口发送计数器的值

一.Cube MX配置

1.打开串口2及其中断,用于发送数据打开串口2及其中断
2.将高速外部时钟源设置为晶振,提高定时精度
将高速外部时钟源设置为晶振

3.将HCLK改为72MHz
将HCLK改为72MHz
4.开启定时器
TIM4–勾选 Internal Clock(内部时钟)/
TIM2–将Clock Source选择为Internal Clock
5.设置预分频器
Prescaler–n(想要实现的分频)-1
Counter Period(自动重装载寄存器)m-1
[即每数到m次计数器清零)
定时器设置

二.代码部分

  • 定时器启动函数 HAL_TIM_Base_Start
    (接收tim4句柄的指针)
    1.启动定时器
    Base定时器基本用法 调用此函数后TIM4开始计时工作
    2.打印计数器的计数值
    定义counter存储计数器的值
    定义char数组message用以拼接字符串

  • 宏定义-获取计数器值函数__HAL_TIM_GET_COUNTER(参数为htim4的指针)
    tips:hal库中宏定义函数比较偏底层,倾向于直接对寄存器进行操作
    3.循环中
    (1) 使用counter变量接受获取到的计数器值
    (2) 使用sprintf进行字符串拼接
    (用于储存字符串的message变量,
    (3) 想用串口发出的字符串"counter:%d",counter);

  • 串口中断发送函数 HAL_UART_Transmit_IT
    (用来发送的串口的指针,要发送数据的指针,发送数据的长度)
    (4) 防止发送过快 HAL_Delay
    tips:HAL_Delay函数精确延时 每次延时都比填入数字多1ms
    (5)sprintf–头文件stdio
    strlen–头文件string
    代码部分

  • /* USER CODE BEGIN Includes */
    #include <stdio.h>
    #include <string.h>
    /* USER CODE END Includes */
    ...
     /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start(&htim4);
    int counter=0;
    char message[20];
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    	  counter=__HAL_TIM_GET_COUNTER(&htim4);
    	  sprintf(message,"counter: %d",counter);
    	  HAL_UART_Transmit_IT(&huart2,(uint8_t*)message,strlen(message));
    	  HAL_Delay(99);
        /* USER CODE END WHILE */
    
    

    三.实现效果

    tips:开始时按KRST键(reset复位按钮)
    从0开始计数 每100毫秒数1000个数
    到10000个数(即9999)时计数器清零

    函数补充

  • __HAL_TIM_GET_COUNTER 获取计数器的值
  • HAL_TIM_SET_COUNTER 用于设置计数器的值
  • HAL_TIM_GET_AUTORELOAD 获取重装载寄存器的值
  • HAL_TIM_SET_AUTIRELOAD 设置重装载寄存器的值
  • HAL_TIM_SET_PRESCALER 设置预分频器的值
  • 任务二:定时

    一.Cube MX配置

    NVIC设置-打开TIM4全局中断

    二.代码部分

    1.启动定时器(+_IT 使其清零时触发更新中断)
    启动定时器中断

  • HAL_TIM_Base_Start_IT
    2.重写中断回调函数
    1.找到中断回调函数找到中断回调函数
  • HAL_TIM_PeriodElapsedCallback 中断回调函数
    重写中断回调函数
  • /* USER CODE BEGIN 0 */
    char data[]="😊😍😘😉";
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    	if(htim==&htim4){
    		HAL_UART_Transmit_IT(&huart2,(uint8_t*)data,strlen(data));
    	}
    }
    /* USER CODE END 0 */
    

    tips:Transmi_IT是非阻塞发送,若中断中的Transmi_IT和while循环中的Transmit_IT发送间隔太小,会导致上次的数据没发完就被下次发送的数据覆盖
    所以这里要注释掉while循环中的发送

    三.实现效果

    实现效果
    每隔1ms发送数据

    补充

  • 预分频器和重装载寄存器都存在影子寄存器,重装载寄存器的影子寄存器可手动调整是否开启
  • 开启影子寄存器
    开启重装载寄存器的影子寄存器,使新设置的清零值等到下个周期生效,防止更改数值后错过
    Core:定时器就是计数器
    原理部分后续补充…

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【STM32】HAL库学习笔记:定时器详解(超详细!)

    发表评论