STM定时器的PWM输入捕获

#程序员成长:技术、职场与思维模式实战指南#

一、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,则频率等于 f_{x}=N/T

测周法:两个上升沿内,以标准频率f_{c}计次,得到N ,则频率对于f_{x}=f_{c}/N

中界频率:测频法与测周法误差相等的频率点  f_{m}=\sqrt{f_{c}/T}

当待测频率大于中界频率是采用测频法,反之使用测周法。

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

 
  1.  

    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
    }

AI写代码

 
分频器配置,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初始代码及其他代码配置

#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_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);//分别读取1通道的CCR,标准频率=72M/预分频系数psc,频率=fc/N
}

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) 数为了得到测频法中的频率f_{x}。其中涉及到的函数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);


}

}

​​​​​​​

四、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

}

 占空比计算公式可以参考下图

4.2、完整代码

4.2.1、 void IC_Init(void)代码部分
 
4. 2.2、main 函数代码
 

 

输入捕获模式测频率、PWMI模式测频率和占空比。测频法利用之前的外设就可实现,如对射式红外传感器计次、定时器外部时钟等稍加改进就可!可自行实验,本次实操用的是测周法注:考虑到初学者可能没有信号发生器,我们借用了上一小节定时器输出比较产生PWM的代码在PA0产生信号波形!!如果有示波器的话,也可以测试验证下程序的结果是否正确。输出比较与输入捕获对比:1、输出比较引脚是输出端口,输入捕获引脚是输入端口。2、输出比较是根据CNT和CCR的大小关系来执行输出动作;

STM32 输入捕获模式测频率

Echo_cy_的博客

文章详细介绍了STM32中的输入捕获(IC)功能,包括其在频率测量和测周法中的应用,以及如何通过电路实现测周法。电路设计中包含了三输入异或门和滤波器,用于处理多个输入信号。主从触发模式用于自动测量周期,而PWMI模式则能同时测量频率和占空比。程序代码部分展示了输入捕获的相关函数配置,以及PWM和输入捕获的初始化和频率、占空比的测量

 

STM32输入捕获模式 本文详细介绍了STM32的输入捕获模式,用于测量脉冲宽度和频率。STM32定时器的输入捕获功能在检测到边沿信号时保存定时器值,可用于PWM输入捕获,通过捕获上升沿和下降沿计算时钟周期和占空比。文章还提供了程序设计思路和相关资源链接。 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了...

其核心作用是将定时器的内部事件或外部信号映射为触发信号(TRGI),进而控制从定时器的计数行为(如启动/停止/复位等)。​:单信号同时触发两个通道,分别捕获周期(CCR1)和占空比(CCR2)。A:否,一次只能选择一个触发源,但可通过分时复用或组合模式实现复杂功能。​:信号上升沿触发CNT复位,CCR直接存储周期计数值,无需计算差值。触发源信号(TRGI)输入至定时器的从模式控制器,通过配置。A:改用普通输入捕获模式(手动记录两次捕获值差值)。​:主定时器更新事件触发从定时器计数,扩展定时范围。

首先要明白一个知识:STM32的定时器输出的PWM的占空比由定时器的三个寄存器决定,分别是 定时器计数器TIMx_CNT; 定时器自动重装载寄存器TIMx_ARR; 定时器捕获/比较寄存器TIMx_CCRx; 定时器预分频器TIMx_PSC; CNT和CCRx的对占空比的影响: 对于本实验要满足的前提如下: ...

利用STM32的PWM输入捕获功能,可以测方波的占空比和(或)频率 使用时将相应的输入配置为对应定时器对应的复用功能,外部待测量波形从该引脚输入 再配置定时器输入捕获功能相应参数,选择主从模式,最后打开中断或者DMA读取测量数据 1. Enable TIM clock 2. Configure the TIM pins by configuring the corresponding GPIO pin...

要参考误差的要求,如果误差要求是千分之一,那么1M/1000=1KHz就是频率上限,误差要求是百分之一,那么1M/100=10KHz就是频率上限。所以可以测量的最低频率是1M/65535,大概是15Hz,频率再低,计数器值就要溢出了,所以可以测得的最低频率是15Hz。最大频率的上限是标准频率1MHz,但这时误差已经非常大了,这个上限没有参考意义,信号频率比标准频率还高,就测不了了。想要降低最低频率的限制,可以把这个预分频再加大一些,这样标准频率值更低,所支持的测得最低频率也更低。这里讨论一下测频率的性能。

项目资源包含:可运行源码+sql文件+LW; python3.8+django+mysql5.7+html 适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 本项目采用了深度学习技术,如卷积神经网络(CNN),用于图像特征提取;同时结合了图像处理库OpenCV,用于图像数据的预处理和后处理。系统实现了基于图像特征的相似图像检索、图像分类、目标检测等功能。通过提取图像的特征向量,不仅可以实现精准的图像搜索和分类,还能帮助用户快速准确地识别图像中的目标物体,具有较高的准确率和效率。通过本项目的设计与实现,可以有效解决在大数据环境下处理海量图像数据时面临的特征提取、图像分析和应用问题,为图像信息的挖掘与利用提供了新的途径和解决方案,具有广泛的应用前景和推广价值。 (1)特征提取模块:使用局部特征描述符(如SIFT、SURF)或深度学习特征提取方法,对海量图像中的特征进行抽取和表示,以便后续的相似度计算。 (2)相似图像搜索模块:用户上传查询图像或输入描述后,系统利用特征提取的结果进行相似图像检索,找出与查询图像最相似的图像,并返回给用户。 (3)标签搜索模块:系统对图像进行自动标签或标注,用户可以根据这些标签进行图像搜索,方便快速地找到感兴趣的内容。 (4)检索结果排序模块:根据图像的相关度或其他指标,系统对检索结果进行排序,确保用户看到最相关的图像在前面展示。 (5)图像分类模块:系统通过训练模型对图像进行分类,将其归入不同的类别,为用户提供更精细的检索和浏览功能。 (6)图像清晰度评估模块:系统可以评估图像的清晰度,排除模糊或质量较低的图像,提高搜索结果的质量和准确性。 (7)图像信息提取模块:系统可以提取图像中的关键信息,如物体、人脸等,为用户提供更多的图像认知和分析功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值