STM32Cube学习之八:输入捕获

合集下载

STM32PWM输入捕获模式源码

STM32PWM输入捕获模式源码

STM32PWM输入捕获模式源码void TIM5_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//GPIO配置GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = 60000; //周期0~FFFFTIM_TimeBaseStructure.TIM_Prescaler = 22; //时钟分频,分频数为5+1即6分频TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;//模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;//NVIC配置NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);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输入捕获模式

STM32输入捕获模式

STM32输入捕获模式
在输入捕获模式下,定时器将统计外部信号的上升沿或下降沿出现的
时间,并将统计结果保存在相关的寄存器中。

用户可以根据需要选择统计
上升沿还是下降沿,并可以选择计数溢出时是否复位计数器。

1.选择定时器和通道:根据实际需求选择合适的定时器和通道。

一般
来说,每个定时器都有多个通道可以配置为输入捕获模式。

2.配置定时器:根据测量的要求配置定时器的工作模式、计数方向和
预分频系数等。

定时器的配置将影响捕获的精度和测量范围。

3.配置输入捕获:选择捕获触发源,可以选择外部信号引脚或其他定
时器的输出作为触发源。

配置捕获触发源时还可以选择捕获的边沿类型
(上升沿或下降沿)和是否复位计数器。

4.开启定时器:配置完成后,通过使能相关的定时器和通道将输入捕
获模式启用。

5.捕获外部信号:当捕获触发源产生触发信号时,定时器将开始计数,当捕获到外部信号的边沿时,定时器会自动将计数值保存在指定的寄存器中。

6.读取测量结果:根据所选择的定时器和通道,从相关的寄存器中读
取测量结果,可以通过计算得到所需的参数,比如周期、脉宽等。

输入捕获模式在很多应用中都是非常常见且重要的。

例如在测量旋转
编码器的位置和速度时,可以使用输入捕获模式来捕获编码器的A相和B
相信号,并通过计算来确定位置和速度。

此外,输入捕获模式还可以用于
测量外部信号的频率、测量脉冲信号的宽度等。

总之,STM32输入捕获模式是一种功能强大且灵活的功能,能够帮助用户实现对外部信号的精确测量和控制。

通过合理配置和使用,可以满足各种不同的应用需求。

理解STM32定时器中的输入捕获滤波器

理解STM32定时器中的输入捕获滤波器

理解STM‎32定时器‎中的输入捕‎获滤波器关于STM‎32定时器‎中的输入捕‎获滤波器的‎功能描述,在中文参考‎手册中描述‎如下:我不理解官‎方的说明,在网上搜了‎老半天,基本都是下‎面这几句话‎:1)当滤波器连‎续采样到N‎次个有效电‎平时,认为一次有‎效的输入电‎平。

2)该数字滤波‎器实际上是‎个事件计数‎器,它记录到N‎个事件后会‎产生一个输‎出的跳变。

例如:当f(CK_IN‎T) = 72MHz‎, CKD[1:0] = 01时,选择f(DTS) = f(CK_IN‎T)/2 = 36MHz‎;而ETF[3:0] = 0100,则采样频率‎f(SAMPL‎I NG) = f(DTS) / 2 = 18MHz‎, N = 6,此时高于3‎M Hz的信‎号将被这个滤‎波器滤除,这样就有效‎地屏蔽了高‎于3MHz‎的干扰。

看了这些说‎法,我还是不理‎解这个数字‎滤波器到底‎是如何工作‎的,问题如下:问题1:当滤波器连‎续采样到N‎次个有效电‎平时,是输出这个‎电平?还是输出一‎个跳变?问题2:当滤波器没‎有连续采样‎到N次个有‎效电平时,输出是的什‎么?带着这两个‎问题,我们来分析‎一下,下面以TI‎M3为例:首先可以肯‎定输入捕获‎过程如下:详细信息见‎参考手册中‎的14.2节,通用定时器‎框图TIM3_‎C H1(PA.6) ----> TI1(外部信号) -------> 输入滤波器‎I C1F[3:0] -----> IC1(滤波器输出‎信号) -------> 输入捕获预‎分频器IC‎1PSC[1:0] ----> 捕获/比较1寄存‎器CCR1‎从上面的过‎程可以知道‎,1)发生输入捕‎获所需要的‎跳变沿是由‎滤波器输出‎产生的。

2)滤波器和预‎分频器可软‎件编程,如果IC1‎F[3:0] = 0x0,则滤波器全‎通,即TI1 和IC1是同‎一个信号。

