15.输入捕获

2023-11-20

1.输入捕获介绍:

  • STM32除了基本定时器(定时器6和定时器7)之外,其他的都具有输入捕获功能;
  • 输入捕获可以对输入的信号的上升沿、下降沿或双边沿进行捕获,通常用于测量输入信号的脉宽、测量PWM输入信号的频率及占空比;
  • 首先将捕获到t1信号之后将CNT的值进行清零,清零之后并且下一次捕获是下降沿,将捕获极性设置为下降沿捕获;到达t2时,就会发生捕获事件,得到此时的CNT的值,将t2的值记为CCRx2,将(t2-t1)*T(计数频率的周期)=溢出时间;当在t1到t2时间内,可能高电平时间脉冲比较长,有可能定时器会产生溢出,如果溢出就会产生溢出中断,在溢出中断中用变量累计溢出的次数N,N*ARR=溢出次数;溢出次数*一次的值=N次溢出累计的时间;(N*ARR+CRRx2)=t1到t2的时间。

 2.输入捕获库函数配置步骤:

定时器相关库函数在stm32f10x_tim.c和stm32f10x_tim.h文件中;
  1. 使能定时器及端口时钟,并设置引脚模式等:RCC_APB1PeriphClockCmd()和GPIO_Init();
  2. 初始化定时器参数,包含自动重装载值,分频系数,计数方式等:void TIM_TimeBaseInit();
  3. 设置通用定时器的输入捕获参数,开启输入捕获功能;void TIM_ICInit()、TIM_OC1PolarityConfig();
  4. 开启捕获和定时器溢出(更新中断):void TIM_ITConfig();
  5. 设置定时器中断优先级,使能定时器中断通道;
  6. 编写定时器中断服务函数;
  7. 使能定时器:void TIM_Cmd();

3.输入捕获实验:

实现功能:实验定时器TIM5的CH1检测输入信号高电平脉冲,将检测的高电平脉冲时间通过printf函数打印出来,同时让LED0指示灯不断闪烁表示系统正常运行。

(1)原理图:

(2)主函数: 

#include "delay.h"
#include "led.h"
#include "usart1.h"
#include "input.h"



int main(){
    
    u8 i=0;                                          
    u32 indata=0;                                        //累计整个从上升沿到下降沿的次数
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //设置分组
    delay_init();                                        //延时初始化
    LED_Init();  
    usart1_Init(9600);                                   //串口通信初始化
    TIM5_CH1_Input_Init(0xffff,72-1);                    //输入捕获->定时器3通道1初始化
   
    while(1){
       if((TIM5_CH1_CAPTURE_STA&0x80))                   //判断捕获是否完成->这里表示完成 
       {
          indata=TIM5_CH1_CAPTURE_STA&0x3f;              //得到溢出次数
          indata*=0xffff;                                //将所有溢出次数换算成计数的次数
          indata+=TIM5_CH1_CAPTURE_VAL;
          printf("高电平持续时间:%d us\r\n",indata);
          TIM5_CH1_CAPTURE_VAL=0;                        //开启下一次捕获
            
       }
       
       i++;
       if(i%20==0)
       {
          LED0=!LED0;
       }

        delay_ms(20);
    }       
}

(3)头文件:

#ifndef __INPUT_H
#define __INPUT_H

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

extern u8 TIM5_CH1_CAPTURE_STA;
extern u16 TIM5_CH1_CAPTURE_VAL;


void TIM5_CH1_Input_Init(u16 arr,u16 psc);         //输入捕获->定时器5通道1初始化


#endif

(4)输入捕获功能函数:

#include "stm32f10x.h"
#include "input.h"



/*
   功能:输入捕获->定时器5通道1初始化
   变量:arr:自动重装载值     psc:预分频系数
   返回值:
*/
void TIM5_CH1_Input_Init(u16 arr,u16 psc)
{
   GPIO_InitTypeDef GPIO_InitStruct;
   TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
   TIM_ICInitTypeDef TIM_ICInitStruct;
   NVIC_InitTypeDef NVIC_InitStruct;
   
   //1.使能定时器和端口时钟,并设置引脚模式;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);     //使能端口时钟
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);      //使能定时器时钟
   
   GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;                 //输入下拉
   GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;                     //PA0
   GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_Init(GPIOA,&GPIO_InitStruct);
      
   //2.定时器初始化
   TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;      //1分频
   TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;  //计数模式->向上计数
   TIM_TimeBaseInitStruct.TIM_Period=arr;                      //自动重装载值
   TIM_TimeBaseInitStruct.TIM_Prescaler=psc;                   //预分频系数
   TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStruct);
   
   //3.设置通用定时器的输入捕获,开启输入捕获功能
   TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;                 //设置为通道1
   TIM_ICInitStruct.TIM_ICFilter=0x00;                         //滤波器长度->不使用滤波
   TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;      //捕获极性->上升沿捕获
   TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;            //1分频
   TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;  //映射->直接映射
   TIM_ICInit(TIM5,&TIM_ICInitStruct);
   
   //4.开启捕获和定时器溢出中断
   TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);
   
   //5.设置定时器中断优先级,使能定时器中断通道
   NVIC_InitStruct.NVIC_IRQChannel=TIM5_IRQn;                  //设置中断通道
   NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;                     
   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;        //抢占优先级
   NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;               //子优先级
   NVIC_Init(&NVIC_InitStruct);
   
   //6.使能定时器
   TIM_Cmd(TIM5,ENABLE);
     
}



