当前位置: 首页 > news >正文

嵌入式-定时器的输入捕获,超声波获距实验-Day23

目录

一、输入捕获

1.输入捕获的基本原理

2.输入捕获的内部结构

3.输入滤波

4.边沿检测

5.信号选择

6.分频器

二、超声波测距实验

1.HCSR-04模块的使用方法

2.梳理思路

3.搭建电路

​4.USART的IO初始化和模块初始化

5.初始化时基单元

6.初始化输入捕获

7.实现初始化的后续模块

8.代码


一、输入捕获

1.输入捕获的基本原理

当时基单元传进信号时,即时基单元初始化后,将信号也接入通道1和通道2,一个接收脉冲信号的上升沿,一个接收信号的下降沿。

这里的闪 电符号cc1,cc2表示的是发生事件了,即当通道1接收到上升沿然后产生事件cc1,然后会拍照保存CNT的值到CCR1寄存器里面,同理cc2的事件发生也会执行步数保存,那这两保存的数据相减就得到了这个波形的脉宽。

2.输入捕获的内部结构

3.输入滤波

滤除毛刺,即去除噪声、


4.边沿检测

就是检测边沿的


5.信号选择

信号分为直接,间接(来源于一对通道,比如1和2,3和4是互为一对)。TRC后面学

间接的优势:

如果没有间接的话,测量一个脉宽。即需要测量上升沿和下降沿正常要两引脚,但是有了间接就可以光使用一个引脚,使用直接的方法走通道1的上升沿检测,使用间接走通道2的下降沿检测。这样就比正常的能空闲出一个引脚来。 


6.分频器

比如设置分频为4,那么当传输了4次上身沿后才出现cc1的事件。即控制事件出现的频率

二、超声波测距实验

关键器件:超声波测距传感器HC-SR04.

1.HCSR-04模块的使用方法

1. HC-SR04 的引脚

  • VCC:电源,5V

  • GND:地

  • Trig:触发引脚(输入)

  • Echo:回响引脚(输出)


2. 工作流程(看图对应理解)

  1. 触发 (Trig)

    • Trig 引脚一个 大于 10 微秒 的高电平脉冲。

    • 这就相当于告诉模块:“开始发射超声波”。

  2. 发射 (超声波)

    • 模块会自动发射 8 个 40kHz 的超声波脉冲(持续时间大约 200 微秒左右)。

    • 发射之后,模块就开始“监听”反射回来的超声波。

  3. 回响 (Echo 输出高电平)

    • 当发射完超声波之后,模块会立即拉高 Echo 引脚

    • 当检测到超声波的回声后(即目标物体反射的超声波返回时),Echo 引脚拉低。

    • 所以,Echo 引脚高电平的时间长度,就是超声波往返目标物体的时间。

  4. 测距公式

    • 声速取 340 m/s(空气中)

    • 超声波走的是 往返路程,所以要除以 2。

    • 公式就是:

      距离=(时间×声速 )  / 2

3. 为什么用脉冲来测?

  • Echo 脉冲的 宽度(时间长短) 就是“声波飞出去再回来”所花的时间。

  • 只要测量 这个脉冲的宽度,就能算出目标物体的距离。

2.梳理思路

从上下两图可以看到,整体的执行流程就是:

0.初始化USART、时基单元、输入捕获通道。

1.对CNT清零。因为如果CNT不清零,可能会发生重新计数,导致不能正确记录时间。比如上边沿97-ARR的100-清零0-下边沿20这个,20到97不好记录时间

2.对cc1和cc2标志位清零

3.开启定时器。注意:当时基单元的开关一闭合就要开始计数了,即CNT开始加了

4.给传感器的Trig引脚发送脉冲,随便一个单片机正常的引脚都可以,只要能给传感器的Trig发送任意大于10us的脉冲信号就行,表示要开始启动了。

由于启动了,传感器自动发送声波,发送后,Echo就输出,注意是输出,高电压,知道传感器接收声波结束,Echo拉低电压表示结束。——那这个有啥用,就是用来测距离的,他底层就是这么测的,使用自己记录的这个高电压变化即脉冲信号,可以记录当前传感器和障碍物的距离。

5.等待cc1的变化和cc2的变化。因为需要拿他两的时间差t,去算出前面没算完的距离。

6.关闭定时器


3.搭建电路


4.USART的IO初始化和模块初始化

                                                                   
5.初始化时基单元

初始化的值默认定时器是传入的72MHz,但是分辨率和周期怎么选择。

网上查找这个传感器的精度最高3mm,那就是最高对应着8us,所以分辨率必须小于8us,那越小越好,但不能太小的话,就取1us。

周期当然越大越好,因为不知道这个要测的脉冲信号的对应的时间多少,但因为就怕出现到达ARR极限值然后归0导致你测不了脉宽即时间,所以周期选择 设备支持的最大的2的16次,因为定时器的时基单元默认是16位的寄存器。

6.初始化输入捕获

这里不一定要遵循手册,因为Echo默认是低电压,所以可以设置对接的引脚为输入下拉,默认也是低电压。

首先初始化输入的IO引脚