PWM输入捕获学习笔记

PWM输入捕获学习笔记

2016.4.17PWM 输入 ◆ STM32 输入捕获工作过程(通道1为例)一句话总结工作过程:通过检测TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。

● 步骤1:设置输入捕获滤波器(TIMx 捕获/比较模式寄存器 1 (TIMx_CCMR1))位 7:4 IC1F :输入捕获 1 滤波器 (Input capture 1 filter)此位域可定义 TI1 输入的采样频率和适用于 TI1 的数字滤波器带宽。

数字滤波器由事件计数器组成,每 N 个事件才视为一个有效边沿:0000:无滤波器,按 fDTS 频率进行采样1000:fSAMPLING=fDTS/8, N=60001: fSAMPLING=fCK_INTN=21001: fSAMPLING=fDTS/8, N=80010: fSAMPLING=fCK_INTN=41010: fSAMPLING=fDTS/16, N=50011: fSAMPLING=fCK_INTN=81011: fSAMPLING=fDTS/16, N=60100: fSAMPLING=fDTS/2N=61100:fSAMPLING=fDTS/16,N=80101: fSAMPLING=fDTS/2N=8 1101: fSAMPLING=fDTS/32,N=50110: fSAMPLING=fDTS/4N=6 1110: fSAMPLING=fDTS/32, N=6 0111: fSAMPLING=fDTS/4N=8 1111: fSAMPLING=fDTS/32, N=8注意:在当前硅版本中,当ICxF[3:0]= 1、 2 或 3 时,将用CK_INT 代替公式中的f DTS。

●步骤2:设置输入捕获极性 (TIMx 捕获/比较使能寄存器(TIMx_CCER))CC1 通道配置为输出:0: OC1 高电平有效1: OC1 低电平有效CC1 通道配置为输入:该位选择是IC1还是IC1的反相信号作为触发或捕获信号00:非反相/上升沿触发10:保留,不使用此配置。

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测量脉冲输入。

基于STM32CubeMX配置PWM输出和输入捕获

基于STM32CubeMX配置PWM输出和输入捕获

基于STM32CubeMX配置PWM输出和输⼊捕获PWM输出和输⼊捕获1、试验⽬标 1.输出2路PWM脉冲信号 2.捕获1路PWM脉冲信号 本次试验会使⽤到2个定时器,⼀个⾼级定时器⽤于脉冲捕获,⼀个普通定时器⽤于PWM脉冲输出。

2、准备材料 1. STM32F103C8 2. STM32CubeMX2、STM32CubeMX配置 2.1时钟树 系统时钟为72M,APB1 和APB2 的定时器时钟都为72MHZ。

2.2 PWM输出配置 PWM的输出配置⽐较简单,这⾥我们使⽤到了TIM2普通定时器控制输出,具体参数如下图。

在 Parameter Settings 页配置预分频系数为 72-1,计数周期(⾃动加载值)为 10000-1,定时器溢出频率,即PWM的周期,就是72MHz/(71+1)/(9999+1) = 100Hz 2.3 PWM输⼊捕获配置 PWM捕获,本次试验使⽤到了STM32F103C8的⾼级定时器TIM1。

配置如下图。

中断配置勾线这⾥,因为我们需要使⽤中断回调函数来计算频率占空⽐。

2.4 配置中断分组和中断使能2.5串⼝输出2.6⽣成⼯程 这⾥选择分离C.h⽂件,IDE 根据⾃⼰的环境选择,这⾥我使⽤的GUN编译⽅式的IDE所以选择了SW4SEM32。

以上CubeMX的PWM配置就完成了。

配置完毕后,⽣成⼯程打开。

下⾯我们来分析代码和如何使⽤。

3、代码实现 3.1 tim.c 该代码主要配置了Tim1 和Tim2 的相关配置,为什么要这么配置,在接下来的第4⼤点会详细说明。

这⾥主要了解HAL_TIM_IC_CaptureCallback 捕获中断回调函数这⾥函数主要处理计算占空⽐和频率。

