STM32输入捕获原理与配置

2023-11-03


一、输入捕获原理

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

        

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

       

二、输入捕获过程

1.设置输出捕获滤波器(通道1为例)

         滤波器IC1F[3:0]是用来设置输入采样频率和数字滤波器长度。f_{DTS}是根据TIMx_CR1的CKD[1:0]来设置的,如果CKD[1:0]设置为00,则f_{DTS} = f_{CK\, INT}。fCK_INT是内部时钟,等于72MHz。假如为上升沿触发,那么在捕获上升沿的时候,再以fCK_INT的频率连续采样8次通道1的电平,如果都是高电平,则是一个有效的触发。这样就可以滤掉低于8个采样周期的脉冲信号(IC1F[3:0]=0011,滤波长度N=8),实现滤波效果。IC1F[3:0]=0000,只用采集上升沿,就触发捕获。

2.设置输入捕获极性

         边沿检测器检测信号,比如设置为上升沿捕获,则捕获上升沿,下降沿同理;CC1输出设置高电平有效还是低电平有效;CC1输入则是选择捕获上升沿或下降沿。

3.设置输入捕获映射通道

 

         

4.设置输入捕获分频器

        

 

         每两个事件(设置为上升沿捕获):每隔2次上升沿执行一次捕获

5.捕获到有效信号可以开启中断

         如果开启了捕获中断,就是在捕获上升沿或下降沿  的时候开启中断。

6.工作工程        

        通过检测TIMx CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器 (TIMx CCRx)里面,完成一次捕获。

三、输入捕获编程流程(HAL库)

         

        1.定时器输入捕获时基参数初始化

        HAL_TIM_IC_Init(TIM_HandleTypeDef *htim);        // IC输入捕获初始化

        2.初始化通道参数配置

        HAL_TIM_IC_ConfigChannel(); 

        3.初始化回调函数(一般情况,回调函数里编写时钟使能,IO口配置以及优先级设置等)

        __HAL_RCC_TIM5_CLK_ENABLE();

        4.使能定时器并使能输入捕获通道

        HAL_TIM_IC_Start();             // 使能

        HAL_TIM_IC_Start_IT();        // 捕获的同时开启中断    

       

        5.捕获中断服务函数

        HAL_TIM_IRQHandler();

       

        6.读取捕获值

        uint32_t HAL_TIM_ReadCapturedValue();

四、程序要求

        测量信号的脉冲宽度。

五、代码实现

        tip:因为要检测上图高电平信号,所以我们用PA0按键,因为PA0是高电平有效,低电平无效。因为是用的是PA0,所以用的是TIM5_CH1。

1.timer.h

#ifndef __TIMER_H
#define __TIMER_H

#include "sys.h"

extern TIM_HandleTypeDef TIM5_IC_Handle;
void TIM5_IC_Init(void);


#endif

2.timer.c

#include "timer.h"

TIM_HandleTypeDef TIM5_IC_Handle;    // TIM句柄
TIM_IC_InitTypeDef TIM5_IC_InitStruct;   // TIM_IC句柄

void TIM5_IC_Init(void)
{

    TIM5_IC_Handle.Instance = TIM5;
    TIM5_IC_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;   // 设置TIM5的计数模式,向上计数
    TIM5_IC_Handle.Init.Period = 0xFFFFFFFF;               // 设置自动装载值
    TIM5_IC_Handle.Init.Prescaler = 90 - 1;               // 设置分频系数
    
    HAL_TIM_IC_Init(&TIM5_IC_Handle);


    TIM5_IC_InitStruct.ICPolarity = TIM_ICPOLARITY_RISING;                          // 捕获极性:上升沿捕获
    TIM5_IC_InitStruct.ICPrescaler = TIM_ICPSC_DIV1;                                // 输入分频:配置输入分频,选择不分频
    TIM5_IC_InitStruct.ICSelection = TIM_ICSELECTION_DIRECTTI;                      // 输入映射:映射到TI1上 
    TIM5_IC_InitStruct.ICFilter = 0;                                                // 配置滤波器,不滤波
    HAL_TIM_IC_ConfigChannel(&TIM5_IC_Handle, &TIM5_IC_InitStruct, TIM_CHANNEL_1);  // 配置IC通道

    HAL_TIM_IC_Start_IT(&TIM5_IC_Handle, TIM_CHANNEL_1);                            // 开启TIM5捕获通道,并且开启捕获中断
    __HAL_TIM_ENABLE_IT(&TIM5_IC_Handle, TIM_IT_UPDATE);                            // 当按键按得过长或许会溢出ARR(设定的装载值),需要记录溢出多少次,所以要开启更新中断

}


