STM32F4系列HAL库配置定时器实验——输入捕获

发布者:BlissfulAura最新更新时间:2022-10-18 来源: csdn关键字:STM32F4系列  定时器  输入捕获 手机看文章 扫描二维码
随时随地手机看文章

输入捕获简单讲解

输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量周期和频率为例,用一个简图来说明输入捕获的原理

在这里插入图片描述

假定定时器工作在向上计数模式,

图中 t1~t2 时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道 x 为上升沿捕获,这样,t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。这样,根据定时器的计数频率,我们就可以算出 t1~t2 的时间,从而得到高电平脉宽。


在 t1~t2 之间,可能产生 N 次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图15.1.1所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。


输入捕获的原理,我们就介绍到这。

STM32F4 的定时器,除了 TIM6 和 TIM7(这些是基本定时器),其他定时器都有输入捕获功能。STM32F4 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。

在这里插入图片描述

你可以用输入捕获通道来检测信号发生器的,也可以用其他定时器输出PWM。


PWM

我记得PWM我是没有写的,这里简单提一下,其实就是再之前定时器配置的时候加一个CCR,通过ARR与CCR的值的比较选择引脚输出高低电平。

在这里插入图片描述

如下图:

在这里插入图片描述

我们在配置PWM时无非就是在CUBEmx里多了一个Pulse(脉宽)设置:

在这里插入图片描述

PULSE我设置为5,为ARR+1的一半,那么占空比为50%。

图中选择的是PWM1模式,即小于CCR时输出高电平,其余默认即可:

使能CCR寄存器的预装载功能

关闭快速输出模式

输出有效电平为高电平

在这里插入图片描述

由于STM32F4的最大时钟频率为84Mhz,那么,我设置的PWM的频率为84000000/(84*(9+1))=100KHZ,周期为1/100000s。


通用定时器可以用来输入捕获,我们用通用定时器即可

在这里插入图片描述

输入捕获HAL库配置

我们用两个定时器,一个用来输出PWM,一个用来输入捕获。

1.选芯片就不用我多说了,我选择的是STM32F401CCU6,因为我在Clion上编写时用F4很方便,STlink直接烧写进去,不用我不停动BOOT设置。

在这里插入图片描述

2.配置时钟,串口,STM32F4CCU6可以达到最大84MHz的输出

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.配置生成PWM定时器以及输入捕获定时器

在这里插入图片描述

这里我用TIM3生成我之前提到的相同频率的PWM,一个定时器可以输出多通道的PWM,我们任选其一生成即可,使用内部时钟(打勾)

之后,我们用TIM2的通道1输入捕获,同样内部时钟打勾

在这里插入图片描述

参数设置如下:

在这里插入图片描述

别忘了我们还要使能中断,在中断里进行计算

在这里插入图片描述

点击代码生成即可。

个人还是强推Clion,不久前才接触,他的代码补全和界面都比较高大上,这里给大家稚晖君的教程优雅的嵌入式开发

还有一个我们院的大佬的教程CLION配置


相关代码

鉴于大部分社区里直接给的代码连解释都不解释一下,很影响我们新手学习,

看到陌生的代码,人一般都愣一下:

在这里插入图片描述

这里我把我之前学习的关于这部分函数的视频给大家:MOOC

明确一下我们要使用的函数:


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获回调函数

  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//输入捕获中断开启

  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//pwm定时器开启

  HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);//输入捕获中断关闭

  uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)


那我们怎么去测呢?我们读到的值是捕获到上升沿的计数值,连续读两次,相减的值就是这段时间的计数值,而我们时钟也是一整段时间的计数值,用总计数值84000000/diff,不就是频率吗?将这个频率倒过来就是信号周期。

在这里插入图片描述

整个过程用前后台编程的思想,分工,主函数里显示计算,中断里读值,读两下,算一下。我们设置两个标志位,用于相互判断,这里计算输出完后才能再次捕获,两次捕获完之后才能计算输出。并且两次捕获依次进行。根据这样我们设置变量。


/* USER CODE BEGIN PV */

uint32_t DIff=0;//差值

uint8_t CaptureIndex=0;//捕获标志位

uint8_t MeasureFlag=0;//测量计算标志位

uint32_t CapVal1=0;//捕获值1

uint32_t CapVal2=0;//捕获值2

/* USER CODE END PV */


接下来主函数while中


if(MeasureFlag==1)//测量位判断