/********************************************************************************* @file tim.c* @brief This file provides code for the configuration* of the TIM instances.******************************************************************************* @attention** <h2><center>© Copyright (c) 2021 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* /licenses/BSD-3-Clause********************************************************************************//* Includes ------------------------------------------------------------------*/#include "tim.h"/* USER CODE BEGIN 0 *//// 计算占空⽐时使⽤__IO uint16_t IC2Value = 0;__IO uint16_t IC1Value = 0;__IO float DutyCycle = 0;__IO float Frequency = 0;/* USER CODE END 0 */TIM_HandleTypeDef htim1; // ⾼级定时器捕获PWMTIM_HandleTypeDef htim2; // 普通定时器输出PWM/* TIM1 init function */void MX_TIM1_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_SlaveConfigTypeDef sSlaveConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_IC_InitTypeDef sConfigIC = {0};htim1.Instance = TIM1;htim1.Init.Prescaler = 72-1;htim1.Init.CounterMode = TIM_COUNTERMODE_UP; /* 计数⽅式上计数 */htim1.Init.Period = 65535; /* 计数器更新上限值 */htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; /* 采样时钟分频 */htim1.Init.RepetitionCounter = 0; /* 重装值=0 */htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* ⾃动装载值软件使能 */ if (HAL_TIM_Base_Init(&htim1) != HAL_OK) /* 初始定时器 */{Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; /* 内部时钟源 */if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK){Error_Handler();}if (HAL_TIM_IC_Init(&htim1) != HAL_OK){Error_Handler();}///选择从模式: 复位模式sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; /* 选择定时器输⼊触发: TI1FP1 */ sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;sSlaveConfig.TriggerFilter = 0;if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK){Error_Handler();}///IC1捕获上升沿触发 TI1FP1sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;sConfigIC.ICFilter = 0;if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}///IC2捕获下降沿捕获 TI1FP2sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK){Error_Handler();}}/* TIM2 init function */void MX_TIM2_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};htim2.Instance = TIM2;/** htim2.Init.Prescaler 分频计算* 定时器时钟源TIMxCLK = 2 * PCLK1* PCLK1 = HCLK / 2* => TIMxCLK = HCLK/2 = SystemCoreClock / 2 *2=72MHz (APB1)* 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=10KHz* */htim2.Init.Prescaler = 72-1;htim2.Init.CounterMode = TIM_COUNTERMODE_UP; /* 计数⽅式上升沿有效 */htim2.Init.Period = 10000-1; /* 累计 TIM_Period个后产⽣⼀个更新或者中断当定时器从0计数到10000,即为10000次,为⼀个定时周期*/ htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;if (HAL_TIM_Base_Init(&htim2) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; /* 内部时钟源 */if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_Init(&htim2) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK){Error_Handler();}///PWM模式配置sConfigOC.OCMode = TIM_OCMODE_PWM1; /* 配置为PWM模式1*/sConfigOC.Pulse = 5000; /* 默认占空⽐为50%*/sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; /* 当定时器计数值⼩于CCR1_Val时为⾼电平*/sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) /* 配置PWM通道*/{Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK){Error_Handler();}HAL_TIM_MspPostInit(&htim2); /* 外置GPIO初始化 */}void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle){GPIO_InitTypeDef GPIO_InitStruct = {0};if(tim_baseHandle->Instance==TIM1){/* USER CODE BEGIN TIM1_MspInit 0 *//* USER CODE END TIM1_MspInit 0 *//* TIM1 clock enable */__HAL_RCC_TIM1_CLK_ENABLE(); /*定时器时钟使能*/__HAL_RCC_GPIOA_CLK_ENABLE(); /*GPIO时钟使能*//**TIM1 GPIO ConfigurationPA8 ------> TIM1_CH1*/GPIO_InitStruct.Pin = GPIO_PIN_8; /* 36脚的F103 不能改变引脚编号*/GPIO_InitStruct.Mode = GPIO_MODE_INPUT; /* 输⼊模式*/GPIO_InitStruct.Pull = GPIO_NOPULL; /* ⽆上下拉*/HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* TIM1 interrupt Init */HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 0); /* 配置中断分组*/HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); /* 使能中断*//* USER CODE BEGIN TIM1_MspInit 1 *//* USER CODE END TIM1_MspInit 1 */}else if(tim_baseHandle->Instance==TIM2){/* USER CODE BEGIN TIM2_MspInit 0 *//* USER CODE END TIM2_MspInit 0 *//* TIM2 clock enable */__HAL_RCC_TIM2_CLK_ENABLE();/* USER CODE BEGIN TIM2_MspInit 1 *//* USER CODE END TIM2_MspInit 1 */}}void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle){GPIO_InitTypeDef GPIO_InitStruct = {0};if(timHandle->Instance==TIM2){/* USER CODE BEGIN TIM2_MspPostInit 0 *//* USER CODE END TIM2_MspPostInit 0 */__HAL_RCC_GPIOA_CLK_ENABLE();/**TIM2 GPIO ConfigurationPA0-WKUP ------> TIM2_CH1PA1 ------> TIM2_CH2*/GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; /* 这⾥定义了2路PMW输出⽤PA0 和PA1*/ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN TIM2_MspPostInit 1 *//* USER CODE END TIM2_MspPostInit 1 */}}void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle){if(tim_baseHandle->Instance==TIM1){/* USER CODE BEGIN TIM1_MspDeInit 0 *//* USER CODE END TIM1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_TIM1_CLK_DISABLE();/**TIM1 GPIO ConfigurationPA8 ------> TIM1_CH1*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);/* TIM1 interrupt Deinit */HAL_NVIC_DisableIRQ(TIM1_CC_IRQn);/* USER CODE BEGIN TIM1_MspDeInit 1 *//* USER CODE END TIM1_MspDeInit 1 */}else if(tim_baseHandle->Instance==TIM2){/* USER CODE BEGIN TIM2_MspDeInit 0 *//* USER CODE END TIM2_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_TIM2_CLK_DISABLE();/* USER CODE BEGIN TIM2_MspDeInit 1 *//* USER CODE END TIM2_MspDeInit 1 */}}/* USER CODE BEGIN 1 *//*** @brief Conversion complete callback in non blocking mode 捕获回调函数* @param htim : hadc handle* @retval None*/void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){/* 获取输⼊捕获值 */IC1Value = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);IC2Value = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_2);if (IC1Value != 0){/* 占空⽐计算 */DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);/* 频率计算 */Frequency = 72000000/72/(float)(IC1Value+1);}else{DutyCycle = 0;Frequency = 0;}}}/* USER CODE END 1 *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/3.2 main.c ⽤于计算的变量//计算占空⽐时的全局表变量extern __IO uint16_t IC2Value;extern __IO uint16_t IC1Value;extern __IO float DutyCycle;extern __IO float Frequency; 使能和输出PWM/// 使能捕获/⽐较2中断请求HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);/// 开始输出PWMHAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); 打印调试输出while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */printSwo("IC1Value =",IC1Value,LINE_FEED_EN);printSwo("IC2Value =",IC2Value,LINE_FEED_EN);printSwo("占空⽐:",DutyCycle,LINE_FEED_EN);printSwo("频率:",Frequency,LINE_FEED_EN);HAL_Delay(500);}3.3 输出结果短接任意⼀路输出 PA0与PA8 PWM输出与捕获,或 PA1与PA8 PWM输出与捕获。