/*
   功能:中断服务函数
   变量:无
   返回值:无
   注意:
      如果捕获到了上升沿再到下一次捕获到下降沿就完成了一次捕获,让TIM5_CH1_CAPTURE_STA最高位 置1,
      如果捕获到上升沿让TIM5_CH1_CAPTURE_STA的次高位 置1,
      将TIM5_CH1_CAPTURE_STA剩下的6位,累计溢出次数;


*/

u8 TIM5_CH1_CAPTURE_STA=0;      //输入捕获状态
u16 TIM5_CH1_CAPTURE_VAL=0;     //输入状态值

void TIM5_IRQHandler(void)
{
   /*注意:处理完第一次捕获成功的数据之后,才能处理下一次捕获的数据*/
   if((TIM5_CH1_CAPTURE_STA&0x80)==0)              // TIM5_CH1_CAPTURE_STA的最高位为0时->未捕获完成
   {
      if(TIM_GetITStatus(TIM5,TIM_IT_Update))      //溢出中断
      {
         if((TIM5_CH1_CAPTURE_STA&0x40))           //已经捕获到上升沿
         {
            if((TIM5_CH1_CAPTURE_STA&0x3f)==0x3f)        //判断当STA后六位全为1时,累计次数已满
            {
               TIM5_CH1_CAPTURE_STA|=0x80;         //将TIM5_CH1_CAPTURE_STA最高位设置为1,表示捕获成功
               TIM5_CH1_CAPTURE_VAL=0xffff;        //将TIM5_CH1_CAPTURE_VAL设置为最大;
            }
            else                                   //当STA后六位不全为1时,说明还没有累计完
            {
               TIM5_CH1_CAPTURE_STA++;
            } 
         }  
      } 
      
      if(TIM_GetITStatus(TIM5,TIM_IT_CC1))                  //捕获中断
      {
         if((TIM5_CH1_CAPTURE_STA&0x40))                    //当STA次高位为1时,说明捕获到上升沿
         {
            TIM5_CH1_CAPTURE_STA|=0x80;                     //设置STA最高位为1;表示捕获成功
            TIM5_CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);     //将定时器5通道1的比较值赋值给VAL
            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_High);    //设置捕获极性为上升沿捕获->为下一次捕获做准备
         }
         else                                               //当STA的次高位不为1时,则没有捕获到上升沿
         {
            TIM5_CH1_CAPTURE_STA=0;
            TIM5_CH1_CAPTURE_VAL=0;
            TIM_SetCounter(TIM5,0);                         //清零计数器的值
            TIM5_CH1_CAPTURE_STA|=0x40;                     //第一次捕获到上升沿时,将STA的次高位设置为1
            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_Low); //设置捕获极性为下降沿捕获
               
         }  
      } 
   }
   
   TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC1);                                 //清除定时器标志位       
 
}



(6)实验结果:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

15.输入捕获 的相关文章

