关于定时器
STM32体内存在有3种定时器
| 类型 | 编号 | 总线 | 功能 |
|---|---|---|---|
| 高级定时器 | TIM1、TIM8 | APB2 | 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能 |
| 通用定时器 | TIM2、TIM3、TIM4、TIM5 | APB1 | 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、 编码器接口、主从触发模式等功能 |
| 基本定时器 | TIM6、TIM7 | APB1 | 拥有定时中断、主模式触发DAC的功能 |
高级包含通用,通用包含基本
关于定时器
有点晃眼睛你真要看吗?
高级定时器
通用定时器
基本定时器
我们先不看其他的,我们就先只研究基本定时器
CK_INK是单片机的工作频率,比如stm32f103是72mhz的
也就是72微秒触发一次
时间单位转换
1GHZ=1X10^3MHZ=1X10^6Khz=1x10^9HZ
周期=1/频率
1秒(s) = 1x10^3 毫秒(ms) = 1x10^6 微秒(μs) = 1X10^9纳秒(ns) = 1X10^12 皮秒(ps)
1秒(s) = 1000 毫秒(ms) = 1,000,000 微秒(μs) = 1,000,000,000 纳秒(ns) = 1,000,000,000,000 皮秒(ps)
周期转换
1hz=1秒
1KHZ=1毫米
1MHZ=1微妙
1GHZ=1纳秒
然后经过PSC(也就预分频器)
那么经过分频器实际频率就是 CK_INK/(PSC+1)
那么CK_INK/(PSC+1)的工作周期影响的就是CNT计数器
然后经过ARR(自动重载定时器)
向上计数的时候
CK_INK/(PSC+1)每经过一个周期CNT就加1
当CNT等于(ARR+1)的时候,那么就会输出触发(例如触发中断)
触发完成后,CNT就会变成0开始新一轮
向下计数的时候
CNT等于(ARR+1)
CK_INK/(PSC+1)每经过一个周期CNT就减1
当CNT等于0的时候,那么就会输出触发(例如触发中断)
触发完成后,CNT就会重新等于(ARR+1)开始新一轮
因为CK_INK/(PSC+1)是频率我们换成时间要1/[CK_INK/(PSC+1)]=(PSC+1)/CK_INK
因此我们可以得出:
定时时间=[(PSC+1)/CK_INK](ARR+1)
=(ARR+1)(PSC+1)/CK_INK
关于几个注意事项
1、为什么要+1
因为数电是0开始的不是1开始
2、PSC和ARR的最大值是65535
因为stm32是标准 16 位定时器
代码函数
1、使用RCC开启时钟 STM32标准库GPIO
2、选择定时器
3、初始化
4、配置连接中断NVIC STM32标准库中断
开启内部时钟
1 | void TIM_InternalClockConfig(TIM_TypeDef* TIMx); |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | 配置的定时器 | TIM1~TIM8 |
| 返回值 | 无 | 无 | 无 |
选择要使用的定时器开启内部时钟
初始化基本定时器
1 | void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | — | 选择要初始化的定时器 |
| TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct | — | 结构体配置 | — |
| 返回值 | 无 | 无 | 无 |
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; 定义结构体
| 名称 | 参数 | 作用 |
|---|---|---|
| TIM_TimeBaseInitStructure.TIM_ClockDivision | #define TIM_CKD_DIV1// 不分频 #define TIM_CKD_DIV2// 2分频 #define TIM_CKD_DIV4// 4分频 |
选择分不分频 |
| TIM_TimeBaseInitStructure.TIM_CounterMode | TIM_CounterMode_Up // 向上计数模式 TIM_CounterMode_Down // 向下计数模式 TIM_CounterMode_CenterAligned1 // 中心对齐模式1(高级PWM专用) TIM_CounterMode_CenterAligned2 // 中心对齐模式2(高级PWM专用) TIM_CounterMode_CenterAligned3 // 中心对齐模式3(高级PWM专用) |
向上计数/向下计数 |
| TIM_TimeBaseInitStructure.TIM_Period | 0-65535 | ARR(上方有解释) |
| TIM_TimeBaseInitStructure.TIM_Prescaler | 0-65535 | PSC(上方有解释) |
| TIM_TimeBaseInitStructure.TIM_RepetitionCounter | 0-65535 | 当CNT被重置了多少次才触发 |
启动定时器
1 | void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | — | 选择要启动的定时器 |
| FunctionalState NewState | — | 是否启动 | ENABLE: 启动计数器 DISABLE: 停止计数器 |
| 返回值 | 无 | 无 | 无 |
清空标志位
1 | void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | — | 选择要的定时器 |
| uint16_t TIM_FLAG | uint16_t | 要清空的定时器标志位 | TIM_FLAG_Update//全部定时器计数溢出 TIM_FLAG_CC1~CC4//PWM 比较匹配 TIM_FLAG_Trigger//ITR 触发从模式用 TIM_FLAG_Break//高级 TIM1/TIM8电机刹车、紧急保护 TIM_FLAG_UpdateRep//高级TIM1/TIM8重复计数器溢出 |
| 返回值 | 无 | 无 | 无 |
开启定时器中断
1 | void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | — | 选择要的定时器 |
| uint16_t TIM_IT | uint16_t | 选择哪种中断 | TIM_IT_Update//全部定时器计数溢出 TIM_IT_CC1~CC4//PWM 比较匹配 TIM_IT_Trigger//ITR 触发从模式用 TIM_IT_Break//高级 TIM1/TIM8电机刹车、紧急保护 TIM_IT_UpdateRep//高级TIM1/TIM8重复计数器溢出 |
| FunctionalState NewState | — | 开启 / 关闭 定时器的指定中断功能 | ENABLE/ DISABLE |
| 返回值 | 无 | 无 | 无 |
TIM_IT_Update是溢出后会触发中断
其他的是有数据来就会触发
IT_CC是通用定时器的CCR寄存器
中断清空标志位:
中断标志位
1 | ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) //读取标志位 |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | — | 选择要的定时器 |
| uint16_t TIM_IT | uint16_t | 选择哪种中断 | TIM_IT_Update//全部定时器计数溢出 TIM_IT_CC1~CC4//PWM 比较匹配 TIM_IT_Trigger//ITR 触发从模式用 TIM_IT_Break//高级 TIM1/TIM8电机刹车、紧急保护 TIM_IT_UpdateRep//高级TIM1/TIM8重复计数器溢出 |
| IITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) | — | 提供返回值 | RESET// 0 → 无中断触发 SET// 1 → 有中断触发 |
参考代码
1 | #include "stm32f10x.h" // Device header |
1 | #ifndef __TIMER_H |
1 | #include "stm32f10x.h" // Device header |
效果:
每过2秒PC14自动翻转
工程下载: