前言
笔者使用的是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 ******************************/