上期我们讲了STM32标准库基本定时器

这个图看起来很复杂
其实也就这样(你知道我想说什么)
上期我们说过通用定时器里面包含了基本定时器
所以我们上一期其实是只用了这个部分
然后本篇我们先讲的通用定时器计数
因为定时器说白了就是记录时钟的信号。如果改成外部的话
那么就可以记录外部的波的数据
我们先说第一个方法使用ETR
方法1:ETR

ETR主要用这通用定时器的这些部分
但是STM32的ETR引脚不多
虽然理论上每个通用定时器和高级定时器的CH1都是ETR
但是可能因为封装不同所以没
这里用STM32C8T6举例
点击展开完整图片

他也就PA12(TIM1) PA0(TIM2)有ETR
所以资源还是比较少的,但是配置相对简单。
参考代码函数
初始化ETR
1 | void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | 选择的定时器 | TIM1~TIM8 |
| uint16_t TIM_ExtTRGPrescaler | uint16_t | 选择分频器 | TIM_ExtTRGPSC_OFF//不分频 TIM_ExtTRGPSC_DIV2//2分频 IM_ExtTRGPSC_DIV4//4分频 TIM_ExtTRGPSC_DIV8//8分频 |
| uint16_t TIM_ExtTRGPolarity | uint16_t | 选择极性 | TIM_ExtTRGPolarity_Inverted//低电平或下降沿有效 TIM_ExtTRGPolarity_NonInverted//高电平或上升沿有效 |
| uint16_t ExtTRGFilter | uint16_t | 选择滤波器 | 0x00到0x0F |
| 返回值 | 无 | 无 | 无 |
这条函数设定单片机使用ETR
但是关于滤波器也就是uint16_t ExtTRGFilter
1、采样频率来源也就分频器
比如多少hz的采样,那么启用滤波器就会多少hz/分频器
2、连续检测次数就是,连续检测到多少次,他才会记录一次
参考滤波器
| 配置值 (二进制) | 采样频率来源 | 连续检测次数 (N) | 通俗效果 |
|---|---|---|---|
| 0000 | fCK_INT | 2 | 无滤波(最快,干扰大慎用) |
| 0001 | fCK_INT | 4 | 轻微滤波 |
| 0010 | fCK_INT | 8 | 稍强滤波 |
| 0011 | fCK_INT | 8 | 稍强滤波 |
| 0100 | fDTS/2 | 6 | 平衡型(推荐新手通用) |
| 0101 | fDTS/2 | 8 | 稳定型 |
| 0110 | fDTS/4 | 6 | 强滤波(适合按键 / 远距离信号) |
| 0111 | fDTS/4 | 8 | 强滤波 |
| 1000 | fDTS/8 | 6 | 极强滤波 |
| 1001 | fDTS/8 | 8 | 极强滤波 |
| 1010 | fDTS/16 | 5 | 超强力滤波 |
| 1011 | fDTS/16 | 6 | 超强力滤波 |
| 1100 | fDTS/32 | 5 | 极致抗干扰(响应最慢) |
| 1101 | fDTS/32 | 6 | 极致抗干扰 |
| 1110 | fDTS/32 | 8 | 极致抗干扰 |
| 1111 | fDTS/32 | 8 | 极致抗干扰 |
读取CNT值
1 | uint16_t TIM_GetCounter(TIM_TypeDef* TIMx) |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | 选择的定时器 | TIM1~TIM8 |
| 返回值 | uint16_t | 读取当前CNT | 无 |
设置CNT值
1 | void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter); |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| TIM_TypeDef* TIMx | TIM_TypeDef* | 选择的定时器 | TIM1~TIM8 |
| uint16_t Counter | uint16_t | 设定CNT值 | 0-65535 |
| 返回值 | 无 | 无 | 无 |
参考代码
点击展开完整代码
方法2:TIX
TIX主要使用的是定时器的这个部分
他对比于ETR来说TIM的4的通道都可以使用,但是使用前建议还是查一下表
点击展开引脚表

他主要是通过TIMx的通道捕获,然后TIx通过TIxFPx(这里的x是未知数)通道
TIxFPx(这里的x是未知数)通道发送给下面的CCR寄存器
然后CCR每触发一次,都会有信号给到CNT。
然后就简单了,和上面一样,当CNT记满后触发中断
不过这也有个限制,就是CCR他不会自动复位,要自动手动复位CCR
参考代码函数
初始化通用定时器
1 | void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); |
TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体
先用这个来复位结构体TIM_ICStructInit(&TIM_ICInitStructure);
| 名称 | 参数 | 作用 |
|---|---|---|
| TIM_ICInitStructure.Channel | TIM_Channel_1 TIM_Channel_2 TIM_Channel_3 TIM_Channel_4 |
选择通道 |
| TIM_ICInitStructure.ICPolarity | TIM_ICPolarity_Rising(上升沿) TIM_ICPolarity_Falling(下降沿) TIM_ICPolarity_BothEdge(双边沿) |
选择极性 |
| TIM_ICInitStructure.ICSelection | TIM_ICSelection_DirectTI(直接映射) TIM_ICSelection_IndirectTI(间接映射) TIM_ICSelection_TRC(从TRC输入) |
通道引脚直接连接捕获模块 |
| TIM_ICInitStructure.ICPrescaler | TIM_ICPSC_DIV1(不分频) TIM_ICPSC_DIV2(2分频) TIM_ICPSC_DIV4(4分频) TIM_ICPSC_DIV8(8分频) |
分频器 |
| TIM_ICInitStructure.ICFilter | 0x00 ~ 0x0F | 输入滤波 |
这里的输入滤波是采样次数
数字越高采样滤波越强,但是可能会带来一点点延迟
关于映射模式:
直接模式就是字面意思
间接模式:
参考解释

我们看这个图
我们可以看到
TI1FP2是到CC2的
TI2FP1是到CC1的
这个就是间接模式
当然有人问,TI1FP2和TI2FP2同时写入到CCR2咋办
STM32会进行仲裁直接大于间接
当然下面CH3和CH4同理一样不多讲了
读取寄存器函数
1 | uint16_t TIM_GetCapture-X(TIM_TypeDef* TIMx); |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| -x | — | 直接填1-4,选择读取不同的CCR寄存器 | TIM_GetCapture1 TIM_GetCapture2 TIM_GetCapture3 TIM_GetCapture4 |
| TIM_TypeDef* TIMx | TIM_TypeDef* | 选择的定时器 | TIM1~TIM8 |
| 返回值 | uint16_t | 读取当前CCR值 | 无 |
设定寄存器CCR
1 | void TIM_SetCompare-x(TIM_TypeDef* TIMx, uint16_t Compare1); |
| 参数 | 数据类型 | 作用 | 选项 |
|---|---|---|---|
| -x | — | 直接填1-4,选择设定不同的CCR寄存器 | TIM_SetCompare1 TIM_SetCompare2 TIM_SetCompare3 TIM_SetCompare4 |
| TIM_TypeDef* TIMx | TIM_TypeDef* | 选择的定时器 | TIM1~TIM8 |
| uint16_t Compare1 | uint16_t | 设定CCR的值 | 0-65535 |
| 返回值 | 无 | 无 | 无 |