0%

6-6输入捕获模式测频率&PWMI模式测频率占空比

常用函数

1
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

用结构体配置输入捕获单元的函数。
ICInit的4个通道,共用一个函数,这一点和OCInit不同。

1
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

初始化输入捕获单元,可以配置两个通道。
把外设电路结构配置成PWMI模式。

1
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);

给输入捕获结构体赋一个初始值。

1
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

选择输入触发源TRGI。从模式的触发源选择。

1
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);

选择输出触发源TRGO,选择主模式输出的触发源。

1
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

选择从模式。

1
2
3
4
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);

分别单独配置通道1、2、3、4的分频器

1
2
3
4
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);

分别读取4个通道的CCR。输入捕获模式下,CCR是只读的,必须使用GetCapture读出。

输入捕获模式测频率

IC.c

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
#include "stm32f10x.h"                  // Device header
void IC_Init(void)
{
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//TIM3是APB1的外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使用TIM3的通道1,引脚是PA6
//配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置时基单元
TIM_InternalClockConfig(TIM3);//内部时钟,计时器TIM3

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARR,这里最好设置大一些,防止溢出,这里给最大值
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PSC,这个值决定测周法的标准频率fc,根据信号频率分布范围调整
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
//初始化输入捕获单元
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//选择通道
TIM_ICInitStructure.TIM_ICFilter = 0xF;//滤波器
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//极性选择
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//选择触发信号从哪个引脚输入
TIM_ICInit(TIM3,&TIM_ICInitStructure);

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);
}


main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
OLED_Init();
PWM_Init();
IC_Init();

OLED_ShowString(1,1,"Freq:00000Hz");

PWM_SetPrescaler(720 - 1); //FREQ = 72M / (PSC + 1) / 100
PWM_SetCompare1(50);//Duty = CCR/100
while(1)
{
OLED_ShowNum(1,6,IC_GetFreq(),5);
}
}


PWMI模式测占空比

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
#include "stm32f10x.h"                  // Device header
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

TIM_InternalClockConfig(TIM3);

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);

TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit(TIM3,&TIM_ICInitStructure);

TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);//这个函数,只要传入一个通道的参数,会自动把剩下的通道初始化成相反的配置

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);
}

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
OLED_Init();
PWM_Init();
IC_Init();

OLED_ShowString(1,1,"Freq:00000Hz");
OLED_ShowString(2,1,"Duty:00%");

PWM_SetPrescaler(720 - 1); //FREQ = 72M / (PSC + 1) / 100
PWM_SetCompare1(50);//Duty = CCR/100
while(1)
{
OLED_ShowNum(1,6,IC_GetFreq(),5);
OLED_ShowNum(2,6,IC_GetDuty(),2);
}
}