之后初始化输入通道1和2(即实现了一个引脚,两个通道的使用)


7.实现初始化的后续模块

8.代码

#include "stm32f10x.h"
#include "Delay.h"#include "usart.h"void App_USART_Init(void);
void App_TimeBase_Init(void);
void App_IC_Init(void);int main(void)
{//传感器测距 //首先初始化USART、时基单元、输入捕获App_USART_Init();App_TimeBase_Init();App_IC_Init();TIM_SetCounter(TIM1,0);TIM_ClearFlag(TIM1,TIM_FLAG_CC1);TIM_ClearFlag(TIM1,TIM_FLAG_CC2);TIM_Cmd(TIM1,ENABLE);//给传感器发送启动信号GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);DelayUs(10);GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);while(1){while(TIM_GetFlagStatus(TIM1,TIM_FLAG_CC1)==RESET  || TIM_GetFlagStatus(TIM1,TIM_FLAG_CC2)==RESET);uint16_t cc1=TIM_GetCapture1(TIM1);uint16_t cc2=TIM_GetCapture1(TIM2);float end=(cc2-cc1)*(1.0e-6f)*340.0f/2;My_USART_Printf(USART1,"%.3f\n",end*100);Delay(100);}
}void App_USART_Init(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//这里只是往串口调试工具发数据,所以不用定义RxGPIO_InitTypeDef GPIO_InitStruct={0};GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);USART_InitTypeDef USART_InitStruct={0};USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_Mode=USART_Mode_Tx;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_Init(USART1,&USART_InitStruct);}
void App_TimeBase_Init(){//RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//默认是72MHz,选择分辨率1us,周期25535+1TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct={0};TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period=25535;TIM_TimeBaseInitStruct.TIM_Prescaler=71;TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);//开启预加载TIM_ARRPreloadConfig(TIM1,ENABLE);//顺便也把CCRx的预加载也打开TIM_CCPreloadControl(TIM1,ENABLE);}//初始化输入
void App_IC_Init(){//初始化一个输入引脚RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStrut={0};GPIO_InitStrut.GPIO_Mode=GPIO_Mode_IPD;GPIO_InitStrut.GPIO_Pin=GPIO_Pin_0;GPIO_InitStrut.GPIO_Speed=GPIO_Speed_2MHz;GPIO_Init(GPIOA,&GPIO_InitStrut);//初始化两通道TIM_ICInitTypeDef IC_InitStruct={0};IC_InitStruct.TIM_Channel=TIM_Channel_1;IC_InitStruct.TIM_ICFilter=1;IC_InitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;IC_InitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;IC_InitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;TIM_ICInit(TIM1,&IC_InitStruct);IC_InitStruct.TIM_Channel=TIM_Channel_2;IC_InitStruct.TIM_ICFilter=1;IC_InitStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;IC_InitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;IC_InitStruct.TIM_ICSelection=TIM_ICSelection_IndirectTI;TIM_ICInit(TIM1,&IC_InitStruct);}

http://www.dtcms.com/a/357246.html

相关文章:

  • 如何使用 Vector 连接 Easysearch
  • 【实时Linux实战系列】实时环境监控系统的架构与实现
  • PPT处理控件Aspose.Slides教程:使用 C# 编程将 PPTX 转换为 XML
  • 【实时Linux实战系列】基于实时Linux的虚拟现实应用开发
  • 趣味学Rust基础篇(所有权)
  • 【DeepSeek】公司内网部署离线deepseek+docker+ragflow本地模型实战
  • 《跳出“技术堆砌”陷阱,构建可演进的软件系统》
  • 【PyTorch】神经风格迁移项目
  • 每周资讯 | 《恋与深空》获科隆游戏展2025“最佳移动游戏奖”;8月173个版号下发
  • 【小白笔记】访问GitHub 账户的权限英文单词解释
  • nvm使用和node使用
  • 【前端教程】用 JavaScript 实现4个常用时间与颜色交互功能
  • centos8部署miniconda、nodejs
  • webpack升级
  • 飞牛Nas每天定时加密数据备份到网盘,基于restic的Backrest笔记分享
  • linux和RTOS架构区别
  • 通过 KafkaMQ 接入Skywalking 数据最佳实践
  • JAVA:Spring Boot 集成 Easy Rules 实现规则引擎
  • 滚珠导轨如何赋能精密制造?
  • 【数据分享】省级人工智能发展水平综合指标体系(2011-2022)
  • 安卓开发---BaseAdapter(定制ListView的界面)
  • 基于SpringBoot和Thymeleaf开发的英语学习网站
  • 笔记本电脑频繁出现 vcomp140.dll丢失怎么办?结合移动设备特性,提供适配性强的修复方案
  • C#连接SQL-Server数据库超详细讲解以及防SQL注入
  • LSTM实战:回归 - 实现交通流预测
  • 保护海外服务器免受黑客攻击的方法
  • WebSocket功能完整解析
  • Linux系统——EXT2 文件系统
  • 【论文阅读】Sparse4D v2:Recurrent Temporal Fusion with Sparse Model
  • HTML 和 JavaScript 关联的基础教程