随机推荐

  • HTTP报文结构

    1 URL HTTP使用统一资源定位符 URL 协议 主机 端口 路径 2 HTTP 3 HTTP请求报文 请求行 首部 空行 主体 客户端发送一个HTTP请求到服务器的请求报文如下 1 请求行 方法 URL 空行 协议的版本 中间空格隔开
  • Qt公有槽和私有槽的区别

    Qt遵循C 的规则 当槽函数作为一个成员函数 公有槽可以被其他类调用 而私有槽只能被类自身调用 当槽函数被信号触发而被调用时 公有槽和私有槽没有区别 它们都能被外部信号触发 参考链接 https stackoverflow com ques
  • JavaEE学习记录day11 IO流02 字符流、转换流、Properties集合

    1 字符流 1 1为什么会出现字符流 理解 字符流的介绍 由于字节流操作中文不是特别的方便 所以Java就提供字符流 字符流 字节流 编码表 中文的字节存储方式 用字节流复制文本文件时 文本文件也会有中文 但是没有问题 原因是最终底层操作会
  • 黑幕!阿里P8爆出学透这份算法面试文档,不再怕任何大厂算法题

    为什么要学习数据结构和算法 随着应用程序变得越来越复杂和数据越来越丰富 几百万 几十亿甚至几百亿的数据就会出现 而对这么大对数据进行搜索 插入或者排序等的操作就越来越慢 数据结构就是用来解决这些问题的 阅读本教程前 您需要了解的知识 在您开
  • FastDFS storage服务器安装Nginx

    环境准备 操作系统 Centos 服务器 192 168 60 165 storage服务器 软件包 fastdfs nginx module 1 20 tar gz nginx 1 14 0 tar gz 软件包下载地址 待补充 第一步
  • Hive 窗口函数如何设置窗口大小

    select city year taxes sum money over as sample1 所有行相加 sum money over partition by city as sample2 按city分组 组内数据相加 sum mo
  • Linux下用inotify-tool实时监控服务器文件

    说明 服务器系统 CentOS 文件目录 home web os 实现目的 当 home web os下面除过cache目录之外 任何文件发生变化时 记录日志并保存 具体操作 一 安装Inotify tools工具 1 查看服务器内核是否支
  • Android SurfaceFlinger服务(三) ----- 本地图层Layer创建

    在上一篇文章中 主要分析了Surface的创建过程 对于Layer图层的创建并没有深入跟踪分析 这篇文章将分析Layer图层的创建 并分析handle gbp这两个变量的来源 在SurfaceFlinger中会根据flags的值创建不同的l
  • CMake中include的使用

    CMake中的include命令用于从文件或模块 file or module 加载并运行CMake code 其格式如下 include
  • 【算法】Dijkstra最短路算法

    上周我们介绍了神奇的只有五行的Floyd最短路算法 它可以方便的求得任意两点的最短路径 这称为 多源最短路 本周来来介绍指定一个点 源点 到其余各个顶点的最短路径 也叫做 单源最短路径 例如求下图中的1号顶点到2 3 4 5 6号顶点的最短
  • VS+QT开发Ocx/ActiveX控件 一

    VS QT开发Ocx ActiveX控件 一 VS QT开发Ocx ActiveX控件 网页中全屏 二 QT开发ActiveX控件 一 所用IDE版本 需用管理员权限 二 创建ActiveX 三 qt desinger 四 regsvr32
  • java虚拟机win10_Win10系统启动软件出现Java虚拟机错误的解决方法

    在 1 为Java设置新的系统变量 当Java需要更大的全局最大堆内存大小时 通常会出现Java虚拟机错误 用户通过扩展分配给Java的最大RAM来解决该问题 用户可以通过建立新的Java System Variable来实现 如下所示 使
  • Linux Debian Jenkins快速搭建配置并运行

    Jenkins安装 参考Debian Jenkins Packageshttps pkg origin jenkins io debian stable 加Key curl fsSL https pkg jenkins io debian
  • C++98 auto_ptr智能指针

    auto ptr 是C 98定义的智能指针模板 其定义了管理指针的对象 可以将new获得 直接或间接 的地址赋给这种对象 当对象过期时 其析构函数将使用delete来释放内存 用法 头文件 include
  • chatgpt赋能python:Python金额计算

    Python金额计算 Python是一种高级编程语言 因其易于阅读 简单 灵活和易于学习而广受欢迎 它还具有强大的数学和计算功能 因此 它是一种非常流行的用于金额计算的工具 在本文中 将介绍如何使用Python进行金额计算 包括不同的货币格
  • mysql-client客户端安装

    测试 生产环境中 有时并不需要在本地安装一个mysql server服务 只需要安装一个登录mysql server 的mysql的客户端client centos6系统上安装mysql client的方式 yum install mysq
  • GDI+学习笔记7-统计报表的图形绘制

    图形编程 SetPixel 设置指定点的颜色 COLORREF SetPixel HDC hDC int X int Y COLORREF crColor hDC 绘制点的DC X Y 坐标位置 crColor 设置的颜色 返回值为设置颜色
  • ubuntu虚拟机与windows系统间不能复制粘贴

    sudo tar zxf VMwareTools 10 3 23 17030940 tar gz 这个命令时解压文件 输入 sudo vmware tools distrib vmware install pl 与 vmware tools
  • PHP的进制转换与字符串的编码解码

    目录 一 进制转换函数 dechex hexdec decbin bindec base convert 二 编码解码函数 bin2hex hex2bin pack 和 unpack 三 字符串类型详解 PHP字符串 从PHP 5 2 1版
  • 15.输入捕获

    1 输入捕获介绍 STM32除了基本定时器 定时器6和定时器7 之外 其他的都具有输入捕获功能 输入捕获可以对输入的信号的上升沿 下降沿或双边沿进行捕获 通常用于测量输入信号的脉宽 测量PWM输入信号的频率及占空比 首先将捕获到t1信号之后