热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获

文章目录前言1、输入捕获原理1.1、设置输入捕获滤波器1.2、设置输入捕获的极性1.3、设置输入捕获的映射通道1.4、设置输入捕获分频器1.5、捕获到有效信号可开启中断1.6、捕获


文章目录

  • 前言
  • 1、输入捕获原理
    • 1.1、设置输入捕获滤波器
    • 1.2、设置输入捕获的极性
    • 1.3、设置输入捕获的映射通道
    • 1.4、设置输入捕获分频器
    • 1.5、捕获到有效信号可开启中断
    • 1.6、捕获实现频率和占空比的获取
  • 2、输入捕获功能配置流程
  • 3、部分源码


前言


  下载工程文件:
  https://gitee.com/Joseph_Cooper/blue-bridge-embedded





1、输入捕获原理

在这里插入图片描述


1.1、设置输入捕获滤波器

  根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动,我们须配置滤波器的带宽长于5个时钟周期;因此我们可以(以fDTS频率)连续采样8次,以确认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。
在这里插入图片描述


1.2、设置输入捕获的极性

  改变CC1P位的值以改变上升沿触发或是下降沿触发。可通过库函数void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)来设置。


1.3、设置输入捕获的映射通道

  通道内获得的信号是可以通过设置交给不同的IC来进行处理的,比如,我们可以将通道1捕获的信号送给IC2处理。
在这里插入图片描述


1.4、设置输入捕获分频器

  可设置多次上升沿触发一次捕获也就是相当于分频的作用。
在这里插入图片描述


1.5、捕获到有效信号可开启中断

  捕获到一次信号可以进入相应的中断服务函数。
在这里插入图片描述
在这里插入图片描述


1.6、捕获实现频率和占空比的获取

在这里插入图片描述
1、设置为上升沿捕获、定时器值清零
2、上升沿捕获成功后记录定时器中的值A再设置为下降沿捕获
3、下降沿捕获成功后记录定时器中的值B再次设置为上升沿捕获。
4、再次设置为上升沿捕获,捕获成功后记录定时器中的值C,清空定时器计数值,(C−A)⋅1fTIM(C-A)\cdot\frac1{f_{TIM}}(CA)fTIM1即为该波形的周期,其倒数即是频率,B−AC−A×100%\frac {B-A}{C-A}\times100\%CABA×100%即为占空比。




2、输入捕获功能配置流程

1、初始化定时器和通道对应IO的时钟。
2、初始化IO口,模式为输入
  GPIO_Init();
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
3、初始化定时器ARR,PSC
   TIM_TimeBaseInit();
4、初始化输入捕获通道
  TIM_ICInit();
5、使能定时器
  TIM_Cmd();
6、如果要开启捕获中断
  TIM_ITConfig();
  NVIC_Init();
7、编写中断服务函数
  TIMx_IRQHandler();

需要用到的函数:
  通道极性设置函数
  void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
  获取捕获值
  uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);




3、部分源码

PWM输出:
在这里插入图片描述

输入捕获:
在这里插入图片描述
main.c:

#include "Headfile.h"/**
* @file main.c
* @brief 实现PA1捕获PA9、PA10端的输出,显示频率和占空比
* @version 1.0
* @author JosephCooper
* @date 2020.10.09
*/
/** 滴答定时器实现延时中间变量 */
u32 TimingDelay = 0;
extern __IO uint32_t TIM2Freq;
extern u8 TIM2FreqReady;
extern __IO uint32_t TIM2Duty;void Delay_Ms(u32 nTime);//Main Body
int main(void)
{uint32_t i &#61; 0;u8 Str[200];uint32_t TIM2Freq_BP &#61; 0;uint32_t TIM2Duty_BP &#61; 0;memset(Str,0x00,sizeof(Str));//清空数组SysTick_Config(SystemCoreClock/1000);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Delay_Ms(200);LEDInit();//LED初始化//关闭所有LEDLEDCmd(Bit_SET);GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) | 0xFF00);LEDCmd(Bit_RESET);STM3210B_LCD_Init();LCD_Clear(Blue);LCD_SetBackColor(Blue);LCD_SetTextColor(White);BuzzerInit();//蜂鸣器初始化TIM2_ICInit();TIM1_PWMInit();//TIM1_PWM初始化while(1){if(TIM2FreqReady){TIM2FreqReady &#61; 0;if( (TIM2Freq!&#61;TIM2Freq_BP) || (TIM2Duty!&#61;TIM2Duty_BP) ){TIM2Freq_BP &#61; TIM2Duty;TIM2Duty_BP &#61; TIM2Freq;sprintf((char*)Str,"TIM2Freq:%dHz ", TIM2Freq);LCD_DisplayStringLine(Line2,Str);sprintf((char*)Str,"TIM2Duty:%d%% ", TIM2Duty);LCD_DisplayStringLine(Line3,Str);for(i&#61;0; i<500000; i&#43;&#43;);//刷新延迟}}}
}//
void Delay_Ms(u32 nTime)
{TimingDelay &#61; nTime;while(TimingDelay !&#61; 0);
}

