定时器输入捕获(4)


说在前面

今天10.1号 看了看日期 学了快10天

给自己安排了下面的学习内容

准备去学学剩下的ADC I2C SPI WDG 感觉就差不多了

单一定时器 是没有 输入输出两个功能不能同时启用

输入捕获

评测方法-测周法

N 是这个标准频率内计数的次数

其中N有可能没有记一个完整的次数 导致一定的误差

主从模式(手册没这个东西)

主模式 可以将定时器内部的信号,映射到TRGO引脚 用于触发别的外设

从模式 就是接收其他外设或者自身外设的一些信号 用于控制自身定时器的运行,也就是被别的信号控制

触发源选择 就是选择从模式的触发信号源的

其中在这次实验中 使用TI1FP1 和TI2FP2 这两个触发方式

时基单元

标准频率 = 72M / psc +1

ARR 建议设置最大值 65535

输入捕获基础结构

其中 只使用一个通道 所以只能捕获频率

从头到尾 先3后4 其中 3将结果保存后 从模式在进行

  1. GPIO输入方波信号

  2. 滤波器 一般来说越大越好 参考手册

  3. 边沿检测 上升沿检测

    1. 输入通道选择直连

    2. 分频器不分频

    3. TI1FP1 出现上升沿时 CNT的值 转运到 CCR1中

  4. 触发沿触发上升沿信号

    1. 从模式选择reset
    2. 将cnt计数器清零

PWMI 输出结构

主要讲下面的TI2FP2 是什么原理

下降沿触发

交叉通道输入

不分频

CCR2 记下CNT的值

不参与CNT清零

当记下CCR1 捕获的整个周期的cnt值的时候

通过ccr2/ccr1 就能捕获占空比

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "stm32f10x.h"                  // Device header


void ic_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
// 时钟使能都能忘 我也是没谁了
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_InitTypeDef gpioA_struct;
gpioA_struct.GPIO_Mode = GPIO_Mode_IPU;
gpioA_struct.GPIO_Pin = GPIO_Pin_6;
gpioA_struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioA_struct);

TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_InitStruct;
// 时钟分频
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
// ARR 自动重装器
// 计数重装值 最好设置大一点,防止计数溢出
TIM_InitStruct.TIM_Period = 65536 - 1 ;
// PSC 预分频器
// 决定了测周法的标准频率FC
TIM_InitStruct.TIM_Prescaler = 72 - 1;
// CNT 计数器的值 高级计数器才有 这里不需要使用
TIM_InitStruct.TIM_RepetitionCounter = 0x0000;
// 这里是 时基单元的初始化
TIM_TimeBaseInit(TIM3, &TIM_InitStruct);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);

// 定时器3 输入捕获设置
TIM_ICInitTypeDef TIM_ICinitStruct;
TIM_ICStructInit(&TIM_ICinitStruct);
TIM_ICinitStruct.TIM_Channel = TIM_Channel_1;
// 滤波器 具体看定义
TIM_ICinitStruct.TIM_ICFilter = 0xF;
TIM_ICinitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICinitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// 没看懂 数据选择器 来控制是直连通道还是交叉通道
TIM_ICinitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_PWMIConfig(TIM3, &TIM_ICinitStruct);

// TRGI触发源为TI1FP1
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

TIM_Cmd(TIM3,ENABLE);


}

uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

uint32_t IC_GetDuty(void)
{
// 通道整错了 可还行
return (TIM_GetCapture2(TIM3)+1)*100 / (TIM_GetCapture1(TIM3)+1);
}