输入捕获总结

输入捕获总结

输入捕获实验捕获是如何实现的?与定时器有什么关系?它为什么就能够捕获到呢?先入为主:可以利用定时器捕获某些IO口的高电平脉宽,脉宽时间可以通过串口打印得到。

输入捕获模式可以用来测量脉冲宽度或者测量频率。

STM32定时器除了TIM6和TIM7,其他的都具有输入捕获功能。

STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。

捕获模式与比较模式的理解:捕获模式的原理是选定的输入引脚发生选定的脉冲出发沿的时候,则该时刻定时器的计数值TIMx_CNT将被保存,同时产生中断(TIMx_CNT的值不会与任何东西进行比较)。

该功能最常用的的就是测量一个外来脉冲的脉宽。

比较模式的原理是当CCRx寄存器中设定的值与定时器计数器值相等的时候,相关引脚发生电平跳变,同时产生中断。

该功能常应用于产生一个一定脉宽的PWM波形。

数字滤波器由一个事件计数器组成,它记录到N个事件后会产生一个输出的跳变:这个N 可以取值具体参考中文手册,意思是说:我采样高电平,只有连续采样到N个电平是高电平的话我才认为是有效的高电平,低于N个我就认为是无效的。

PWM输入捕获模式是输入捕获模式的特例,自己理解如下1. 每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。

且IC1 IC2一组,IC3 IC4一组。

并且可是设置管脚和寄存器的对应关系。

2. 同一个TIx输入映射了两个ICx信号。

3. 这两个ICx信号分别在相反的极性边沿有效。

4. 两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。

5. 当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获“一个PWM周期(即连续的两个上升沿或下降沿)”,它等于包含TIM时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。

