人若无名 便可潜心练剑.|

hazy1k

园龄:7个月粉丝:14关注:0

2024-09-13 19:20阅读: 20评论: 0推荐: 0

第31章 高级定时器-定时

第三十一章 高级定时器-定时

1. 硬件设计

无需硬件设计

2. 软件设计

2.1 编程大纲

  1. TIM相关参数宏定义

  2. TIM NVIC及Mode配置

  3. TIM中断服务函数

  4. 主函数测试

2.2 代码分析

2.2.1 高级定时器相关参数宏定义

#define ATMx TIM1
#define ATIM_Period 999
#define ATIM_Prescaler 71
#define ATIM_IRQ TIM1_UP_IRQn
#define ATIM_IRQHandler TIM1_UP_IRQHandler

2.2.2 NVIC及Mode配置

#include "AdvanceTim.h"

static void ATIM_NVIC_Init(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = ATIM_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

static void ATIM_Mode_Init(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  TIM_TimeBaseStructure.TIM_Period = ATIM_Period; // 999
  TIM_TimeBaseStructure.TIM_Prescaler = ATIM_Prescaler; // 71
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(ATMx, &TIM_TimeBaseStructure);
  TIM_ClearFlag(ATMx, TIM_FLAG_Update); // 清除更新标志位
  TIM_ITConfig(ATMx, TIM_IT_Update, ENABLE); // 使能更新中断
  TIM_Cmd(ATMx, ENABLE); // 使能定时器
}

void ATIM_Config(void)
{
  ATIM_NVIC_Init();
  ATIM_Mode_Init();
}

2.2.3 中断服务函数

volatile uint32_t time = 0; // ms 计时变量 
void ATIM_IRQHandler(void)
{
    if(TIM_GetITStatus(ATMx, TIM_IT_Update) != RESET) 
    {    
        time++;
        TIM_ClearITPendingBit(ATMx , TIM_FLAG_Update);           
    }             
}

2.2.4 主函数

#include "stm32f10x.h"
#include "led.h"
#include "AdvanceTim.h" 
#include "usart.h"

extern volatile uint32_t time;

int main(void)
{ 
    LED_Init();
    ATIM_Config();
    USART_Config();
  while(1)
  {
    if(time == 1000) // 1000 * 1 ms = 1s 时间到 
    {
      time = 0;
            LED1_TOGGLE(); 
            printf("这是由TIM1产生的1s定时器中断\r\n");
    }        
  }
}

3. 小结

这个与其他定时器无异,只是基本使用,无法体现高级定时器的功能,那我们再来回顾一下定时器基本配置的流程吧:

3.1 定义定时器结构体

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  • 这行代码定义了一个TIM_TimeBaseInitTypeDef类型的结构体TIM_TimeBaseStructure。这个结构体用于配置定时器的基本参数,如计数周期、预分频器等。

3.2 开启定时器时钟

ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK, ENABLE);
  • 通过调用ADVANCE_TIM_APBxClock_FUN函数启用与定时器相关的时钟。ADVANCE_TIM_CLK是要使能的时钟源(例如RCC_APB2Periph_TIM1),ENABLE表示开启时钟。
  • 这一步骤是必须的,因为定时器在未使能其时钟之前无法正常工作。

3.3 配置自动重装载寄存器

TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_Period;
  • TIM_Period设置了定时器的自动重装载寄存器的值。定时器会在计数到这个值后重新从零开始计数,从而触发一个更新事件或中断。

3.4 配置时钟预分频数

TIM_TimeBaseStructure.TIM_Prescaler = ADVANCE_TIM_Prescaler;
  • TIM_Prescaler设置了时钟的预分频值。定时器时钟频率通过将输入时钟除以TIM_Prescaler来降低。这决定了定时器的计数频率。

3.5 时钟分频因子

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  • TIM_ClockDivision指定了时钟的分频因子。在这里,它被设置为TIM_CKD_DIV1,表示没有额外的分频。这一项在很多情况下可以忽略,特别是当使用定时器的基本模式时。

3.6 计数器计数模式

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

3.7 重复计数器的值

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  • TIM_RepetitionCounter用于高级定时器的重载计数模式,但在此代码中设置为0,表示不使用该功能。

3.8 初始化定时器

TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);

3.9 清除计数器中断标志位

TIM_ClearFlag(ADVANCE_TIM, TIM_FLAG_Update);
  • TIM_ClearFlag函数用于清除定时器的更新中断标志位。通常在中断处理程序中或在启用中断之前需要清除标志位,以防止错误的中断触发。

3.10 开启计数器中断

TIM_ITConfig(ADVANCE_TIM, TIM_IT_Update, ENABLE);
  • TIM_ITConfig函数用于配置定时器的中断。这里设置TIM_IT_Update中断为使能状态,以便定时器达到更新事件时产生中断。

3.11 使能计数器

TIM_Cmd(ADVANCE_TIM, ENABLE);
  • 最后,调用TIM_Cmd函数启用定时器。此时定时器开始工作,并根据设置的周期和预分频值产生定时器中断或事件。

2024.9.13 第一次修订,后期不再维护

2025.1.27 优化代码

本文作者:hazy1k

本文链接:https://www.cnblogs.com/hazy1k/p/18412743

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hazy1k  阅读(20)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起