1.实物图如下:
2.代码如下:
主函数代码如下:
IC.c( 输入捕获模式)代码部分如下:
#include "stm32f10x.h" // Device header //思路:参照输入捕获基本结构图 //1.RCC开启时钟,开启GPIO和TIM时钟 //2.GPIO初始化,配置GPIO为输入模式(上拉输入或浮空输入) //3.配置时基单元,使CNT计数器在内部时钟驱动下自增 //4.配置输入捕获单元,是结构体,包括滤波器,极性,两个通道同时捕获同一个引脚,分频器 //5.配置TRGI的触发源为TI1FP1 //6.配置从模式为ReSet //7.调用TIM_Cmd,开启定时器 void IC_Init(void)//输入捕获初始化 { //1~3开启时钟,配置GPIO,配置时基单元(直接抄写LED代码,修改通道和引脚,输入模式等即可) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启APB1时钟,TIM2是输出PWM,更改为TIM3(仍是APB1外设) //配置GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //GPIO的时钟配置,查表得TIM3的通道1和2对应PA6和PA7(GPIOA);通道3和通道4对应PB0和PB1(GPIOB) GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//选择上拉输入模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//用的是PA6引脚 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_CKD_DIV1,1分频,不分配;TIM_CKD_DIV2,2分频;TIM_CKD_DIV4,4分频----要求不高时,随意选择 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数 //TIM_CounterMode_Up向上计数;TIM_CounterMode_Down向下计数;TIM_CounterMode_CenterAligned1等为中央对齐 TIM_TimeBaseInitStructure.TIM_Period=65536-1;//自动重装器的值,取最大值,防止溢出---ARR的值 TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//预分频,对72M进行7200分频----PSC的值 TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器用到,通用定时器选0 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//结构体 //4.配置输入捕获单元(两个通道同时捕获同一个引脚,方式一:再次初始化 方式二:直接用库函数) TIM_ICInitTypeDef TIM_ICInitStructuer; TIM_ICInitStructuer.TIM_Channel=TIM_Channel_1;//指定选择通道几,通道1为TIM_Channel_1 TIM_ICInitStructuer.TIM_ICFilter=0xF;//配置输入捕获的滤波器(有毛刺或噪声时增大滤波器参数) //参数解释:这个数可是是0x0~0xF之间的数.数越大,滤波效果越好 //滤波器计次不会改变信号的原有频率,之后让波形更符合条件. TIM_ICInitStructuer.TIM_ICPolarity=TIM_ICPolarity_Rising;//选择极性----上升沿触发还是下降沿还是都触发 TIM_ICInitStructuer.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器, //不分频就是每次触发都有效,2分频是每隔一次有效一次... TIM_ICInitStructuer.TIM_ICSelection=TIM_ICSelection_DirectTI;//选择直连通道 TIM_ICInit(TIM3,&TIM_ICInitStructuer); //方式一:再次初始化 // TIM_ICInitStructuer.TIM_Channel=TIM_Channel_2;//指定选择通道几,通道2为TIM_Channel_2 // TIM_ICInitStructuer.TIM_ICFilter=0xF;//配置输入捕获的滤波器(有毛刺或噪声时增大滤波器参数) // //参数解释:这个数可是是0x0~0xF之间的数.数越大,滤波效果越好 // //滤波器计次不会改变信号的原有频率,之后让波形更符合条件. // TIM_ICInitStructuer.TIM_ICPolarity=TIM_ICPolarity_Falling;//选择极性----上升沿触发还是下降沿还是都触发 // TIM_ICInitStructuer.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器, // //不分频就是每次触发都有效,2分频是每隔一次有效一次... // TIM_ICInitStructuer.TIM_ICSelection=TIM_ICSelection_IndirectTI;//选择交叉通道 // TIM_ICInit(TIM3,&TIM_ICInitStructuer); //方式二:直接用库函数 TIM_PWMIConfig(TIM3,&TIM_ICInitStructuer); //5.配置TRGI的触发源为TI1FP1 TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//第二个参数选择触发源TIM_TS_TI1FP1 //6.配置从模式为ReSet TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset); //7.调用TIM_Cmd,开启定时器 TIM_Cmd(TIM3,ENABLE); } //注:想要查看频率时,读取CCR,计算即可 //fx=fc/N //fc=72M/(PSC+1) //因为PSC=72,所以fc=1MHz,所以fx=1000000/N,(N就是CCR) uint16_t IC_GetFreq(void) { return 1000000/(TIM_GetCapture1(TIM3)+1); } //获取占空比的函数: uint16_t IC_GetDuty(void) { return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);//CCR2/CCR1就是占空比(结果是0~1,所以要*100) }
IC.h(输入捕获模式)代码部分:
#ifndef __IC_H #define __IC_H uint16_t IC_GetFreq(void); void IC_Init(void); uint16_t IC_GetDuty(void); #endif
注:此代码与测频率基本一致,只是主函数中多显示了一个占空比的相关指令,IC.c中多使用了占空比函数和配置输入捕获单元时的区别。均在代码图中标出