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中多使用了占空比函数和配置输入捕获单元时的区别。均在代码图中标出
|