void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{

    if (htim->Instance == TIM5)                       // 判断为TIM5
    {
        
        __HAL_RCC_TIM5_CLK_ENABLE();                // 使能TIM5
        __HAL_RCC_GPIOA_CLK_ENABLE();               // 使能PA

        GPIO_InitTypeDef GPIO_InitStruct;           // GPIO句柄

        GPIO_InitStruct.Pin = GPIO_PIN_0;           // PA0
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;       // 下拉
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;     // 推挽输出
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;    // 高速
        GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;  // 复用为TIM5

        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);      // 初始化GPIOA

        HAL_NVIC_EnableIRQ(TIM5_IRQn);              // 使能TIM5
        HAL_NVIC_SetPriority(TIM5_IRQn, 2, 1);      // 设置TIM5优先级

    }
    
}


/*
    捕获状态:
        [7]:0:没有捕获成功;1:捕获成功
        [6]:0:没有捕获高电平;1:捕获高电平
        [5-0]:捕获低电平后溢出的次数
*/

u8  TIM5CH1_CAPTURE_STA=0;	//输入捕获状态		    				
u32	TIM5CH1_CAPTURE_VAL;	//输入捕获值(TIM2/TIM5是32位)

void TIM5_IRQHandler(void)                              // TIM5中断服务函数
{

    HAL_TIM_IRQHandler(&TIM5_IC_Handle);            // 中断处理入口函数(所有的TIM中断都用函数)

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)     // 定时器更新中断(溢出)处理回调函数,在HAL_TIM_IRQHandler调用
{

    if ((TIM5CH1_CAPTURE_STA&0x80) == 0)                        // 还未捕获成功
    {
        
        if (TIM5CH1_CAPTURE_STA&0x40)                    // 捕获成功
        {
            
            if ((TIM5CH1_CAPTURE_STA&0x3F) == 0x3F)             // 高电平太长
            {
                
                TIM5CH1_CAPTURE_STA |= 0x80;                    // 标记捕获成功一次
                TIM5CH1_CAPTURE_VAL = 0XFFFFFFFF;

            }
			else
			{
				
				TIM5CH1_CAPTURE_STA++;                              // 自加1次
				
			}
 
        }
        
    }
    
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)        // 定时器输入捕获回调函数,在HAL_TIM_IRQHandler调用
{

    if ((TIM5CH1_CAPTURE_STA&0x80) == 0)                        // 未捕获成功
    {
        
        if (TIM5CH1_CAPTURE_STA&0x40)                    // 捕获到下降沿
        {
            
            TIM5CH1_CAPTURE_STA |= 0x80;                        // 标志成功捕获到一次高电平脉宽
            TIM5CH1_CAPTURE_VAL = HAL_TIM_ReadCapturedValue(&TIM5_IC_Handle,TIM_CHANNEL_1);     // 获取当前的捕获值

            TIM_RESET_CAPTUREPOLARITY(&TIM5_IC_Handle, TIM_CHANNEL_1);                          // 清除之前的设置
            TIM_SET_CAPTUREPOLARITY(&TIM5_IC_Handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);     // 配置TIM5通道1上升沿捕获 

        }
        else
        {
            
            TIM5CH1_CAPTURE_STA = 0;                            // 清零
            TIM5CH1_CAPTURE_VAL = 0;
            TIM5CH1_CAPTURE_STA |= 0x40;                        // 捕获到上升沿

            __HAL_TIM_DISABLE(&TIM5_IC_Handle);                 // 关闭定时器TIM5
            __HAL_TIM_SET_COUNTER(&TIM5_IC_Handle, 0); 

            TIM_RESET_CAPTUREPOLARITY(&TIM5_IC_Handle, TIM_CHANNEL_1);                          // 清除之前的设置
            TIM_SET_CAPTUREPOLARITY(&TIM5_IC_Handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING);     // 配置TIM5通道1下降沿捕获 

            __HAL_TIM_ENABLE(&TIM5_IC_Handle);                  // 使能TIM5

        }
        
        
    }
    

}

