stm32f407关于通用定时器各种函数——中断功能(一)

一、通用定时器

道 STM32F407 有 10 个通用 定时器(TIM2~TIM5 和 TIM9~TIM14)。这些定时器彼此完全独立,不共享任何资源。

1.1、与基本定时器的比较

通用定时器的架构图如下,从架构图就可以发现其结构比基本定时器复杂很多。

通用定时器的计数模式有三种:递增计数模式、递减计数模式和中心对齐模式

STM32F4 定时器 TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14 挂载在 APB1 总线

APB2 总线上挂载的通用定时器 TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8

 ④部分是输入捕获,一般应用是要和第⑤部分一起完成测量功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通 过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的 IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常见的测量 有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。

第⑥部分是输出比较,一般应用是要和第⑤部分一起完成定时器输出功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通 过复用功能与这些通道相连。

二、通用定时器的中断实战

通用定时器的中断和基本定时器的中断基本没有任何区别,就是在配置的时候可以选择递增、递减或者中心对齐模式。还有就是要注意不同定时器在APB1还是APB2总线上

现在配置通用定时器3,用中断实现每500ms实现GPIOF_PIN_10上的LED状态反转。

#include "stm32f4xx.h"
#include "core_cm4.h"
#include "stm32f4xx_hal.h"
#include "stdio.h"
 #include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"


 
TIM_HandleTypeDef g_timx_handle; 
 
 
 
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓通用定时器初始化↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
void gtim_tim3_int_init(uint16_t arr, uint16_t psc)
{
    __HAL_RCC_TIM3_CLK_ENABLE();                             /* 使能TIM3时钟 */

    g_timx_handle.Instance = TIM3;                          /* 通用定时器3 */
    g_timx_handle.Init.Prescaler = psc;                     /* 预分频系数 */
    g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 递增计数模式 */
    g_timx_handle.Init.Period = arr;                        /* 自动装载值 */
    HAL_TIM_Base_Init(&g_timx_handle);
    
    HAL_NVIC_SetPriority(TIM3_IRQn, 1, 3);      /* 设置中断优先级,抢占优先级1,子优先级3 */
    HAL_NVIC_EnableIRQ(TIM3_IRQn);                 /* 开启ITMx中断 */

    HAL_TIM_Base_Start_IT(&g_timx_handle);         /* 使能定时器x和定时器x更新中断 */
}
 
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ LED的配置↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
void led_init(void)                                         /* 对LED串口进行初始化*/
{
    GPIO_InitTypeDef gpio_init_struct;                      /* 定义结构体 */
   
    gpio_init_struct.Pin = GPIO_PIN_10;                     /* LED引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
 
    HAL_GPIO_Init(GPIOF, &gpio_init_struct);                /* 初始化LED引脚 */
}
 
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 中断函数↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
void TIM3_IRQHandler(void)
{
    /* 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式 */
    if(__HAL_TIM_GET_FLAG(&g_timx_handle, TIM_FLAG_UPDATE) != RESET)
    {
        HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); 
        __HAL_TIM_CLEAR_IT(&g_timx_handle, TIM_IT_UPDATE);  /* 清除定时器溢出中断标志位 */
    }
}

 
 
int main(void)
{    
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);     /* 设置时钟,168Mhz */
    delay_init(168);                        /* 延时初始化 */
    led_init();                             /* 初始化LED */
    gtim_tim3_int_init(4999, 8399); /* 84 000 000 / 84 00 = 10 000 10Khz的计数频率,计数5K
次为500ms */
    __HAL_RCC_GPIOF_CLK_ENABLE();                                /* F端口使能*/
    HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);        /* 开启LED */
 
    while(1)
    {
 
        delay_ms(200);
    }
}

注:delay_ms(200);直接用的正点原子的代码,这里只是用来表示一下。

这里对定时器进行配置的时候没有使用HAL自带的通用函数,直接在 gtim_timx_int_init(uint16_t arr, uint16_t psc)中完成了定时器参数的配置和中断使能等操作。此外在定时器中断的函数里面也没有调用HAL提供的统一函数,所以需要手动将中断的标志位进行重置,利用函数__HAL_TIM_CLEAR_IT(&g_timx_handle, TIM_IT_UPDATE);

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值