{

   if(CapVal2>=CapVal1)//注意这里分两种情况

   {

       DIff=CapVal2-CapVal1;

   }

   else

   {

       DIff=((4294967295+1-CapVal1)+CapVal2);//这种情况在捕获值1在一个计数周期的结束,而捕获值2是下个计数周期的开始

   }

   UART_printf(&huart1,"DIFF=%.8frn",DIff/1.0);


    UART_printf(&huart1,"Period=%.8fsrn",DIff/84000000.0);

   UART_printf(&huart1,"Fred=%dHzrn",84000000/DIff);

   UART_printf(&huart1,"rn");

   MeasureFlag=0;//置位测量标志位

    HAL_Delay(1000);

    HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//再次开启下次捕获

}


  }


中断函数里捕获


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{

if(htim->Instance==TIM2)

{

    if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)//两次判断

    {

        if(CaptureIndex==0)//捕获标志位判断

        {

            CapVal1= HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//读捕获值1

            CaptureIndex=1;//捕获标志位=1

        }

        else if(CaptureIndex==1)//连续读值

        {

            CapVal2= HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);

            CaptureIndex=0;//捕获标志位置位

            MeasureFlag=1;//测量标志位置1

            HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);//关闭中断

        }

        else

        {

            Error_Handler();//错误处理

        }

    }

}

}


串口重定向里使用,因为Clion里没有使用之前的Microlib库,所以必须换一个函数来重定向,加入#include "stdio.h" #include "stdarg.h"

以及


/* USER CODE BEGIN 0 */

int UART_printf(UART_HandleTypeDef *huart, const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);


    int length;

    char buffer[128];


    length = vsnprintf(buffer, 128, fmt, ap);


    HAL_UART_Transmit(huart, (uint8_t *)buffer, length, HAL_MAX_DELAY);


    va_end(ap);

    return length;

}

/* USER CODE END 0 */


这个重定向代码很神奇,在MSP432里也可以使用,甚至我在用串口屏也是用到了,有机会研究一下,或者有大佬可以给我留言讲解一下。

在这里插入图片描述

之后我们根据cubemx里的图接线(PA0-PA6,usart-USB转TTL),直接烧录。

在这里插入图片描述

和我们TIM3的PWM的设置是一样的。

关键字:STM32F4系列  定时器  输入捕获 引用地址:STM32F4系列HAL库配置定时器实验——输入捕获

上一篇:STM32利用Flymcu进行烧录
下一篇:STM32F1基本定时器实验-外部触发脉冲计数

推荐阅读最新更新时间:2024-11-12 22:11