3.main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "timer.h"

extern u8  TIM5CH1_CAPTURE_STA;	//输入捕获状态		    				
extern u32	TIM5CH1_CAPTURE_VAL;	//输入捕获值(TIM2/TIM5是32位)

int main()
{

	long long temp = 0;
	HAL_Init();
	Stm32_Clock_Init(360, 25, 2, 8);
	delay_init(180);
	uart_init(115200);
	
	TIM5_IC_Init();

	while (1)
	{

		delay_ms(10);
		
		if (TIM5CH1_CAPTURE_STA&0x80)		// 成功捕获了一次高电平
		{
			
			temp = TIM5CH1_CAPTURE_STA&0x3F;		// 先把最大的值赋值给temp
			temp *= 0XFFFFFFFF;				// 再和TIM最大值相乘可以得到溢出时间的总和
			temp += TIM5CH1_CAPTURE_VAL;			// 得到高电平时间
			
			printf("高电平时间:%lldus \r\n", temp);		// 输出打印高电平时间
			
			TIM5CH1_CAPTURE_STA = 0;				// 清零,进行下一次捕捉

		}
		
		
	}
	

}

4.实验结果

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

STM32输入捕获原理与配置 的相关文章

  • 挖矿病毒攻击的排查处置手册

    一 背景 在用户不知情或未经允许的情况下 占用系统资源和网络资源进行挖矿 影响用户的网络和资源 从而获取虚拟币牟利 为了帮助应对恶意挖矿程序攻击 发现和清除恶意挖矿程序 防护和避免感染恶意挖矿程序 整理了如下针对挖矿活动相关的现状分析和检测
  • 【FPGA基础篇】底层结构组成

    文章目录 前言 CPU和DSP FPGA ASIC对比 FPGA和CPLD比较 FPGA基础 IOB 输入输出单元 CLB 可编程逻辑模块 LUT 查找表 MUX 选择器 复用器 Carry Chain 进位链 Flip Flop 触发器
  • SHELL 脚本定期删除日志文件(日志定期清理)

    假设我们的应用每天会产生一个日志文件 但我们并没有对日志文件做任何归档处理 久而久之日积月累 就会将磁盘空间占满 从而影响系统的正常运行 分析磁盘空间占用情况 当前磁盘空间占用情况 df h 当前目录文件大小列表 ll lh 文件列表按时间

随机推荐

  • 解决Python的your data either using array.reshape(-1, 1) if your data has a single featur

    今天写关于决策树的一些算法的时候 卧槽 mmp 竟然出现了红色的警示错误 oneRowX 0 0 1 0 1 1 0 0 1 0 newRowX 1 0 0 0 1 1 0 0 1 0 Traceback most recent call
  • verilog开发调试入门

    verilog开发调试入门 日常踩坑 记录调试经验 希望帮到初学者 2022 09 26 非阻塞赋值 注意在时序电路内部使用 lt 仿真波形不动 检查代码无误后 考虑分频间隔过大 仿真长度不够 憨憨落泪 上板 生成比特流失败 遇如下警告 C
  • ios笔记--class关键字,Category,protocol和block笔记

    1 class关键字介绍 1 概念 只是声明是一个类 但是调用不了这个类里面的方法 2 作用 只是定义成员变量 属性 3 好处 当import导入的文件里面的方法变动了 引用的地方也要跟着改变 而且还需要重新编译一次 影响程序效率 但是使用
  • 计算机毕业设计-基于SSM的高校毕业生离校管理系统

    项目摘要 随着信息技术和网络技术的飞速发展 人类已进入全新信息化时代 传统管理技术已无法高效 便捷地管理信息 为了迎合时代需求 优化管理效率 各种各样的管理系统应运而生 各行各业相继进入信息管理时代 高校毕业生离校管理系统就是信息时代变革中
  • 详解 IntelliJ IDEA 配置和启动maven 项目 步骤

    一 从svn中检出web项目 1 如果是maven项目 首先配置仓库 2 从svn中检出maven项目 3 检查项目是否是maven项目 如果不是转化成maven 然后点击 更新jar 二 配置jdk SDK 1 点击 三 配置projec
  • 几种概率分布(伯努利分布、二项分布、泊松分布、均匀分布、正态分布、指数分布、伽马分布)

    伯努利分布 Bernoulli Distribution 又名两点分布或者0 1分布 是一个离散型概率分布 为纪念瑞士科学家雅各布 伯努利而命名 若伯努利试验成功 则伯努利随机变量取值为1 若伯努利试验失败 则伯努利随机变量取值为0 记其成
  • 这个cuda教程不错,一个链接

    http supercomputingblog com cuda tutorials
  • 遗传算法(Python)

    import numpy as np import matplotlib pyplot as plt from matplotlib import cm from mpl toolkits mplot3d import Axes3D 设定参
  • Servlet详解

    一 Servlet的生命周期 创建Servlet有两个时机 一是客户端第一次请求每个Servlet时 系统创建该Servlet实例 另外是Web应用启动时立即创建Servlet实例 即load on startup Servlet 每个Se
  • 解决问题:Visual Studio 2022 打开Qt设计文件xxx.ui报错

    文章目录 解决问题 Visual Studio 2022 打开Qt设计文件xxx ui报错 环境 问题描述 解决方案 在viusal studio中操作Qt的UI文件 解决问题 Visual Studio 2022 打开Qt设计文件xxx
  • 北航计算机科学与技术专业河北投档线,北京航空航天大学2020录取分数线(附2017-2020年分数线)...

    北京航空航天大学2020年录取分数线是多少 各专业录取分数线是多少 是每个填报 北京航空航天大学的考生最关注的问题 随着各省高考录取批次相继公布 考生也开始关心是否被 北京航空航天大学的录取 一品高考网整理相关信息供参考 希望对大家有帮助
  • 申请搜狐自媒体账号

    visualor 申请入驻搜狐公众平台 特此声明
  • 抽象工厂模式和工厂模式的区别?

    简单工厂模式 简单工厂模式不是23种里的一种 简而言之 就是有一个专门生产某个产品的类 比如下图中的鼠标工厂 专业生产鼠标 给参数0 生产戴尔鼠标 给参数1 生产惠普鼠标 工厂模式 工厂模式也就是鼠标工厂是个父类 有生产鼠标这个接口 戴尔鼠
  • HIVE beeline使用shell 批量执行sql语句

    shell脚本如图所示 principal 代表的是认证方式 bin sh Date Author etc profile bash profile sql14 pc insert into table uv daybyday bylimi
  • PHP小皮使用

    PHP小皮基本使用方法 本人新手一枚开始涉猎PHP了 下次有空补个Apache2 4 php7 2的安装教程 小皮使用 官网下载小皮 https www xp cn 选择好对应版本的小皮 本人电脑是windows10 64位的 2 下载好之
  • python知识复习一

    文章目录 前言 一 变量和简单数据类型 1 命名和使用 2 字符串 2 1 修改字符串大小写 2 2 字符串中使用变量 2 3 使用制表符或者换行符添加空白 2 4 删除空白 3 标准数据类型 4 数据类型转变 5 常量 二 数 1 常量
  • sql语句的复习

    sql语句的复习 说来惭愧 写了这么多年代码 sql语句都忘记差不多了 基础 CREATE DATABASE database name drop datebase dbname 备份数据库 mysqldump u 用户名 p 数据库名 g
  • 一步一步理解大模型:模型量化技术3 - GPTQ

    本文介绍专门为生成式预训练模型设计的量化技术GPTQ GPTQ是一种一次性权重量化方法 专为生成预训练Transformer GPT 模型设计 该方法基于近似二阶信息 旨在实现高度准确和高效 关于GPTQ的关键点 GPTQ可以在大约四个GP
  • Redis数据持久化——快照RDB、AOF、主从复制

    redis 本地持久化到硬盘有两种方式 一是快照 snapshotting 二是只追加文件 append only file AOF 快照 快照 顾名思义可以理解为拍照一样 把整个内存数据映射到硬盘中 保存一份到硬盘 因此恢复数据起来比较快
  • STM32输入捕获原理与配置

    目录 一 输入捕获原理 二 输入捕获过程 1 设置输出捕获滤波器 通道1为例 2 设置输入捕获极性 3 设置输入捕获映射通道 4 设置输入捕获分频器 5 捕获到有效信号可以开启中断 6 工作工程 三 输入捕获编程流程 HAL库 四 程序要求