stm32f10x_it.c:

#include "stm32f10x_tim.h"
#include "stm32f10x.h"
extern u32 TimingDelay;
...
//7、编写中断服务函数
__IO uint16_t IC2ReadValue1 &#61; 0, IC2ReadValue2 &#61; 0,IC2ReadValue_LOW &#61; 0;
__IO uint16_t CaptureNumber &#61; 0;
__IO uint32_t Capture &#61; 0;
__IO uint32_t TIM2Freq &#61; 0;
__IO uint32_t TIM2Duty &#61; 0;
u8 TIM2FreqReady &#61; 0;
void TIM2_IRQHandler(void)
{ if(TIM_GetITStatus(TIM2, TIM_IT_CC2) &#61;&#61; SET) {/* Clear TIM3 Capture compare interrupt pending bit */TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);if(CaptureNumber &#61;&#61; 0){/* Get the Input Capture value */IC2ReadValue1 &#61; TIM_GetCapture2(TIM2);CaptureNumber &#61; 1;//设置下降沿捕获TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_Low);}else if(CaptureNumber &#61;&#61; 1){IC2ReadValue_LOW &#61; TIM_GetCapture2(TIM2);CaptureNumber &#61; 2;//设置上升沿捕获TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High);}else if(CaptureNumber &#61;&#61; 2){/* Get the Input Capture value */IC2ReadValue2 &#61; TIM_GetCapture2(TIM2); /* Capture computation */if (IC2ReadValue2 > IC2ReadValue1){Capture &#61; (IC2ReadValue2 - IC2ReadValue1); }else{Capture &#61; ((0xFFFF - IC2ReadValue1) &#43; IC2ReadValue2);}/* Frequency computation */ TIM2Duty &#61; ( (IC2ReadValue_LOW-IC2ReadValue1)*100 ) / Capture;TIM2Freq &#61; 1000000 / Capture;//定时器经过72分频后的频率CaptureNumber &#61; 0;TIM2FreqReady &#61; 1;TIM_SetCounter(TIM2,0);}}
}

InputCaputer.c

#include "Headfile.h"void TIM2_ICInit()
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM2_ICInitStructure;GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//1、初始化定时器和通道对应IO的时钟。RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//2、初始化PA1&#xff0c;模式为输入GPIO_InitStructure.GPIO_Pin &#61; GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed &#61; GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//3、初始化定时器&#xff08;时基设置&#xff09;TIM_TimeBaseStructure.TIM_Prescaler &#61; 72 - 1 ;TIM_TimeBaseStructure.TIM_CounterMode &#61; TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period &#61; 0xFFFF;TIM_TimeBaseStructure.TIM_ClockDivision &#61; 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);//4、初始化输入捕获通道TIM2_ICInitStructure.TIM_Channel &#61; TIM_Channel_2;//定时器2的通道2TIM2_ICInitStructure.TIM_ICPolarity &#61; TIM_ICPolarity_Rising;//上升沿捕获TIM2_ICInitStructure.TIM_ICSelection &#61; TIM_ICSelection_DirectTI;//使用通道默认IC即IC2TIM2_ICInitStructure.TIM_ICPrescaler &#61; TIM_ICPSC_DIV1;//不分频TIM2_ICInitStructure.TIM_ICFilter &#61; 0x00;//不滤波//5、使能定时器TIM_ICInit(TIM2, &TIM2_ICInitStructure);//IC初始化TIM_Cmd(TIM2, ENABLE);//打开定时器//6、如果要开启捕获中断NVIC_InitStructure.NVIC_IRQChannel &#61; TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority &#61; 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority &#61; 1;NVIC_InitStructure.NVIC_IRQChannelCmd &#61; ENABLE;NVIC_Init(&NVIC_InitStructure);TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}

  关于LCD刷新的问题&#xff1a;LCD在刷新时可能因为中断打断出现乱码的问题&#xff0c;将要显示的字符串添加&#xff08;用空格补全&#xff09;至总长度超过20位即可sprintf((char*)Str,"TIM2Freq:%dHz ", TIM2Freq);


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
马芷靈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有