【STM32】_03_分享个定时器板级驱动包,一个驱动包适用于所有定时器

前言

笔者使用的是STM32F103系列,使用的是标准库编程,此驱动包,可以实现设置定时器中断,设置PWM输出、PWM互补输出,参考的是安富莱教程。
先贴一个F103系列的时钟树图。对理解后面的程序有帮助。(PS:在CubeMX,可以很容易查到ST系列芯片的最新数据手册)
在这里插入图片描述

废话不多说,直接放源码

#ifndef __TIM_PWM_H
#define __TIM_PWM_H

#include "stm32f10x.h"

static uint32_t get_rcc_gpio(GPIO_TypeDef *GPIOx);
static uint32_t get_rcc_tim(TIM_TypeDef *TIMx);
static void config_tim_gpio(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX, TIM_TypeDef *TIMx);
static void config_gpio_out(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX);                            


/* 设置定时器引脚输出PWM */
void set_tim_out_pwm(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, uint8_t _ucChannel,
                      uint32_t _ulFreq, uint32_t _ulDutyCycle);

/* 设置定时器 互补 引脚输出PWM */
void set_tim_out_pwm_n(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, uint8_t _ucChannel,
                        uint32_t _ulFreq, uint32_t _ulDutyCycle);

/* 配置定时器进行简单的定时中断 */
void set_tim_int(TIM_TypeDef *TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority);



#endif /* __TIM_PWM_H */


/**
******************************************************************************
* @file     tim_pwm.c
* @author   BJX
* @version  V1.0
* @date     2024-04-xx
* @brief    TIM基本定时中断和PWM驱动模块
******************************************************************************
* @attention
*
*   APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14      ---- 72M
*   APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11                               ---- 72M
*
******************************************************************************
*/

#include "./tim/tim_pwm.h"


/**
 * @brief  根据GPIO 得到RCC寄存器
 * @param  GPIOx: 选择GPIO外设
 * @retval GPIO外设时钟名
 */
static uint32_t get_rcc_gpio(GPIO_TypeDef *GPIOx)
{
    uint32_t rcc = 0;

    if (GPIOx == GPIOA)
    {
        rcc = RCC_APB2Periph_GPIOA;
    }
    else if (GPIOx == GPIOB)
    {
        rcc = RCC_APB2Periph_GPIOB;
    }
    else if (GPIOx == GPIOC)
    {
        rcc = RCC_APB2Periph_GPIOC;
    }
    else if (GPIOx == GPIOD)
    {
        rcc = RCC_APB2Periph_GPIOD;
    }
    else if (GPIOx == GPIOE)
    {
        rcc = RCC_APB2Periph_GPIOE;
    }
    else if (GPIOx == GPIOF)
    {
        rcc = RCC_APB2Periph_GPIOF;
    }
    else if (GPIOx == GPIOG)
    {
        rcc = RCC_APB2Periph_GPIOG;
    }

    return rcc;
}

/**
 * @brief  根据TIM 得到RCC寄存器
 * @param  TIMx: 选则TIMX外设
 * @retval TIM外设时钟名
 */
static uint32_t get_rcc_tim(TIM_TypeDef *TIMx)
{
    uint32_t rcc = 0;

    /*
        APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14
        APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
    */
    if (TIMx == TIM1)
    {
        rcc = RCC_APB2Periph_TIM1;
    }
    else if (TIMx == TIM8)
    {
        rcc = RCC_APB2Periph_TIM8;
    }
    else if (TIMx == TIM9)
    {
        rcc = RCC_APB2Periph_TIM9;
    }
    else if (TIMx == TIM10)
    {
        rcc = RCC_APB2Periph_TIM10;
    }
    else if (TIMx == TIM11)
    {
        rcc = RCC_APB2Periph_TIM11;
    }
    /* 下面是 APB1时钟 */
    else if (TIMx == TIM2)
    {
        rcc = RCC_APB1Periph_TIM2;
    }
    else if (TIMx == TIM3)
    {
        rcc = RCC_APB1Periph_TIM3;
    }
    else if (TIMx == TIM4)
    {
        rcc = RCC_APB1Periph_TIM4;
    }
    else if (TIMx == TIM5)
    {
        rcc = RCC_APB1Periph_TIM5;
    }
    else if (TIMx == TIM6)
    {
        rcc = RCC_APB1Periph_TIM6;
    }
    else if (TIMx == TIM7)
    {
        rcc = RCC_APB1Periph_TIM7;
    }
    else if (TIMx == TIM12)
    {
        rcc = RCC_APB1Periph_TIM12;
    }
    else if (TIMx == TIM13)
    {
        rcc = RCC_APB1Periph_TIM13;
    }
    else if (TIMx == TIM14)
    {
        rcc = RCC_APB1Periph_TIM14;
    }

    return rcc;
}