STM8S-定时器2的PWM
//软件环境:IAR FOR STM8 V1.0 //作者:Nicole //功能:定时器2的PWM功能,控制小灯的亮灭间隔 //日期:2010.11.10 #include iostm8s207k6.h void CLK_Init(void); void TIM_Init(void); // 函数功能:延时函数 // 输入参数:ms -- 要延时的毫秒数,这里假设CPU的主频为2MHZ void DelayMS(unsigned int ms) { unsigned char i; while(ms != 0) { for(i=0;i 250;i++) { } for(i=
[单片机]
Cortex-M0系统滴答定时器Systick详解
上图是LPC1114系统滴答定时器(SysTick)的结构图。系统滴答定时器位于Cortex-M0内核中,也就是说,不论是LPC1114,还是其他的Cortex-M0内核单片机,都有这个系统定时器。其存在的主要目的是为嵌入式操作系统提供100Hz(即10ms)的定时节拍。当然,也可以做为其它的普通定时等其他用途。下面是LPC1114用户手册上列举出的一些用途,你可以了解了解。 可编程设置频率的RTOS 定时器(例如100 Hz),调用一个SysTick 服务程序。 用于核时钟的高速报警定时器。 简单计数器。软件可使用它测量时间 (如:完成任务所需时间、已使用时间)。 基于丢失 / 命中期限控制的内部时钟源。控制和状态寄存
[单片机]
Cortex-M0系统滴答<font color='red'>定时器</font>Systick详解
基于STM32定时器的红外遥控数据接收设计原理
一、原理 1、红外发射协议 红外发射协议已经在之前的文章中写过,在此就不赘述。 2、定时器计数和输入捕获 定时器就是按照一个特定的频率对计数值进行加一或减一操作,当数值溢出时则产生一个标志或中断。 定时器的输入捕获就是可以测量输入信号的脉冲宽度。 本次就是通过普通计数和输入捕获的结合来实现的。 3、实现方法 利用定时器记录输入信号高脉冲的时间,通过该时间来判断数据是否是同步头信息、数据 1 或者数据 0。 二、实现 1、配置 定时器2 输入捕获通道 示例代码中使用 PA1 管脚,配置为上拉输入模式,复用功能为定时器2的通道2。 定时器采用普通定时器,定时器2,该定时器具有输入捕获功能。 配置定时器的两种工作模式,一个是普通
[单片机]
基于STM32<font color='red'>定时器</font>的红外遥控数据接收设计原理
8052计数器(定时器0和计数器1)
之前由于同学的一个小实验,需要用到频率计,所以自己想搞一个出来,于是网上找了很多资料,简单的有用8052单片机的定时器和计数器的结合来测其信号的频率,还有的是c8051f的捕捉功能,想来想去,还是想用用自己熟悉的8052的计数器功能,毕竟平时都用的是定时器功能,很少用到计数器功能,以便更加深入的运用8052,以后再学习C8051F。 搞了好几天,时钟没有结果,计数功能倒是有了,但是不能在1s的时间里计数,很是头痛,忽然有一天,我的同学找到了一段代码,说是可以运行的,于是我拿过来,把LED改了一改,烧录之后,还真的成功了!甚是大喜啊!这里附上源代码; /*******http://hi.baidu.com/zhangjiay
[单片机]
8052计数器(<font color='red'>定时器</font>0和计数器1)
51单片计4种定时器应用场景详解
  51单片机的定时器有两个,分别是定时器0和定时器1。   定时器0:定时器0是一个8位定时器,它可以用作定时器或计数器。在定时器模式下,它可以生成中断,定时范围为0255。在计数器模式下,它可以计数外部脉冲,计数器范围为065535。   定时器1:定时器1是一个16位定时器,也可以用作定时器或计数器。在定时器模式下,它可以生成中断,定时范围为065535。在计数器模式下,它可以计数外部脉冲,计数器范围为065535。   在使用定时器时,需要先进行定时器的初始化设置。具体步骤如下:   1.选择定时器工作模式(定时器或计数器)。   2.设置计数值或定时器的初值。   3.打开定时器中断(如果需要中
[单片机]
51单片机定时器设置方式_51单片机定时器/计数器
8051单片机内部有两个定时/计数器T0及T1,具有定时和计数两种功能。T0及T1在计数过程中不需要CPU参与,也不影响CPU的其他工作。当计数溢出后,定时/计数器给出中断信号,申请CPU停止当前的工作,去处理预先设定的中断事件。 一、T1内部结构 定时器工作模式:对内部时钟信号计数。由于时钟频率是定值,所以可根据计数值计算出定时时间。 计数器工作模式:是对加在T1(P3.5)引脚上的外部脉冲进行计数。 二、计数功能 计数器用于统计从TO(P3.4)和Tl(P3.5)两个引脚输入脉冲的负跳变数量。负跳变是指前一个机器周期采样为高电平,后一个机器周期为低电平。每输入一个脉冲负跳变,计数器加1。 输入脉冲的高电平与
[单片机]
51单片机<font color='red'>定时器</font>设置方式_51单片机<font color='red'>定时器</font>/计数器
单片机矩阵按键定时器消抖程序源码
芯片是采用的stc89c51单片机. 下面是矩阵键盘的电路图,矩阵键盘是接在p2口的. 下面是单片机部分的图,数码管显示等完整的原理图可以从 http://www.51hei.com/f/ks51.pdf 这里下载 下面是程序源码: /********矩阵按键定时器消抖**************/ /** *时间:2014年3月18日20:27:23 *作者:寒竹子 *工程写法:用定时器为按键消抖不占用cpu的时间 **/ #include reg52.h typedef unsigned int uint; typedef unsigned char uchar; //138 sbit ADDR0 = P1
[单片机]
单片机矩阵按键<font color='red'>定时器</font>消抖程序源码
AVR 定时器快速PWM模式使用
PWM很常用,AVR自带内部PWM功能,分为快速PWM模式和相位修正PWM模式。 我们这里选择方式15 ,由OCR1A保存上限值,由OCR1B保存匹配值,所以输出管脚 OCR1A不能输PWM,只能有OCR1B输出PWM信号。 如果用方式 5,6,7模式 上限值是固定的,所以我们就可以用OCR1A和OCR1B保存匹配值 OCR1A和OCR1B都可以输出PWM信号。 快速PWM时序图 根据此公式计算出OCR1A和OCR1B的数值 OCR1A: 1,11059200 / 100 /64 = 1728
[单片机]
AVR <font color='red'>定时器</font>快速PWM模式使用
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved