STM32的捕获模式应用
STM32Cube学习之八:输入捕获
STM32Cube学习之八:输入捕获假设已经安装好STM32CubeMX和STM32CubeF4支持包。
Step1.打开STM32CubeMX,点击“New Project”,选择芯片型号,STM32F407ZETx。
Step2. 在Pinout界面下配置晶振输入引脚。
配置TIM2使用内部时钟源,CH1作为输入捕获通道,默认映射到PA0引脚。
配置TIM3使用内部时钟,CH1~CH4为PWM输出通道,默认映射引脚分别为PA6,PA7,PB0,PB1。
配置TIM4使用内部时钟,CH1,CH2为PWM输出通道,映射引脚分别为PD12,PD13。
配置串口,作为信息输出接口。
Step3.在Clock Configuration界面配置时钟源。
使用外部8M晶振作PLL时钟输入,并使用PLL输出作为系统时钟。
为了后面的计算方便,将系统时钟配置成160MHz。
Step4.配置外设参数。
在configuration界面中点击TIM2/ TIM3/ TIM4按钮,可以进入参数配置界面。
TIM2:在Parameter Settings页配置预分频系数为7,其计数时钟就是80MHz/(7+1)=10MHz。
计数周期(自动加载值),转换为十六进制形式,输入32bit最大值0xFFFFFFFF。
注意,TIM2的自动加载寄存器ARR和各个通道的捕获/比较寄存器CCRx都是32bit的。
在NVIC页面使能捕获/比较中断。
在GPIO页面设置捕获输入引脚下拉电阻,设置成上拉也可以,主要是为了使在没有信号输入时在输入引脚上得到稳定的电平。
TIM3:在Parameter页配置预分频系数为7,计数周期(自动加载值)为9999。
其溢出频率就是80MHz/(7+1)/(9999+1)=1kHz,这就是TIM3各通道输出的PWM信号的频率。
各通道输出PWM的占空比参数如上图红框标注,其他参数使用默认值。
按照图中参数,CH1~CH4输出的PWM周期都是1ms,而高电平时间分别是123.4us,234.5us,567.8us,678.9us。
STM32(十八)输入捕获应用
STM32(⼗⼋)输⼊捕获应⽤
输⼊捕获⼀般应⽤在两个⽅⾯:
脉冲跳变沿时间测量
PWM输⼊测量
1、测量频率
当捕获通道TIx.上出现上升沿时,发⽣第⼀次捕获,计数器CNT的值会被锁存到捕获寄存器CCR中,⽽且还会进⼊捕获中断,在中断服务程序中记录⼀-次捕获(可以⽤⼀个标志变量来记录),并把捕获寄存器中的值读取到valuel 中。
当出现第⼆次上升沿时,发⽣第⼆次捕获,计数器CNT的值会再次被锁存到捕获寄存器CCR中,并再次进⼊捕获中断,在捕获中断中,把捕获寄存器的值读取到value3中,并清除捕获记录标志。
利⽤value3和valuel的差值我们就可以算出信号的周期(频率)。
2、测量脉宽
当捕获通道TIx.上出现上升沿时,发⽣第⼀次捕获,计数器CNT的值会被锁存到捕获寄存器CCR中,⽽且还会进⼊捕获中断,在中断服务程序中记录⼀次捕获(可以⽤⼀个标志变量来记录),并把捕获寄存器中的值读取到valuel 中。
然后把捕获边沿改变为下降沿捕获,⽬的是捕获后⾯的下降沿。
当下降沿到来的时候,发⽣第⼆次捕获,计数器CNT的值会再次被锁存到捕获寄存器CCR中,并再次进⼊捕获中断,在捕获中断中,把捕获寄存器的值读取到value3 中,并清除捕获记录标志。
然后把捕获边沿设置为上升沿捕获。
在测量脉宽过程中需要来回的切换捕获边沿的极性,如果测量的脉宽时间⽐较长,定时器就会发⽣溢出,溢出的时候会产⽣更新中断,我们可以在中断⾥⾯对溢出进⾏记录处理。
STM32输入捕获模式
STM32输入捕获模式
在输入捕获模式下,定时器将统计外部信号的上升沿或下降沿出现的
时间,并将统计结果保存在相关的寄存器中。
用户可以根据需要选择统计
上升沿还是下降沿,并可以选择计数溢出时是否复位计数器。
1.选择定时器和通道:根据实际需求选择合适的定时器和通道。
一般
来说,每个定时器都有多个通道可以配置为输入捕获模式。
2.配置定时器:根据测量的要求配置定时器的工作模式、计数方向和
预分频系数等。
定时器的配置将影响捕获的精度和测量范围。
3.配置输入捕获:选择捕获触发源,可以选择外部信号引脚或其他定
时器的输出作为触发源。
配置捕获触发源时还可以选择捕获的边沿类型
(上升沿或下降沿)和是否复位计数器。
4.开启定时器:配置完成后,通过使能相关的定时器和通道将输入捕
获模式启用。
5.捕获外部信号:当捕获触发源产生触发信号时,定时器将开始计数,当捕获到外部信号的边沿时,定时器会自动将计数值保存在指定的寄存器中。
6.读取测量结果:根据所选择的定时器和通道,从相关的寄存器中读
取测量结果,可以通过计算得到所需的参数,比如周期、脉宽等。
输入捕获模式在很多应用中都是非常常见且重要的。
例如在测量旋转
编码器的位置和速度时,可以使用输入捕获模式来捕获编码器的A相和B
相信号,并通过计算来确定位置和速度。
此外,输入捕获模式还可以用于
测量外部信号的频率、测量脉冲信号的宽度等。
总之,STM32输入捕获模式是一种功能强大且灵活的功能,能够帮助用户实现对外部信号的精确测量和控制。
通过合理配置和使用,可以满足各种不同的应用需求。
stm32PWM输入捕获
stm32PWM输入捕获tm32定时器pwm输入捕获输入捕捉的功能是记录下要捕捉的边沿出现的时刻,如果你仅仅捕捉下降沿,那么两次捕捉的差表示输入信号的周期,即两次下降沿之间的时间。
如果要测量低电平的宽度,你应该在捕捉到下降沿的中断处理中把捕捉边沿改变为上升沿,然后把两次捕捉的数值相减就得到了需要测量的低电平宽度。
如果要的测量低电平太窄,中断中来不及改变捕捉方向时,或不想在中断中改变捕捉方向,则需要使用PWM输入模式,或使用两个TIM某通道,一个通道捕捉下降沿,另一个通道捕捉上升沿,然后对两次捕捉的数值相减。
PWM输入模式也是需要用到两个通道。
使用两个通道时,最好使用通道1和通道2,或通道3和通道4,这样上述功能只需要使用一个I/O管脚,详细请看STM32技术参考手册中的TIM某框图。
//0-----------------------一、概念理解PWM输入捕获模式是输入捕获模式的特例,自己理解如下1.每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。
且IC1IC2一组,IC3IC4一组。
并且可是设置管脚和寄存器的对应关系。
2.同一个TI某输入映射了两个IC某信号。
3.这两个IC某信号分别在相反的极性边沿有效。
4.两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。
5.当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获“一个PWM周期(即连续的两个上升沿或下降沿)”,它等于包含TIM时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。
6.同样另一个捕获通道捕获触发信号和下一个相反极性的边沿信号的计数个数m,即(即高电平的周期或低电平的周期)7.由此可以计算出PWM的时钟周期和占空比了frequency=f(TIM时钟频率)/n。
dutycycle=(高电平计数个数/n),若m为高电平计数个数,则dutycycle=m/n若m为低电平计数个数,则dutycycle=(n-m)/n 注:因为计数器为16位,所以一个周期最多计数65535个,所以测得的最小频率=TIM时钟频率/65535。
理解STM32定时器中的输入捕获滤波器
理解STM32定时器中的输入捕获滤波器关于STM32定时器中的输入捕获滤波器的功能描述,在中文参考手册中描述如下:我不理解官方的说明,在网上搜了老半天,基本都是下面这几句话:1)当滤波器连续采样到N次个有效电平时,认为一次有效的输入电平。
2)该数字滤波器实际上是个事件计数器,它记录到N个事件后会产生一个输出的跳变。
例如:当f(CK_INT) = 72MHz, CKD[1:0] = 01时,选择f(DTS) = f(CK_INT)/2 = 36MHz;而ETF[3:0] = 0100,则采样频率f(SAMPLI NG) = f(DTS) / 2 = 18MHz, N = 6,此时高于3M Hz的信号将被这个滤波器滤除,这样就有效地屏蔽了高于3MHz的干扰。
看了这些说法,我还是不理解这个数字滤波器到底是如何工作的,问题如下:问题1:当滤波器连续采样到N次个有效电平时,是输出这个电平?还是输出一个跳变?问题2:当滤波器没有连续采样到N次个有效电平时,输出是的什么?带着这两个问题,我们来分析一下,下面以TIM3为例:首先可以肯定输入捕获过程如下:详细信息见参考手册中的14.2节,通用定时器框图TIM3_C H1(PA.6) ----> TI1(外部信号) -------> 输入滤波器I C1F[3:0] -----> IC1(滤波器输出信号) -------> 输入捕获预分频器IC1PSC[1:0] ----> 捕获/比较1寄存器CCR1从上面的过程可以知道,1)发生输入捕获所需要的跳变沿是由滤波器输出产生的。
2)滤波器和预分频器可软件编程,如果IC1F[3:0] = 0x0,则滤波器全通,即TI1 和IC1是同一个信号。
STM32利用捕获功能完成脉冲宽度测量
STM32利用捕获功能完成脉冲宽度测量STM32是一款常见的32位微控制器,它具有强大的功能和灵活性。
通过利用STM32的捕获功能,我们可以实现脉冲宽度测量。
下面是一个详细的说明,包括如何配置STM32的定时器和GPIO引脚,以及如何使用捕获功能进行脉冲宽度测量。
1.配置定时器和GPIO引脚:首先,我们需要配置定时器和GPIO引脚,以确保它们能够正常工作。
在STM32中,使用CubeMX可视化工具来配置硬件资源是一个比较方便的方法。
- 打开CubeMX工具,并选择你正在使用的STM32微控制器型号。
- 在"Pinout & Configuration"选项卡中,选择所需的GPIO引脚进行输入捕获。
将引脚配置为输入模式,并启用上拉或下拉电阻。
-在同一选项卡上,选择所需的定时器。
将其配置为捕获模式,并选择所需的输入通道。
- 在"Generated Code"选项卡中,点击"Project Firmware Structure"下的"Middlewares"文件夹,选择"TIM"文件夹,然后选择"TIM_HandleTypeDef"文件。
复制该文件到你的代码工程文件夹下。
2.配置捕获功能与中断处理函数:- 在自动生成的代码中,找到`HAL_TIM_IC_MspInit`函数。
在该函数中,初始化定时器和GPIO相关的寄存器。
-在主函数中,进行以下配置:```cuint32_t ICValue1 = 0;uint32_t ICValue2 = 0;uint32_t Difference = 0;TIM_HandleTypeDef htim2;```-初始化定时器和GPIO:```cvoid MX_TIM2_Init(void)TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_IC_InitTypeDef sConfigIC = {0};htim2.Instance = TIM2;htim2.Init.Prescaler = 0;htim2.Init.CounterMode = TIM_COUNTERMODE_UP;htim2.Init.Period = 0xFFFFFFFF;htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_IC_Init(&htim2);sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;sConfigIC.ICFilter = 0;HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim2,&sMasterConfig);```3.启动捕获功能和中断处理:```cvoid HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)if (ICValue1 == 0)ICValue1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);}else if (ICValue2 == 0)ICValue2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);if (ICValue2 > ICValue1)Difference = ICValue2 - ICValue1;}else if (ICValue1 > ICValue2)Difference = (0xFFFFFFFF - ICValue1) + ICValue2; }elseError_Handler(;}ICValue1 = 0;ICValue2 = 0;}}int main(void)HAL_Init(;SystemClock_Config(;MX_GPIO_Init(;MX_TIM2_Init(;HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); while (1)//主循环}```4.测试和读取脉冲宽度:通过使用上述代码配置和启动定时器和GPIO引脚后,STM32将能够使用捕获功能进行脉冲宽度测量。
STM32输入捕获的脉冲宽度及频率计算
STM32输入捕获的脉冲宽度及频率计算脉冲宽度的计算:脉冲宽度是指脉冲信号的高电平或低电平持续的时间。
在STM32中,定时器的输入捕获模式可以测量脉冲宽度。
输入捕获模式下,定时器会记录脉冲边沿的时间戳,可以通过计算时间戳之差来得到脉冲宽度。
具体的计算方法如下:1.配置定时器为输入捕获模式,并设置触发边沿(上升沿或下降沿)。
2.当捕获到脉冲边沿时,获取当前的定时器计数器值,作为开始时间戳。
3.当下一个脉冲边沿到来时,再次获取当前的定时器计数器值,作为结束时间戳。
4.计算时间戳之差,即为脉冲宽度。
脉冲频率的计算:脉冲频率是指单位时间内脉冲信号的个数。
脉冲频率的计算可以通过测量脉冲的周期来实现。
在STM32中,定时器的输入捕获模式可以测量脉冲的周期。
具体的计算方法如下:1.配置定时器为输入捕获模式,并设置触发边沿(上升沿或下降沿)。
2.当捕获到脉冲边沿时,获取当前的定时器计数器值,作为开始时间戳。
3.当接收到下一个脉冲边沿时,再次获取当前的定时器计数器值,作为结束时间戳。
4.计算时间戳之差,即为脉冲的周期。
5.频率等于周期的倒数。
需要注意的是,输入捕获功能只能测量单个脉冲的宽度和周期,如果要测量信号源的频率或平均脉冲宽度,需要根据测量的脉冲个数进行统计和计算。
以下是一个示例代码,演示了如何使用STM32的输入捕获功能计算脉冲宽度和频率:```c#include "stm32f4xx.h"//定义输入捕获相关的变量volatile uint32_t startTimestamp = 0;volatile uint32_t endTimestamp = 0;volatile uint32_t pulseWidth = 0;volatile uint32_t pulsePeriod = 0;volatile uint32_t pulseFrequency = 0;void TIM2_IRQHandler(void)if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)if (startTimestamp == 0)startTimestamp = TIM_GetCapture1(TIM2);} elseendTimestamp = TIM_GetCapture1(TIM2);pulseWidth = endTimestamp - startTimestamp;pulsePeriod = pulseWidth * 2;pulseFrequency = SystemCoreClock / pulsePeriod;startTimestamp = 0;}TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);}int main(void)//初始化定时器2TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_DeInit(TIM2);TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 设置计数器为向上计数模式TIM_TimeBaseInitStruct.TIM_Period = 0xFFFFFFFF; // 设置计数器的溢出值为最大值TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 设置时钟分割TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; // 设置重复计数值为0TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//配置输入捕获模式TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 选择定时器通道1TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; // 设置捕获参数,上升沿触发TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; // 设置输入映射,直接连接至TIM2_IC1管脚TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 设置输入分频,不分频TIM_ICInitStruct.TIM_ICFilter = 0; // 不开启滤波器TIM_ICInit(TIM2, &TIM_ICInitStruct);//开启输入捕获中断TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);//启动定时器2TIM_Cmd(TIM2, ENABLE);while (1)}```在上述示例代码中,定时器2被配置为输入捕获模式,通过TIM2的通道1测量脉冲输入。
STM32利用捕获功能完成脉冲宽度测量
数 TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//
直接映射到 TI1 TIM_ICInit<TIM5,&TIM_ICInitStructure>;
捕获程序
需要区分是捕获中断还是定时器更新中断 设置全局变量记录捕获状态和定时器更新
次数 在捕获到高电平后要改变捕获极性为低电
平捕获 如何更新中断发生次数超过记录极限,强制
设置捕获完成状态
知识回顾 Knowledge ReviewBiblioteka 如果使用TIM5和PA0作为捕获引脚
〔4开启捕获和定时器溢出〔更新中断 假如我们需要检测输入信号的高电平脉宽,就需
要在第一次上升沿到来时捕获一次,然后设置为 下降沿捕获,等到下降沿到来时又捕获一次.如 果输入信号的高电平脉宽比较长,那么定时器就 可能溢出,所以需要对定时器溢出进行处理,否 则计算的高电平时间将不准.所以需要开启定时 器溢出中断.
GPIO_Init<GPIOA,&GPIO_InitStructure>; //初 始化结构体
如果使用TIM5和PA0作为捕获引脚
〔2初始化定时器参数,包含自动重装值,分频系数,计数方式 等
要使用定时器功能,必须对定时器内相关参数初始化,其库 函数如下:
voidTIM_TimeBaseInit<TIM_TypeDef*TIMx,TIM_TimeBaseInit TypeDef*TIM_TimeBaseInitStruct>;
RCC_APB1PeriphClockCmd<RCC_APB1Periph_ TIM5,ENABLE>;//使能 TIM5 时
stm32f407通用定时器输入捕获
通用定时器输入捕获通用定时器作为输入捕获的使用。
我们用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽(用KEY_UP按键输入高电平),通过串口来打印高电平脉宽时间。
输入捕获模式可以用来测量脉冲宽度或者测量频率。
我们以测量脉宽为例,用一个简图来说明输入捕获的原理:如图所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中t1~t2时间,就是我们需要测量的高电平时间。
测量方法如下:首先设置定时器通道x为上升沿捕获,这样,t1时刻,就会捕获到当前的CNT值,然后立即清零CNT,并设置通道x为下降沿捕获,这样到t2时刻,又会发生捕获事件,得到此时的CNT值,记为CCRx2。
这样,根据定时器的计数频率,我们就可以算出t1~t2的时间,从而得到高电平脉宽。
在t1~t2之间,可能产生N次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。
如图所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以CNT的计数周期,即可得到t2-t1的时间长度,即高电平持续时间。
STM32F4的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。
STM32F4的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。
同时还可以配置捕获时是否触发中断/DMA等。
这里我们用TIM5_CH1来捕获高电平脉宽。
============================================================== =====================捕获/比较通道(例如:通道1 输入阶段)============================================================== =====================接下来介绍我们需要用到的一些寄存器配置,需要用到的寄存器:TIMx_ARR、TIMx_PSC、TIMx_CCMR1、TIMx_CCER、TIMx_DIER、TIMx_CR1、TIMx_CCR1 (这里的x=5)。
STM32利用捕获功能完成脉冲宽度测量解析
STM32利用捕获功能完成脉冲宽度测量解析脉冲宽度测量是一种常见的电子测量技术,它可以用来测量脉冲信号的时间间隔,常用于测量脉冲频率、PWM信号的占空比以及其他与时间相关的信号参数。
在STM32微控制器中,捕获功能可以使用定时器外设来实现。
定时器可以产生定时中断或者触发其他外设,同时,它还可以配置为捕获模式,以测量脉冲信号的时间间隔。
在使用STM32捕获功能进行脉冲宽度测量时,主要需要以下几个步骤:1.初始化定时器:选择合适的定时器外设,并根据具体需求配置计数模式、时钟源以及预分频系数。
需要注意的是,定时器的时钟源和预分频系数会影响测量的时间分辨率。
2.配置捕获模式:选择合适的输入通道,并配置捕获模式为边沿对齐模式或中心对齐模式。
边沿对齐模式适用于测量脉冲宽度,而中心对齐模式适用于测量脉冲间隔。
3.获取捕获值:在触发捕获事件时,通过读取捕获寄存器的值来获取脉冲宽度。
捕获值的单位由定时器的时钟源和预分频系数决定,通常为计数周期数。
4.计算脉冲宽度:根据捕获值和定时器的参数,可以计算出具体的脉冲宽度。
如果需要转化为实际的时间值,还需要考虑时钟源的频率和预分频系数。
在编写使用STM32捕获功能进行脉冲宽度测量的代码时,可以使用STM32Cube库或其他编写固件的开发工具。
以下是一个简单的示例代码:```c#include "stm32f4xx_hal.h"TIM_HandleTypeDef htim;void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)if (htim->Instance == TIM1) { // 根据实际情况修改定时器实例uint32_t captureValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);float pulseWidth = (float)captureValue / htim.Instance->ARR;//在这里进行脉冲宽度的处理}int main(void)HAL_Init(;SystemClock_Config(;__HAL_RCC_GPIOA_CLK_ENABLE(;__HAL_RCC_TIM1_CLK_ENABLE(;GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);htim.Instance = TIM1;htim.Init.Prescaler = 0;htim.Init.CounterMode = TIM_COUNTERMODE_UP;htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;HAL_TIM_Base_Init(&htim);TIM_IC_InitTypeDef sConfigIC;sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING;sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;sConfigIC.ICFilter = 0;HAL_TIM_IC_ConfigChannel(&htim, &sConfigIC, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim, TIM_CHANNEL_1);while (1)//主循环}```上述代码在初始化后,通过HAL库函数配置了一个TIM1定时器通道1的输入捕获模式,并启动了中断。
STM32输入捕获例程
刚刚开始做定时器输入捕获的时候在这个论坛上找了好久,都没有人分享,也有很多人问,无奈自己动手写了。
花了一天的时间,这个东西真的不好写了,对比了库的例子,仿真,等。
可以说付出了很多。
现在完成了和大家分享。
希望大家多多支持。
这个程序是在定时器输入捕获的基础上看手册完成的,程序说明:1、程序中定时器4的PB6用于输出频率为1K,占空比为50%的PWM信号。
2、定时器2的PA0用于输入捕获,当程序下到板子上,只有两个脚连在一起才会发生捕获。
3、串口用于发送捕获的值到PC机上。
4、定时器2的CCR1存PWM信号的频率,CCR2存高电平时间。
这里声明一下,如果你要捕获的PWM信号不在ARR,PSC计算的范围内,请自己先计算再使用本程序。
#include "stm32f10x_lib.h"#include "sys.h"#include "delay.h" //延时子函数#include "usart.h"u16 IC1Value;u16 IC2Value;u16 DutyCycle;u16 Frequency;void PWM_Init(u16 arr,u16 psc);void Capture_Init(u16 arr,u16 psc);int main(void){Stm32_Clock_Init(9); //系统时钟设置delay_init(72);//延时函数初始化uart_init(72,9600);PWM_Init(1000,72-1); //不分频。
PWM频率=72000/1440=5KhzCapture_Init(2000,72-1);while(1){Frequency = 1000000/IC1Value;DutyCycle = (IC2Value*100)/IC1Value;//占空比=(IC2Value/IC1Value)*100;printf("Frequency = %d\r\n",Frequency);printf("DutyCycle = %d\r\n",DutyCycle);printf("suqingxiao\r\n");}}//PWM输出初始化//arr:自动重装值//psc:时钟预分频数void PWM_Init(u16 arr,u16 psc){//此部分需手动修改IO口设置RCC->APB2ENR|=1<<0; //RCC->APB1ENR|=1<<2; //TIM4 时钟使能RCC->APB2ENR|=1<<3; //使能PORTB时钟GPIOB->CRL&=0XF0FFFFFF;//PB6 输出GPIOB->CRL|=0X0B000000;//复用功能输出GPIOB->ODR|=1<<6;//PB6 上拉TIM4->ARR=arr;//设定计数器自动重装值TIM4->PSC=psc;//预分频器不分频TIM4->CCMR1|=7<<4; //CH1 PWM2模式TIM4->CCMR1|=1<<3; //CH1 预装载使能TIM4->CCER|=1<<0; //OC1 输出使能TIM4->CR1=0x0080; //ARPE使能TIM4->CR1|=0x01; //使能定时器3TIM4->CCR1 = 500; //占空比初值=1440*50% =720 }void Capture_Init(u16 arr,u16 psc){//此部分需手动修改IO口设置RCC->APB2ENR|=1<<0; //RCC->APB1ENR|=1<<0; //TIM2 时钟使能RCC->APB2ENR|=1<<2; //使能PORTA时钟TIM2->ARR=arr; //设定计数器自动重装值//刚好1msTIM2->PSC=psc; //预分频器,GPIOA->CRL&=0XFFFFFFF0;//PA0 输出GPIOA->CRL|=0X00000004;//复用功能输出GPIOA->ODR|=1<<0;//PA0 上拉TIM2->SMCR|=0x00D4;//TIM2->SMCR|= 1<<5; //MSM=1 主/从模式//TIM2->SMCR|= 5<<4; //TS=101 触发选择//TIM2->SMCR|= 4<<0; //SMS=100 复位模式TIM2->CCMR1|=1<<0;//CC1S=01 选择输入端TIM2->CCMR1|=3<<4; //IC1F=0011配置输入滤波器TIM2->CCER|=0<<1; //CC1P=0 选择有效转换边沿上升沿有效TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中TIM2->CCMR1|=2<<8;//CC2S=10 选择输入端TIM2->CCER|=1<<5; //CC2P=1 选择有交转换边沿下降沿有效TIM2->CCER|=1<<4; //CC2E=1 允许捕获计数器的值到捕获寄存器中TIM2->DIER|=1<<1; //允许更新捕获中断TIM2->CR1|=0x01; //使能定时器2MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//抢占1,子优先级3,组2 }//定时器2中断服务程序void TIM2_IRQHandler(void){IC1Value = TIM2->CCR1;//读取CCR1也可以清CC1IF标志位IC2Value = TIM2->CCR2;//读取CCR1也可以清CC2IF标志位TIM2->SR&=~(1<<1);//清除中断标志位}。
STM32利用捕获功能完成脉冲宽度测量
STM32利用捕获功能完成脉冲宽度测量脉冲宽度测量是通过测量一个脉冲信号的高电平持续时间或低电平持续时间来获取其脉冲宽度的方法。
在STM32中,捕获功能可以通过输入捕获单元,结合计数器,实现对脉冲宽度的测量。
首先,我们需要配置STM32引脚为输入模式,将待测脉冲信号连接到该引脚上。
接下来,我们需要配置捕获单元和计数器。
捕获单元有多种模式可选,根据具体的需求选择适合的模式。
常用的模式有:1.输入捕获模式:用于测量脉冲的上升沿或下降沿的时间。
2.PWM输入捕获模式:用于测量脉冲信号的周期和占空比。
在本文中,我们将介绍如何使用输入捕获模式来测量脉冲宽度。
首先,我们需要配置计数器。
计数器用于计算脉冲信号的周期,可以选择16位或32位计数器,具体选择取决于需要测量的脉冲信号的频率。
配置计数器的时钟源和分频系数,以便适配脉冲信号的频率。
然后,将计数器进行清零。
接下来,我们需要配置输入捕获单元。
配置输入捕获模式和计数模式,以便捕获脉冲信号的上升沿或下降沿。
在每次捕获到脉冲信号的边沿时,输入捕获单元会自动将当前计数器的值保存到一个寄存器中,并将计数器清零。
我们可以通过读取寄存器的值来获取脉冲宽度。
在代码中,可以通过配置计数器、输入捕获单元和GPIO来实现脉冲宽度测量。
以下是一个基本的代码示例:```c#include "stm32fxxx.h"#include "stm32fxxx_gpio.h"#include "stm32fxxx_rcc.h"#include "stm32fxxx_tim.h"int main(void)//初始化GPIO和时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化定时器TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period = 0xFFFF;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//配置输入捕获单元TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInitStructure.TIM_ICFilter = 0x0;TIM_ICInit(TIM2, &TIM_ICInitStructure);//启动定时器TIM_Cmd(TIM2, ENABLE);while (1)//等待输入捕获事件发生while (TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1) == RESET);//读取输入捕获寄存器的值,即脉冲宽度uint16_t pulseWidth = TIM_GetCapture1(TIM2);//清除输入捕获事件标志位TIM_ClearFlag(TIM2, TIM_FLAG_CC1);}```上述代码示例使用了定时器2和GPIOA的0号引脚进行脉冲宽度测量。
用STM32触发捕捉实现高速高精度测频
c ou nt v a l u e a r e c a p t ur e d t o c h a nne l l ' s c a pt u r e c o m pa r e r e g i s t e r TI M 2 CCR1.I n or de r t o i m pr o ve e f f i c i e nc y of t he e n t i r e pr o gr a m ,t i me
H uang Chunpi ng (El e c t r oni c a nd I nf o r ma t i o n Eng i ne e r i ng, Zh on gs ha n Po l y t e c h ni c,Zho ng s ha n 52 8 4 04, Chi na) Ab s t r ac t :T h e p a pe r us e s ST M 3 2 F1 03 mi c r o c 0 nt r o 1 l e r t o a c hi e ve h i g h — s pe e d,h i g h— p r e c i s i on f r e q ue nc y me a s u r e me nt p r i n c i pl e s a nd me t h —
前预分频计数器 P S C — C NT 对 C E上 升 沿 进 行 上 行 计 数 ,
stm32 pwm输入捕捉模式学习笔记
stm32 pwm输入捕捉模式学习笔记(本文来自:android_chunhui的博客)PWM输入是输入捕获的一个特殊应用,输入捕获就是当连接到定时器的引脚上产生电平变化时对应的捕获装置会立即将当前计数值复制到另一个寄存器中。
你可以开启捕获中断然后在中断处理函数中读出保存的计数值。
主要用于读取pwm的频率和占空比。
与输入捕获不同的是PWM输入模式时,用到两个通道(一般用TIMx_CH1或TIMx_CH2),只给其中一个通道分配gpio时钟即可,另一个在内部使用。
给一个通道分配gpio时钟后,需要设置另一个为从机且复位模式。
(例如使用ch2,ch1就得设置成从机模式)。
当一个输入信号(TI1或TI2)来临时,主通道捕获上升沿,从机捕获下降沿。
假设pwm从低电平开始触发,当上升沿来临时,两个通道TIM_CNT均复位开始计数,下一个下降沿来临,从机读取TIM_CNT中的值,记为CCR1,下一个上升沿来临,主通道读取TIM_CNT的值,记为CCR2。
所以CCR2/f,为pwm周期,倒数即频率。
CCR1/CCR2就是占空比。
下面是pwm捕获模式下的配置:void Tim2_PWMIC_Init(void){TIM_ICInitTypeDef TIM_ICInitStructure;TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //***通道选择,通道一为从机TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //管脚与寄存器对应关系TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入预分频。
STM32输入捕获模式
输入捕获模式库函数例程位置:STM32F10x_StdPeriph_Lib_V3.3.0\Project\STM32F10x_StdPeriph_Examples\TIM\I nputCapture在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中。
当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。
在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。
PWM输入模式库函数例程位置:STM32F10x_StdPeriph_Lib_V3.3.0\Project\STM32F10x_StdPeriph_Examples\TIM\P WM_Input该模式是输入捕获模式的一个特例例如,你需要测量输入到TI1上的PWM信号的长度(TIMx_CCR1寄存器)和占空比(TIMx_CCR2寄存器),具体步骤如下(取决于CK_INT的频率和预分频器的值)● 选择TIMx_CCR1的有效输入:置TIMx_CCMR1寄存器的CC1S=01(选择TI1)。
● 选择TI1FP1的有效极性(用来捕获数据到TIMx_CCR1中和清除计数器):置CC1P=0(上升沿有效)。
● 选择TIMx_CCR2的有效输入:置TIMx_CCMR1寄存器的CC2S=10(选择TI1)。
● 选择TI1FP2的有效极性(捕获数据到TIMx_CCR2):置CC2P=1(下降沿有效)。
● 选择有效的触发输入信号:置TIMx_SMCR寄存器中的TS=101(选择TI1FP1)。
● 配置从模式控制器为复位模式:置TIMx_SMCR中的SMS=100。
● 使能捕获:置TIMx_CCER寄存器中CC1E=1且CC2E=1。
由于只有TI1FP1和TI2FP2连到了从模式控制器,所以PWM输入模式只能使用TIMx_CH1 /TIMx_CH2信号。
STM32HAL库学习系列第7篇---定时器TIM输入捕获功能
STM32HAL库学习系列第7篇---定时器TIM输⼊捕获功能测量脉冲宽度或者测量频率基本⽅法1.设置TIM2 CH1为输⼊捕获功能;2.设置上升沿捕获;3.使能TIM2 CH1捕获功能;4.捕获到上升沿后,存⼊capture_buf[0],改为捕获下降沿;5.捕获到下降沿后,存⼊capture_buf[1],改为捕获上升沿;6.捕获到上升沿后,存⼊capture_buf[2],关闭TIM2 CH1捕获功能;7.计算:capture_buf[2] - capture_buf[0]就是周期,capture_buf[1] - capture_buf[0]就是⾼电平所占时间。
时钟配置:引脚看是否需要上拉做项⽬中的⼀个例⼦:/*** 函数功能: TIM_IC配置* 输⼊参数: value* 返回值: ⽆* 说明: ⽆*/void user_ic_config(uint16_t value){TIM_IC_InitTypeDef sConfigIC;if(value != 0) //1{sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;//上升沿}else//0{sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; //下降沿}sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;sConfigIC.ICFilter = 0;HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);}/*** 函数功能: TIM_IC回调函数* 输⼊参数: htim* 返回值: ⽆* 说明: 得到转速*/void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){static uint32_t uwICValue;static uint32_t last_uwICValue;uint32_t uwDiffCapture;if ( ((htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)||(htim->Channel== HAL_TIM_ACTIVE_CHANNEL_4)) && (htim->Instance == TIM3) ) {pulseCntr++;last_uwICValue = uwICValue;uwICValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);if(HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_3) != HAL_OK) //开启定时器中断{}if (uwICValue > last_uwICValue){uwDiffCapture = (uwICValue - last_uwICValue); //脉冲宽度为前后两个周期相减}else if (uwICValue < last_uwICValue) //若超值{/* 0xFFFF is max TIM2_CCRx value */uwDiffCapture = ((0xFFFF - last_uwICValue) + uwICValue) + 1;}if(uwDiffCapture < 0x10000){middleCapture = uwDiffCapture; //脉冲宽度}pulsein_flag = 1; // 捕捉到标记}else if ( (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) && (htim->Instance == TIM2) ){if(uhCaptureIndex == 0){// 第⼀个脉冲,检测的是上升沿uwIC2Value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);uhCaptureIndex = 1;user_ic_config(0); //下降if(HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_1) != HAL_OK) //中断{}}else if(uhCaptureIndex == 1){uwIC2Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);uhCaptureIndex = 0;user_ic_config(1);//上升if(HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_1) != HAL_OK){}/* Capture computation */if (uwIC2Value2 > uwIC2Value1){uwDiffCapture = (uwIC2Value2 - uwIC2Value1); //脉冲宽度 }else if (uwIC2Value2 < uwIC2Value1){/* 0xFFFF is max TIM2_CCRx value */uwDiffCapture = ((40000 - uwIC2Value1) + uwIC2Value2) + 1; }RCin = uwDiffCapture/2; //删除}}}应⽤:1.脉冲时间测量2.电容按键使⽤。
STM32--输入捕获和输出比较
STM32--输⼊捕获和输出⽐较概述⾸先,明确⼀点对⽐AD的构造,stm32有3个AD, 每个AD有很多通道(⼀个外设可以有多个中断通道,但是每个中断通道只有⼀个外设),使⽤哪个通道就配置成哪个通道(只设置⽤⼀个就可以),这⾥定时器也如此,有很多定时器TIMx,每个定时器有很多CHx(通道),可以配置为输⼊捕捉-------测量频率⽤,也可以配置为输出⽐较--------输出PWM使⽤输⼊捕获输⼊捕捉:可以⽤来捕获外部事件,并为其赋予时间标记以说明此事件的发⽣时刻。
外部事件发⽣的触发信号由单⽚机中对应的引脚输⼊(对应的引脚设置成输⼊)(具体可以参考单⽚机的datasheet),也可以通过模拟⽐较器单元来实现。
时间标记可⽤来计算频率,占空⽐及信号的其他特征,以及为事件创建⽇志,主要是⽤来测量外部信号的频率。
1.1、朋友,可以解释⼀下输⼊捕获的⼯作原理不?很简单,当你设置的捕获开始的时候,cpu会将计数寄存器的值复制到捕获⽐较寄存器中并开始计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获。
它没多⼤⽤处,最常⽤来测频率。
1.2、计数寄存器的初值,是⾃⼰写进去的吗?是的,不过默认不要写⼊(即计数寄存器为零)1.3、我如果捕获上升沿,两个值相减,代表的时两个上升沿中间那段电平的时间。
对不?是的1.4、timer1有五个通道(对应五个IO引脚),在同⼀时刻,只能捕获⼀个引脚的值,对不?那是肯定的,通道很像ADC通道,是可以进⾏切换的。
输出⽐较输出⽐较:定时器中的计数寄存器在初始化完后会⾃动的计数,从bottom计数到top,并且有不同的⼯作模式。
另外,还有个⽐较寄存器。
⼀旦计数寄存器在从bottom到top 计数过程中与⽐较寄存器匹配(在计数的过程中进⾏⽐较,不单指bottom或top)则会产⽣⽐较中断(⽐较中断使能的情况下),这⾥的匹配指的是计数寄存器的值与⽐较寄存器的值相等。
STM32中采用DMA实现方波的产生和捕获
2 DMA和 TMx简 介 I
S TM3 2系 列 微 控 制 器 均 含 有 DMA 和 通 用 时 钟 TI Mx模 块 。其 低 端 型 号 中 仅 包 含 DMA1 支 持 7个 通 , 道 ; 端 型 号 还 包 括 DMA2 支 持 5个 通 道 。它 的 每 个 通 高 ,
—
e s f DM A G e I le i( tTSt t 8( a u DM A 1 T H T x) I ){
DM A
— —
TI M
—
I nt TI 2,& TI CI i( M M I nt tu t r) CIiS r cu e ;
Cl a l e r TPe ndigBi(DM A 1 I n t T H T x );
设 存 放 时 刻 值 的 缓 冲 长 度 为 N, 每 N 2个 点 才 中 断 一 则 / 次 , 样 C U就不需 要频 繁进 入 中断 , 行 效率 比较 高。 这 P 执
由此 也 可 以看 出 , 冲 越 大 , 中 断 响 应 的 实 时 性 要 求 也 缓 对 越 低 , 然 这 时 中 断 的 处 理 时 间 也 越 长 。 以 下 为 示 例 当 代码 :
一 — —
T D C l MA— T I—
D MA 的使 用 比 较 简 单 , 路 D A 仅 包 括 4个 寄 存 每 M 器 , 于指 定 D 用 MA 的 工 作 模 式 、 地 址 、 源 目标 地 址 和 传 输
次 数 。S 公 司 提 供 了很 好 的驱 动库 , 化 了外 设 的使 用 , T 简 方 便 阅读 和 移 植 。本 文 采 用 库 函 数 来 展 示 功 能 。
ppr m se.o .n投稿专用) ae@ entcm c( (
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32捕获模式应用。
1、stm32脉冲方波捕获脉冲方波长度捕获a)目的:基础PWM输入也叫捕获,以及中断配合应用。
使用前一章的输出管脚P B1(19脚),直接使用跳线连接输入的PA3(13脚),配置为TIM2_CH4,进行实验。
b)对于简单的PWM输入应用,暂时无需考虑TIM1的高级功能之区别,按照目前我的应用目标其实只需要采集高电平宽度,而不必知道周期,所以并不采用PWM 输入模式,而是普通脉宽捕获模式。
c)初始化函数定义:void TIM_Configuration(void); //定义TIM初始化函数d)初始化函数调用:TIM_Configuration(); //TIM初始化函数调用e)初始化函数,不同于前面模块,TIM的CAP初始化分为三部分——计时器基本初始化、通道初始化和时钟启动初始化:void TIM_Configuration(void)//TIM2的CAP初始化函数{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时器初始化结构TIM_ICInitTypeDef TIM_ICInitStructure; //通道输入初始化结构//TIM2输出初始化TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~F FFFTIM_TimeBaseStructure.TIM_Prescaler = 5; //时钟分频TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化//TIM2通道的捕捉初始化TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;//通道选择TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;//下降沿TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;/ /管脚与寄存器对应关系TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器TIM_ICInitStructure.TIM_ICFilter = 0x4; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xFTIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); //选择时钟触发源TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//触发方式TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE); //打开中断TIM_Cmd(TIM2, ENABLE); //启动TIM2f)RCC初始化函数中加入TIM时钟开启:RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM3, ENABLE);g)GPIO里面将输入和输出管脚模式进行设置。
IN_FLOATING,50MHz。
h)使用中断的话在NVIC里添加如下代码://打开TIM中断(与前一章相同)NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;i)简单应用:变量 = TIM_GetCapture4(TIM2);j)注意事项:i.由于我的需求只跟高电平宽度有关,所以避免了使用PWM输入模式,这样可以每个管脚捕捉一路信号。
如果使用PWM模式,每一路需要占用两个寄存器,所以一个定时器只能同时使用两路PWM输入。
ii.由于捕捉需要触发启动定时器,所以PWM输出与捕捉不容易在同一个TIM通道上实现。
如果必须的话只能增加计数溢出的相关代码。
iii.有些程序省略了捕捉通道的初始化代码,这是不对的iv.在基本计时器初始化代码里面注意选择适当的计数器长度,最好让波形长度不要长于一个计数周期,否则需要增加溢出代码很麻烦。
一个计数周期的长度计算跟如下几个参数有关:(1)RCC初始化代码里面的RCC_PCLKxConfig,这是TIM的基础时钟源与系统时钟的关系。
(2)TIM初始化的TIM_Period,这是计数周期的值(3)TIM初始化的TIM_Prescaler,这是计数周期的倍频计数器,相当于调节计数周期,可以使TIM_Period尽量大,提高计数精度。
2、使用STM32的TIMER捕获功能,求取输入PWM信号的周期,误差很大,请求解决!使用的是TIMER2的CH1通道,PWM信号接在PA0脚。
输入PWM的周期信号为100Hz,根据捕获值计算出来却是105Hz,这误差也太大了吧!!哪位高手知道是什么原因呀,指点一下呀,万分感谢呀!!下面是我的相关部分程序:1、时钟部分,TIMER2的时钟频率,我是初始化为36M.RCC_PCLK1Config(RCC_HCLK_Div2); //设置低速AHB时钟=系统时钟/2RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 倍频系数为9 PLLCLK=8*9=722、TIMER初始化TIM_DeInit(TIM2);TIM_TimeBaseStructure.TIM_Period = 65535;TIM_TimeBaseStructure.TIM_Prescaler = 18;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV4;TIM_ICInitStructure.TIM_ICFilter = 0x0;TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); //复位模式为从模式TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable); //使能主从模式TIM_Cmd(TIM2, ENABLE); //使能TIM2计数器TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); //使能CC2中断请求3、TIMER中断处理void TIM2_IRQHandler(void){/* Clear TIM2 Capture compare interrupt pending bit */TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);/* Get the Input Capture value */IC2_Value = TIM_GetCapture2(TIM2);3、STM32 TIM输入捕获模式记录调试的过程中,总能遇到一些问题,很庆幸能遇到那么多的问题,也许这就是最好的学习过程:继续我的笔记:在main函数中,文件名:main.c对TIM2的CH1,CH2配置如下:TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP; //配置为输入捕获模式TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择通道1TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //输入上升沿捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 通道方向选择TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //每次检测到捕获输入就触发一次捕获TIM_ICInitStructure.TIM_ICFilter = 0x0; //TIM_ICInit(TIM2, &TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP; //配置为输入捕获模式TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //选择通道2TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //输入上升沿捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 通道方向选择TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //每次检测到捕获输入就触发一次捕获TIM_ICInitStructure.TIM_ICFilter = 0x0; //TIM_ICInit(TIM2, &TIM_ICInitStructure);TIM1->PSC = 10; //由于要测量的信号频率为200-1000HZ 采取10倍的预分频TIM2->PSC = 10; //如果不分频最小的频率为1100hz,分频后可以测量的频率为110HZ,为了达到最佳捕捉效果,且满足要求建议分频系数设为6;/* Select the TIM2 Input Trigger: TI2FP2 【输入触发源选择】*/TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1); //参考TIM结构图选择滤波后的TI2输入寄存器SMCR/* Select the slave Mode: Reset Mode */TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset); //复位模式-选中的触发输入(TRGI)的上升沿初始化计数器,并且产生一个更新线号/* Enable the Master/Slave Mode */TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable); / /主从模式选择说说我要测量两路信号频率的思路吧:我想把两路信号跟别加到TIM2的CH1跟CH2上面去,然后通过TI1FP1跟TI 2FP2轮流触发,TIM2->CCR1与TIM2->CCR2记录下来的数据就是信号的周期,接着根据具体的情况计算出信号的频率。