/**
 * @brief  配置GPIO和TIM时钟, GPIO连接到TIM输出通道
 * @param  GPIOx: 选则GPIOx外设
 * @param  GPIO_PinX 选则GPIOx外设的引脚
 * @param  TIMx: 选则TIMX外设
 * @retval 无
 */
static void config_tim_gpio(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX, TIM_TypeDef *TIMx)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能GPIO时钟 */
    RCC_APB2PeriphClockCmd(get_rcc_gpio(GPIOx), ENABLE);

    /* 使能TIM时钟 */
    if ((TIMx == TIM1) || (TIMx == TIM8))
    {
        RCC_APB2PeriphClockCmd(get_rcc_tim(TIMx), ENABLE);
    }
    else
    {
        RCC_APB1PeriphClockCmd(get_rcc_tim(TIMx), ENABLE);
    }

    /* 配置GPIO */
    GPIO_InitStructure.GPIO_Pin = GPIO_PinX;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 复用功能 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
}

/**
 * @brief  配置GPIO为推挽输出。主要用于PWM输出,占空比为0和100的情况。
 * @param  GPIOx: 选则GPIOx外设
 * @param  GPIO_PinX 选则GPIOx外设的引脚
 * @retval 无
 */
static void config_gpio_out(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能GPIO时钟 */
    RCC_APB2PeriphClockCmd(get_rcc_gpio(GPIOx), ENABLE);

    /* 配置GPIO */
    GPIO_InitStructure.GPIO_Pin = GPIO_PinX;         /* 带入的形参 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
}

/**
 * @brief  设置引脚输出的PWM信号的频率和占空比.  当频率为0,并且占空为0时,关闭定时器,GPIO输出0。
 *                                            当频率为0,占空比为100%时,GPIO输出1。
 * @param  GPIOx        选则GPIOx外设
 * @param  GPIO_PinX    选则GPIOx外设的引脚
 * @param  TIMx         选则TIMX外设
 * @param  _ucChannel   选则TIMX外设PWM输出通道
 * @param  _ulFreq      PWM频率    0 表示禁止输出
 * @param  _ulDutyCycle PWM占空比  单位:万分之一。如5000,表示50.00%的占空比
 * @retval 无
 */
void set_tim_out_pwm(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, uint8_t _ucChannel,
                      uint32_t _ulFreq, uint32_t _ulDutyCycle)
{
    uint16_t usPeriod;
    uint16_t usPrescaler;
    uint32_t uiTIMxCLK;
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    
    if ((_ulFreq == 0) && (_ulDutyCycle == 0))
    {
        TIM_Cmd(TIMx, DISABLE);                    /* 关闭PWM输出,可能对其它通道有影响 */

        config_gpio_out(GPIOx, GPIO_Pin);          /* 配置GPIO为推挽输出 */
        GPIO_WriteBit(GPIOx, GPIO_Pin, Bit_RESET); /* PWM = 0 */
        return;
    }
    else if ((_ulFreq == 0) && (_ulDutyCycle == 10000))
    {
        TIM_Cmd(TIMx, DISABLE);                  /* 关闭PWM输出 */

        config_gpio_out(GPIOx, GPIO_Pin);        /* 配置GPIO为推挽输出 */
        GPIO_WriteBit(GPIOx, GPIO_Pin, Bit_SET); /* PWM = 1 */
        return;
    }

    config_tim_gpio(GPIOx, GPIO_Pin, TIMx);     /* 使能GPIO和TIM时钟*/

    if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM9) || (TIMx == TIM10) || (TIMx == TIM11))
    {
        /* APB2 定时器 */
        uiTIMxCLK = SystemCoreClock;    /* 当系统时钟为 72M 时,APB1、APB2 总线上挂载的时钟都为 72M */
    }
    else /* APB1 定时器 */
    {
        uiTIMxCLK = SystemCoreClock; // SystemCoreClock / 2;
    }

    if (_ulFreq < 100)
    {
        usPrescaler = 10000 - 1;                      /* 分频比 = 10000 */
        usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
    }
    else if (_ulFreq < 3000)
    {
        usPrescaler = 100 - 1;                      /* 分频比 = 100 */
        usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
    }
    else /* 大于4K的频率,无需分频 */
    {
        usPrescaler = 0;                    /* 分频比 = 1 */
        usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
    }

    /* 时基配置*/
    TIM_TimeBaseStructure.TIM_Period = usPeriod;                /* 自动重装载寄存器值(周期) */
    TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;          /* 预分频器 */
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                /* 时钟分频, */
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* 定时器计数方式 */
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            /* 重复计数器 */
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);

    /* PWM1 模式配置:Channel1*/
    TIM_OCStructInit(&TIM_OCInitStructure);                     /* 初始化结构体成员为默认值 */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                  /* 比较输出模式 */
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      /* 比较输出使能 */
    TIM_OCInitStructure.TIM_Pulse = (_ulDutyCycle * usPeriod) / 10000; /* 脉冲宽度)(占空比) */
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;          /* 比较输出极性 */

    /* 仅适用于 TIM1 和 TIM8。*/
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /* 比较互补输出使能. */
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;      /* 比较互补输出极性 */
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;     /* 空闲状态时通道输出电平设置 */
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;   /* 空闲状态时互补通道输出电平设置 */

    if (_ucChannel == 1)
    {
        TIM_OC1Init(TIMx, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 2)
    {
        TIM_OC2Init(TIMx, &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 3)
    {
        TIM_OC3Init(TIMx, &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 4)
    {
        TIM_OC4Init(TIMx, &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }

    TIM_ARRPreloadConfig(TIMx, ENABLE);

    /* TIMx 使能计数器*/
    TIM_Cmd(TIMx, ENABLE);

    /* 下面这句话对于TIM1和TIM8是必须的,对于TIM2-TIM6则不必要 */
    if ((TIMx == TIM1) || (TIMx == TIM8))
    {
        TIM_CtrlPWMOutputs(TIMx, ENABLE);
    }
}

/**
 * @brief  设置TIM8_CH1N 等反相引脚输出的PWM信号的频率和占空比. 当频率为0,并且占空为0时,关闭定时器,GPIO输出0。
 *                                            当频率为0,占空比为100%时,GPIO输出1。
 * @param  GPIOx        选则GPIOx外设
 * @param  GPIO_PinX    选则GPIOx外设的引脚
 * @param  TIMx         选则TIMX外设
 * @param  _ucChannel   选则TIMX外设PWM输出通道
 * @param  _ulFreq      PWM频率 单位Hz   0 表示禁止输出
 * @param  _ulDutyCycle PWM占空比 单位:万分之一。如5000,表示50.00%的占空比
 * @retval 无
 */
void set_tim_out_pwm_n(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, uint8_t _ucChannel,
                        uint32_t _ulFreq, uint32_t _ulDutyCycle)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    uint16_t usPeriod;
    uint16_t usPrescaler;
    uint32_t uiTIMxCLK;

   if ((_ulFreq == 0) && (_ulDutyCycle == 0))
    {
        TIM_Cmd(TIMx, DISABLE);                    /* 关闭PWM输出 */

        config_gpio_out(GPIOx, GPIO_Pin);          /* 配置GPIO为推挽输出 */
        GPIO_WriteBit(GPIOx, GPIO_Pin, Bit_RESET); /* PWM = 0 */
        return;
    }
    else if ((_ulFreq == 0) && (_ulDutyCycle == 10000))
    {
        TIM_Cmd(TIMx, DISABLE);                  /* 关闭PWM输出 */

        config_gpio_out(GPIOx, GPIO_Pin);        /* 配置GPIO为推挽输出 */
        GPIO_WriteBit(GPIOx, GPIO_Pin, Bit_SET); /* PWM = 1 */
        return;
    }

    config_tim_gpio(GPIOx, GPIO_Pin, TIMx);     /* 使能GPIO和TIM时钟,并连接TIM通道到GPIO */

    if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM9) || (TIMx == TIM10) || (TIMx == TIM11))
    {
        /* APB2 定时器 */
        uiTIMxCLK = SystemCoreClock;    /* 当系统时钟为 72M 时,APB1、APB2 总线上挂载的时钟都为 72M */
    }
    else /* APB1 定时器 */
    {
        uiTIMxCLK = SystemCoreClock; // SystemCoreClock / 2;
    }

    if (_ulFreq < 100)
    {
        usPrescaler = 10000 - 1;                      /* 分频比 = 10000 */
        usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
    }
    else if (_ulFreq < 3000)
    {
        usPrescaler = 100 - 1;                      /* 分频比 = 100 */
        usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
    }
    else /* 大于4K的频率,无需分频 */
    {
        usPrescaler = 0;                    /* 分频比 = 1 */
        usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
    }

    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = usPeriod;
    TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);

    /* PWM1 模式配置:Channel1*/
    TIM_OCStructInit(&TIM_OCInitStructure); /* 初始化结构体成员 */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;  /* 和 set_tim_out_pwm() 不同 */
    TIM_OCInitStructure.TIM_Pulse = (_ulDutyCycle * usPeriod) / 10000;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; /* 仅适用于 TIM1 和 TIM8。*/
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;     /* only for TIM1 and TIM8. */
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;    /* only for TIM1 and TIM8. */
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;  /* only for TIM1 and TIM8. */

    if (_ucChannel == 1)
    {
        TIM_OC1Init(TIMx, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 2)
    {
        TIM_OC2Init(TIMx, &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 3)
    {
        TIM_OC3Init(TIMx, &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }
    else if (_ucChannel == 4)
    {
        TIM_OC4Init(TIMx, &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable);
    }

    TIM_ARRPreloadConfig(TIMx, ENABLE);

    /* TIMx 使能计数器*/
    TIM_Cmd(TIMx, ENABLE);

    /* 下面这句话对于TIM1和TIM8是必须的,对于TIM2-TIM6则不必要 */
    if ((TIMx == TIM1) || (TIMx == TIM8))
    {
        TIM_CtrlPWMOutputs(TIMx, ENABLE);
    }
}

/**
 * @brief  配置TIM和NVIC,用于简单的定时中断. 开启定时中断。 中断服务程序由应用程序实现。
 * @param  TIMx                 选则TIMX外设
 * @param  _ulFreq              定时频率 (Hz)。 0 表示关闭。
 * @param  _PreemptionPriority  抢占优先级
 * @param  _SubPriority         子优先级
 * @retval 无
 */
void set_tim_int(TIM_TypeDef *TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    uint16_t usPeriod;
    uint16_t usPrescaler;
    uint32_t uiTIMxCLK;

    /* 使能TIM时钟 */
    if ((TIMx == TIM1) || (TIMx == TIM8))
    {
        RCC_APB2PeriphClockCmd(get_rcc_tim(TIMx), ENABLE);
    }
    else
    {
        RCC_APB1PeriphClockCmd(get_rcc_tim(TIMx), ENABLE);
    }

    if (_ulFreq == 0)
    {
        TIM_Cmd(TIMx, DISABLE); /* 关闭定时输出 */

        /* 关闭TIM定时更新中断 (Update) */
        {
            NVIC_InitTypeDef NVIC_InitStructure; /* 中断结构体在 misc.h 中定义 */
            uint8_t irq = 0;                     /* 中断号, 定义在 stm32f10x.h */

            if (TIMx == TIM1)
                irq = TIM1_UP_IRQn;
            else if (TIMx == TIM2)
                irq = TIM2_IRQn;
            else if (TIMx == TIM3)
                irq = TIM3_IRQn;
            else if (TIMx == TIM4)
                irq = TIM4_IRQn;
                
#ifdef STM32F10X_HD     

            else if (TIMx == TIM5)
                irq = TIM5_IRQn;
            else if (TIMx == TIM6)
                irq = TIM6_IRQn;
            else if (TIMx == TIM7)
                irq = TIM7_IRQn;
            else if (TIMx == TIM8)
                irq = TIM8_UP_IRQn;
#endif                

            NVIC_InitStructure.NVIC_IRQChannel = irq;
            NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = _PreemptionPriority;
            NVIC_InitStructure.NVIC_IRQChannelSubPriority = _SubPriority;
            NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
            NVIC_Init(&NVIC_InitStructure);
        }
        return;
    }

    if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM9) || (TIMx == TIM10) || (TIMx == TIM11))
    {
        /* APB2 定时器 */
        uiTIMxCLK = SystemCoreClock;    /* 当系统时钟为 72M 时,APB1、APB2 总线上挂载的时钟都为 72M */
    }
    else /* APB1 定时器 .  */
    {
        uiTIMxCLK = SystemCoreClock; // SystemCoreClock / 2;
    }

    if (_ulFreq < 100)
    {
        usPrescaler = 10000 - 1;                      /* 分频比 = 1000 */
        usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
    }
    else if (_ulFreq < 3000)
    {
        usPrescaler = 100 - 1;                      /* 分频比 = 100 */
        usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
    }
    else /* 大于4K的频率,无需分频 */
    {
        usPrescaler = 0;                    /* 分频比 = 1 */
        usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
    }

    /* 时基配置*/
    TIM_TimeBaseStructure.TIM_Period = usPeriod;                /* 定时器周期(设定自动重载寄存器 ARR 的值) */
    TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;          /* 预分频器 */
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                /* 时钟分频 */
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* 计数模式 */
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            /* 重复计数器(只存在于高级定时器) */

    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);

    TIM_ARRPreloadConfig(TIMx, ENABLE);

    /* TIM 中断启用*/
    TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);

    /* TIMx 使能计数器*/
    TIM_Cmd(TIMx, ENABLE);

    /* 配置TIM定时更新中断 (Update) */
    {
        NVIC_InitTypeDef NVIC_InitStructure; /* 中断结构体在 misc.h 中定义 */
        uint8_t irq = 0;                     /* 中断号, 定义在 stm32f10x.h */

        if (TIMx == TIM1)
            irq = TIM1_UP_IRQn;
        else if (TIMx == TIM2)
            irq = TIM2_IRQn;
        else if (TIMx == TIM3)
            irq = TIM3_IRQn;
        else if (TIMx == TIM4)
            irq = TIM4_IRQn;

#ifdef STM32F10X_HD

        else if (TIMx == TIM5)
            irq = TIM5_IRQn;
        else if (TIMx == TIM6)
            irq = TIM6_IRQn;
        else if (TIMx == TIM7)
            irq = TIM7_IRQn;
        else if (TIMx == TIM8)
            irq = TIM8_UP_IRQn;
#endif

        NVIC_InitStructure.NVIC_IRQChannel = irq;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = _PreemptionPriority; /* 抢占优先级 */
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = _SubPriority;               /* 子优先级 */
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
}

/****************************** END OF FILE ******************************/

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值