TIM定时器
TIM简介
TIM(Timer) 定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz(系统主频)计数时钟下可以实现最大59.65s的定时(72M/65536/65536取倒数)
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
定时器类型
类型 | 编号 | 总线 | 功能 |
高级定时器 | TIM1、TIM8 | APB2 | 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能 |
通用定时器 | TIM2、TIM3、TIM4、TIM5 | APB1 | 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能 |
基本定时器 | TIM6、TIM7 | APB1 | 拥有定时中断、主模式触发DAC的功能 |
定时器结构框图
基本定时器
时基单元寄存器功能介绍
计数器寄存器(TIMx_CNT) 由预分频器的时钟输出CK_CNT驱动, 当设置了控制寄存器TIMx_CR1中的计数器使能位(CEN)时, CK_CNT才有效, 16位寄存器, 可计数范围为0~65535
预分频器(TIMx_PSC) 16位寄存器(可设置0~65535), 可以将计数器的时钟频率按1~65536之间的任意值分频。这个控制寄存器带有缓冲器, 它不能够在工作时被改变。新的预分频器参数再下一次更新事件到来时被采用
自动重装载寄存器(TIMx_ARR) 是预先装载的, 写或读自动重装载寄存器将访问预装载寄存器。根据在TIMx_CR1中的自动重装载预装载使能位(ARPE)的设置, 预装载寄存器的内容被立即或在每次更新事件(UEV)时传送到其影子寄存器。也是一个16位寄存器, 可设置范围为0~65535,当计数值等于自动重装值时, 产生中断并清零计数器
Note: 由计数器寄存器的计数范围、预分频器的分频范围和自动重装载寄存器的可设置范围, 可以计算:最大定时为59.65s
主模式触发DAC功能(硬件自动化设计)
使用DAC时, 可能会用DAC输出一段波形
把定时器的更新事件映射到TRGO(Trigger Out)的位置, TRGO直接接到DAC的触发转换引脚上, 这样定时器的更新就不需要再通过中断来触发DAC转换了
好处避免了主程序处于频繁被中断的状态(该状态会影响到其他中断的运行)
计数模式: 基本定时器的计数模式只有向上计数的方式
通用定时器
通用定时器的结构
STM32通用定时器主要包括1个外部触发引脚(TIMx_ETR), 4个输入/输出通道(TIMx_CH1, TIMx_CH2, TIMx_CH3, TIMx_CH4), 一个内部时钟(CK_INT), 一个触发控制器、1个时基单元(由预分频器PSC、自动重装载寄存器ARR和计数器CNT组成) ..( 预分频器 Prescaler)
时钟源
定时器时钟可由下列时钟源提供:
内部时钟(CK_INT)
外部时钟模式1(外部输入引脚TIx), 图中为从TIMx_CHx往右边看, 具体位置参考引脚定义表
外部时钟模式2(外部触发输入ETR), 信号来源TIMx_ETR外部触发引脚, 具体位置参考引脚定义表
内部触发输入(ITR, 使用一个定时器作为另一个定时器的预分频器, 也叫级联的方式) 比如: 先初始化TIM3,然后使用主模式把它的更新事件映射到TRGO上,再初始化TIM2, 选择ITR2(对应TIM3的TRGO), 选择时钟为内部触发输入,这样TIM3的更新事件就可以驱动TIM2的时基单元,也就实现了定时器的级联
计数模式:
向上计数(最常用)
向下计数
中央对齐模式(向上/向下计数)
高级定时器
重复次数计数器
可以实现每隔几个计数周期,才发生一次更新事件和更新中断, 相当于对输出的更新信号又做了一次分频 最大定时时间59.65*65536
DTG(Dead Time Generate)
死区生成电路: 产生一定时长的死区, 让桥臂的上下管全部关断, 防止直通现象。
直通现象: 电子管是利用阴极和阳极之间产生束流来实现电流控制,而所谓直通现象就是阳极与阴极直接连通了。
目的: 为了避免开关切换瞬间, 由于器件的不理想, 造成短暂的直通现象
输出
前三路输出引脚由原来的一个, 变为了两个互补输出, 可以输出一对互补的PWM波,(目的是为了驱动三相无刷电机)
刹车输入功能
目的: 给电机驱动提供安全保障, 如果外部引脚BKIN(Break IN) 产生了刹车信号, 或者内部时钟失效, 产生了故障, 控制电路就会自动切断电机的输出, 防止意外发生
定时中断基本结构
运行控制: 一些寄存器可以控制时基单元的运行
左边部分为时基单元提供时钟,也可通过配置相应寄存器选择时钟源和模式
时基单元产生的中断信号会先在状态寄存器里配置一个中断标志位, 标志位会通过中断输出控制(中断输出的允许位), 到NVIC申请中断
预分频器时序(后面的图差不多, 就不详细说明了)
CK_PSC:一般为72MHz
CNT_EN:计数器使能,高电平正常允许,低电平停止
CK_CNT:计数器时钟
计数器寄存器:跟随时钟的上升沿不断自增
预分频寄存器缓冲机制:
预分频缓冲器(影子寄存器):
真正起作用的寄存器
机制过程:
假设在某时刻,把预分频寄存器由0改成1,若计数到一半,则前半部分和后半部分的计数频率就不一致了。而在STM32中,定时器比较严谨,当计数计一半时改变了分频值,这个变化不会立刻生效,而是等本次计数周期结束时,产生了更新事件,预分频寄存器的值才会被传递到缓冲寄存器里,才会生效,所以真正起作用的寄存器是影子寄存器
预分频计数器:
预分频器内部实际上也是靠计数分频,当预分频值为0时,计数器就一直为0,直接输出原频率; 当预分频值为1时,计数器就0、1、0、1这样计数,在回到0时输出一个脉冲, 这样输出频率就是输入频率的2分频
计数器计数频率: CK_CNT = CK_PSC / (PSC + 1)
计数器时序
计数器溢出频率: CK_CNT_OV = CK_CNT / (ARR +1) = CK_PSC / (PSC + 1) / (ARR + 1)
计数器无预装时序
计数器有预装时序
RCC时钟树
Note: 程序中主函数之前还会执行SystemInit函数,这个函数就是用来配置时钟树的
Attention: 主频经过2分频后到APB1为36MHz, 到TIM2~7前频率又×2,因此TIM2~7的频率还是72MHz,而APB2的频率为72MHz
案例: 定时器定时中断&定时器外部时钟
定时器定时中断
1. 配置定时器
RCC开启时钟
// RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
选择时钟源, 即黄色区域部分
// 选择时钟源
TIM_InternalClockConfig(TIM2); // 内部时钟
可供选择的时钟源在stm32f10x_tim.h中有定义, 感兴趣可以参考STM32技术手册
void TIM_InternalClockConfig(TIM_TypeDef* TIMx); // 内部时钟
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
uint16_t TIM_ICPolarity, uint16_t ICFilter);
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter); // 外部时钟模式1
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); // 外部时钟模式2
配置时基单元
// 配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 内部时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数模式
TIM_TimeBaseInitStructure.TIM_Period=50000-1; // 加载到自动重装寄存器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1; // 预分频的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; // 重复计数器的值
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); // 调用初始化函数
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除标志
最后一步清除标志,解决了复位上电后Num不从0开始而从1开始的问题
原因是TIM_TimeBaseInit() 时基初始化函数在最后面, 手动触发了一次更新事件, 导致标志位也被设置, 因此上电后Num已经加了一次,在该函数外面将标志位清除即可解决问题。
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
{
uint16_t tmpcr1 = 0;
/* Check the parameters */
assert_param(IS_TIM_ALL_PERIPH(TIMx));
assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
tmpcr1 = TIMx->CR1;
if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
(TIMx == TIM4) || (TIMx == TIM5))
{
/* Select the Counter Mode */
tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
}
if((TIMx != TIM6) && (TIMx != TIM7))
{
/* Set the clock division */
tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
}
TIMx->CR1 = tmpcr1;
/* Set the Autoreload value */
TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
/* Set the Prescaler value */
TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))
{
/* Set the Repetition Counter value */
TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
}
/* Generate an update event to reload the Prescaler and the Repetition counter
values immediately */
TIMx->EGR = TIM_PSCReloadMode_Immediate; // 问题在这里
}
使能更新中断
// 使能更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 以下为TIM_ITConfig函数的注释
/**
* @brief Enables or disables the specified TIM interrupts.
* @param TIMx: where x can be 1 to 17 to select the TIMx peripheral.
* @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
* This parameter can be any combination of the following values:
* @arg TIM_IT_Update: TIM update Interrupt source
* @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
* @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
* @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
* @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
* @arg TIM_IT_COM: TIM Commutation Interrupt source
* @arg TIM_IT_Trigger: TIM Trigger Interrupt source
* @arg TIM_IT_Break: TIM Break Interrupt source
* @note
* - TIM6 and TIM7 can only generate an update interrupt.
* - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
* TIM_IT_CC2 or TIM_IT_Trigger.
* - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.
* - TIM_IT_Break is used only with TIM1, TIM8 and TIM15.
* - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.
* @param NewState: new state of the TIM interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
配置NVIC
// 配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; // 中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级
NVIC_Init(&NVIC_InitStructure);
这里和之前一样, 就不详细解释了
启动定时器
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
操作的是上图的运行控制部分, 控制定时器的运行
整体初始化代码
void Timer_Init(void)
{
// RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 选择时钟源
TIM_InternalClockConfig(TIM2); // 内部时钟
// 配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 内部时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数模式
TIM_TimeBaseInitStructure.TIM_Period=50000-1; // 加载到自动重装寄存器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1; // 预分频的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; // 重复计数器的值
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除标志
// 使能更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; // 中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级
NVIC_Init(&NVIC_InitStructure);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
return;
}
2.编写中断事件
void TIM2_IRQHandler(void)
{
// 判断标志位
if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
Num++;
// 清除标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
这里我们将中断函数放到main.c下, 方便操作Num变量
也可在Timer.c 用extern指令引入Num变量
3.整体代码
main.c
#include "stm32f10x.h"
#include "OLED.h"
#include "Timer.h"
// 定时器定时中断
// 2023年3月16日12:21:33
uint16_t Num;
int main(void)
{
OLED_Init();
Timer_Init();
OLED_ShowString(1, 1, "Num:");
OLED_ShowString(2, 1, "CNT:");
while(1)
{
OLED_ShowNum(1, 5, Num, 5);
OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);
}
}
void TIM2_IRQHandler(void)
{
// 判断标志位
if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
Num++;
// 清除标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
Timer.c
#include "stm32f10x.h"
// extern uint16_t Num;
void Timer_Init(void)
{
// RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 选择时钟源
TIM_InternalClockConfig(TIM2); // 内部时钟
// 配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 内部时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数模式
TIM_TimeBaseInitStructure.TIM_Period=50000-1; // 加载到自动重装寄存器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1; // 预分频的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; // 重复计数器的值
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除标志
// 使能更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; // 中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级
NVIC_Init(&NVIC_InitStructure);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
return;
}
/*
void TIM2_IRQHandler(void)
{
// 判断标志位
if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
Num++;
// 清除标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
*/
定时器外部中断
硬件接线
整体代码
main.c
#include "stm32f10x.h"
#include "OLED.h"
#include "Timer.h"
// 定时器外部中断
// 2023年3月16日14:26:54
uint16_t Num;
int main(void)
{
OLED_Init();
Timer_Init();
OLED_ShowString(1, 1, "Num:");
OLED_ShowString(2, 1, "CNT:");
while(1)
{
OLED_ShowNum(1, 5, Num, 5);
OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);
}
}
void TIM2_IRQHandler(void)
{
// 判断标志位
if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
Num++;
// 清除标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
Timer.c
#include "stm32f10x.h"
// extern uint16_t Num;
void Timer_Init(void)
{
// RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 选择时钟 外部时钟模式1
TIM_ETRClockMode1Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
// 配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 内部时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数模式
TIM_TimeBaseInitStructure.TIM_Period=10-1; // 加载到自动重装寄存器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=1-1; //
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; // 重复计数器的值
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除标志
// 使能更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; // 中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级
NVIC_Init(&NVIC_InitStructure);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
return;
}
/*
void TIM2_IRQHandler(void)
{
// 判断标志位
if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
Num++;
// 清除标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
*/
注意: 这里与江科大教程中不同, 时钟源采用的是外部时钟模式1
这是因为, PA0除了支持TIM2_ETR(外部时钟模式2) 也支持 TIM2_CH1(外部时钟模式1)
TIM定时器常用函数
函数原型 | 功能 |
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); | 根据TIM_TimeBaseInitStruct中指定的参数, 初始化TIMx的时基单位 |
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); | 把TIM_TimeBaseInitStruct中的每一个参数按缺省值填入 |
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); | 使能或失能TIMx外设 |
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); | 使能或失能指定的TIM中断 |
void TIM_InternalClockConfig(TIM_TypeDef* TIMx); | 设置TIMx内部时钟 |
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); | 设置TIMx内部触发为外部时钟模式 |
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter); | 设置TIMx触发为外部时钟 |
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); | 配置TIMx外部时钟模式1 |
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); | 配置TIMx外部时钟模式2 |
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); | 配置TIMx外部触发 |
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); | 设置TIMx预分频 |
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); | 设置TIMx计数器模式 |
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); | 使能或失能TIMx在ARR上的预装载寄存器 |
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter); | 设置TIMx计数器寄存器值 |
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload); | 设置TIMx自动重装载寄存器值 |
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx); | 获取TIMx计数器的值 |
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); | 获取TIMx预分频值 |
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); | 检查指定的TIM标志位设置与否 |
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); | 清除TIMx的待处理标志位 |
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); | 检查指定的TIM中断发生与否 |
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); | 清除TIMx的中断待处理位 |
Note: ClearFlag()和ClearITPendingBit()的区别, 请参考: http://t.csdn.cn/0KYkq
参考资料:
嵌入式单片机STM32原理及应用(机械工业出版社)