目录
一、IC介绍
1.1、IC作用
1.2、电路部分
1.2.1、详细电路作用
1.2.2、从模式控制器
1.3、输入捕获配置基本结构
1.3.1、PWMI模式
二、代码配置
2.1、从模式函数
2.1.1、TIM_SelectInputTrigger()
2.1.2、TIM_SelectSlaveMode()
2.1.3、TIM_SelectSlaveMode()
2.2.输入捕获及时基单元函数
2.2.1、TIM_ICInit()
2.2.2、TIM_PWMIConfig()
2.2.3、TIM_ICStructInit()
2.2.4 TIM_SetICxPrescaler()
2.2.5、TIM_GetCapturex();
三、IC初始代码及其他代码配置
3.1、IC_Init()模块完整代码
3.2、main 函数完整代码
一、IC介绍
1.1、IC作用
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
1.2、频率测量
测量方法:
测频法:在闸门时间T内,对上升沿计次,得到N,则频率等于
测周法:两个上升沿内,以标准频率计次,得到N ,则频率对于
中界频率:测频法与测周法误差相等的频率点
当待测频率大于中界频率是采用测频法,反之使用测周法。
1.2、电路部分
1.2.1、详细电路作用
1.2.2、从模式控制器
TI1FP1信号自动触发从模式,从模式可以选择Reset,从而令从模式自动清零CNT. (详情可参考芯片手册 14.4.1)。
1.3、输入捕获配置基本结构
配置顺序:
1、RCC开启时钟,打开GPIO和TIM的时钟。
2、GPIO初始化,GPIO 配置成输入模式(一般选择上拉输入/浮空输入)。
3、配置时基单元,让计数器CNT在内部时钟的驱动下自增运行。
4、配置输入捕获单元,包括滤波器、极性、连接通道、分频器等参数。
5、从模式触发源。
6、触发后的执行操作。
7、调用TIM_Cmd函数,开启定时器。
注意:CNT的值存在计数上限,即最大只能计数65535
1.3.1、PWMI模式
CCR2是高电平期间的计数值,CCR2/CCR1的值对应着占空比。
二、代码配置
2.1、从模式函数
2.1.1、TIM_SelectInputTrigger()
//从模式触发源TRGI的选择
参数1:选择定时器;参数2:从下图配置图选择
TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
从模式对应配置,对应下图
2.1.2、TIM_SelectSlaveMode()
//选择主模式输出的触发源
TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
2.1.3、TIM_SelectSlaveMode()
//选择从模式
TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
2.2.输入捕获及时基单元函数
2.2.1、TIM_ICInit()
//用结构体配置输入捕获单元函数
//参数1:选择定时器、参数2:各个配置的结构体
TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
使用:
图1
TIM_ICInitTypeDef TIM_ICINitstructure;
TIM_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道1
(1)TIM_ICINitstructure.TIM_ICFilter=0xF;//配置输入捕获的滤波器,数值大,滤波效果越好
(2)TIM_ICINitstructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//极性选择 上升沿or下降沿,
(4)TIM_ICINitstructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器配置
(3)TIM_ICINitstructure.TIM_ICSelection=TIM_ICSelection_DirectTI; //配置数据选择器
TIM_ICInit(TIM3,&TIM_ICINitstructure);
分频器配置,585~588分别是不分频,2分频,4分频,8分频
极性选择:553~555分别是上升沿、下降沿、上升沿下降沿都触发
2.2.2、TIM_PWMIConfig()
//与2.1.1一样都是用于初始化捕获单元的函数,可快速配置2个通道。
TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
2.2.3、TIM_ICStructInit()
//给输入捕获结构体赋予初始值。
TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
2.2.4 TIM_SetICxPrescaler()
//配置分频器通道函数——函数中的x可取值为1~4
TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
2.2.5、TIM_GetCapturex();
//分别读取4个通道的CCR的值,函数中的x可取值为1~4
TIM_GetCapture1(TIM_TypeDef* TIMx);
TIM_GetCapture1(TIM_TypeDef* TIMx);
TIM_GetCapture1(TIM_TypeDef* TIMx);
TIM_GetCapture1(TIM_TypeDef* TIMx);
三、IC初始代码及其他代码配置
3.1、IC_Init()模块完整代码
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启时钟,选择GPIOkou
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//选择上拉输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
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;
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //配置时基单元
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);//整个结构体附初始值,避免出现错误
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //输出比较模式
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出比较极性
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态,使能or失能
TIM_OCInitStructure.TIM_Pulse=0; //设置CCR寄存器的值
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_ICInitTypeDef TIM_ICINitstructure;
TIM_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道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 100000/TIM_GetCapture1(TIM3);
}
1、对于第一个 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启时钟。
为什么要选择TIM3定时器,是因为TIM2需要输出PWM,而输入与输出模式共用寄存器,故需要更改一个定时器。
2、该模块 uint32_t IC_GetFreq(void) 数为了得到测频法中的频率。其中涉及到的函数TIM_GetCapture1()是读取通道的CCR的值。(该函数位于2.2.5)
3.2、main 函数完整代码
int main(void)
{
IC_Init();
OLED_Init(); //OLED初始化
PWM_Init();
OLED_ShowString(1,1,"Freq:00000Hz");
PWM_SetPrescaler(720-1); //Freq=72M/(PSC+1)/100
PWM_SetCompare(50); //Duty=CCR/100
while(1)
{
OLED_ShowNum(1,6,IC_GetFreq(),5);
}
}
3.3、问题补充
最后所呈现的结果如下图所示
这与我们所设想的1000Hz的值不吻合。
解决方法:
uint32_t IC_GetFreq(void)
{
return 100000/(TIM_GetCapture1(TIM3)+1);//读取通道的CCR的值
}
TIM_GetCapture1(TIM3)+1即可
原因:暂未找到
四、PWMI模式
4.1、代码配置
4.1.1、TIM_PWMIConfig()
TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
该函数效果是把结构体配置参数部分重复复制一份,即取代红色框图部分,传入一个通道参数后,函数会自动剩下的通道的参数配置成相反配置。(仅支持通道1/2)
4.1.2、计算占空比
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);
// 占空比=CCR2/CCR1
}
占空比计算公式可以参考下图文章来源:https://www.toymoban.com/news/detail-822268.html
文章来源地址https://www.toymoban.com/news/detail-822268.html
4.2、完整代码
4.2.1、 void IC_Init(void)代码部分
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启时钟,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启时钟,选择GPIOkou
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//选择上拉输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM3);//初始化时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //指定参数分频值(选择1分频),DIV22分频 DIV4 44分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择技术模式;
TIM_TimeBaseInitStructure.TIM_Period=65536-1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;//PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //配置时基单元
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);//整个结构体附初始值,避免出现错误
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //输出比较模式
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出比较极性
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态,使能or失能
TIM_OCInitStructure.TIM_Pulse=0; //设置CCR寄存器的值
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_ICInitTypeDef TIM_ICINitstructure;
TIM_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道1
TIM_ICINitstructure.TIM_ICFilter=0xF; //配置输入捕获的滤波器,数值大,滤波效果越好
TIM_ICINitstructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//极性选择 上升沿or下降沿,此处选择上升沿
TIM_ICINitstructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器配置
TIM_ICINitstructure.TIM_ICSelection=TIM_ICSelection_DirectTI; //配置数据选择器
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 100000/(TIM_GetCapture1(TIM3)+1);//TIM_GetCapture1()-读取通道的CCR的值
}
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1); // 占空比=CCR2/CCR1
}
4. 2.2、main 函数代码
int main(void)
{
IC_Init();
OLED_Init(); //OLED初始化
PWM_Init();
OLED_ShowString(1,1,"Freq:0000000Hz");
OLED_ShowString(2,1,"Duty:00%");
PWM_SetPrescaler(720-1); //Freq=72M/(PSC+1)/100
PWM_SetCompare(10); //Duty=CCR/100
while(1)
{
OLED_ShowNum(1,6,IC_GetFreq(),5);
OLED_ShowNum(2,6,IC_GetDuty(),2);
}
}
到了这里,关于STM32——输入捕获IC(测试频率以及PWMI测试频率占空比)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!