STM32Cube学习之八:输入捕获

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。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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。

在GPIO页面配置相关引脚的特性。

TIM4:在Parameter页配置预分频系数为7,计数周期(自动加载值)为999。

其溢出频率就是80MHz/(7+1)/(999+1)=10kHz,这就是TIM4各通道输出的PWM信号的频率。

各通道输出PWM的占空比参数如上图红框标注,其他参数使用默认值。

CH1,CH2输出的PWM周期都是100us,而高电平时间分别是23.4us,56.7us。

在GPIO页面配置相关引脚的特性。

串口参数配置,使用默认值即可。

Step5.生成源代码。

点击生成源代码按钮。

在设置界面中输入工程名,保存路径,工程IDE类型,点OK即可。

生成代码完成后可直接打开工程。

弹出如下对话框时,如果已经安装了F4的支持包,则点击OK关闭。

如果没有安装,则点击界面中的/...链接,找到芯片的支持包,然后安装。

关闭后面的界面。

点击“是”,然后选择芯片型号。

可以在搜索框中输入关键字,加快选择速度。

Step6.添加功能代码。

先在main.c文件用户代码区输入包含标准输入输出头文件。

在用户代码区4实现标准输出printf()的底层驱动函数fputc(),功能是在UART1输出一个字符。

在主函数前面的用户代码区0,定义一些全局变量。

在while(1)之前的用户代码区2,使能TIM3、TIM4的各个通道PWM输出。

在while(1)中的用户代码区3,写入TIM2 CH1通道的输入捕获控制和数据处理。

在main文件的用户代码区4,写入TIM2输入捕获中断处理回调函数。

至此,工程完成。

功能是使用TIM的输入捕获功能,实现对PWM信号的周期和占空比测量,并将数据通过串口发送出去。

用杜邦线将PA0和其他PWM信号输出脚相连,即可测量信号的周期,高电平所占时间,以及占空比,在串口1会输出这些信息。

输出信息示例如下:
Cycle:1.0000ms
High :0.1234ms
Duty :12.3%
Cycle:0.1000ms
High :0.0567ms
Duty :56.7%
按照本例的配置,测量精度是0.1us,测量信号周期范围是0~0xFFFFFFFF*0.1us,即0~429.4967295秒
测量基本思路是:
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]就是高电
平所占时间。

特别说明:
printf()函数的详细使用方法可到网上查找,在此仅解释本例的语句。

printf("Cycle:%.4fms\r\n", pwm_cycle/10000.0);
其中“%f”是输出浮点数的格式,加了“.4”就是保留4位小数。

pwm_cycle是32bit无符号整形,除以10000.0就是先将其变成小数,在除以10000。

printf("Duty :%.1f%%\r\n", duty/10.0);
因为%在printf()函数的格式转换中是格式转换的特殊符号,因此要打印一个“%”时,就要写成“%%”。

HAL_TIM_PWM_Start()函数用于使能定时器某一通道的PWM输出。

HAL_TIM_IC_Start_IT()函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断。

对应的HAL_TIM_IC_Stop_IT()函数和其功能相反,是关闭定时器某一通道的输入捕获功能和相应中断。

__HAL_TIM_SET_CAPTUREPOLARITY不是函数,而是底层操作的一个宏定义。

在stm32f4xx_hal_tim.h文件中可以找到。

其作用是修改定时器某一通道的输入捕获极性。

__HAL_TIM_GET_COMPARE也是一个宏定义。

在stm32f4xx_hal_tim.h文件中可以找到。

其作用是获取定时器某一通道的捕获/比较寄存器值。

根据我使用CubeMX开发的经验,发现HAL库并没有把所有的操作都封装成函数。

对于底层的寄存器操作(如本例中的读取捕获/比较寄存器),还有修改外设的某个配置参数(如本例中的改变输入捕获的极性),HAL库会使用宏定义来实现。

而且会用__HAL_作为这类宏定义的前缀。

获取某个参数,宏定义中一般会有_GET,而设置某个参数的,宏定义中就会有_SET。

在开发过程中,如果遇到寄存器级别或者更小范围的操作时,可以到该外设的头文件中查找,一般都能找到相应的宏定义。

官方例程请参考stm32cubef4.zip解压后
STM32Cube_FW_F4_V1.11.0\Projects\STM324xG_EVAL\Examples\TIM\TIM_InputCapture目录下的工程。

S.D.Lu 于深圳
2016年8月。

相关文档
最新文档