版权归如下公司,禁止非授权转载:

  • 北京西普阳光教育科技股份有限公司(https://www.simpleware.com.cn)
  • 维周机器人科技有限公司(http://www.vejoe.com)

文章目录

  • 【实验目的】
  • 【实验原理】
    • 一、HC-SR04超声波传感器简介
    • 二、工作原理
    • 三、硬件连接和相关库函数介绍
    • 四、软件流程图
  • 【实验环境】
    • 硬件设备
    • 软件环境
    • 实验场地
  • 【实验步骤】
    • 第一步 配置工程环境
    • 第二步 编写定时器函数,完成定时器的配置和启用
    • 第三步 编写main.c文件
    • 第四步 编译并下载,观察实验现象
  • 【思考题】
    • 1、选择题
    • 2、简答题
  • 附录:TIM库函数

【实验目的】

1、熟悉超声波传感器的工作原理;
2、了解HC-SR04超声波传感器的测量范围、测量精度等特性;
3、掌握STM32F10xx系列微控制器上超声波传感器的接口配置与数据采集过程。

【实验原理】

一、HC-SR04超声波传感器简介

超声波传感器是利用检测采集超声波的形式来获得环境信息的传感器。通常用于测距、定位等具体应用场景。超声波是一种弹性介质中的机械波,通常其振动频率为几十KHz到几十MHz(人体能听到的声音频率在20Hz到20KHz)。相比与人耳能听到的声波,超声波具有频率高、波长小、绕射现象小等特点,其传播的方向性强,因此可以用来检测一个固定方向上的距离信息。

本实验采用HC-SR04超声波测距模块,该模块在空气中的测量范围为20mm到4000mm,其测量精度达到3mm。HC-SR04超声波测距模块的硬件实物图如图1.1所示,该模块主要包涵超声波发射器、超声波接收器和外围控制电路。在电路板上一共引出4根引脚,对映于图1.1模块摆设的方向,其接口从左到右分别为VCC(+5V)、Trig(触发信号输入)、Echo(回响信号输出)、GND。

二、工作原理

在外部电路正常供电的情况下,外部采集电路通过给该模块的Trig引脚上输入一个长为10us至20us的高电平信号,以开启一次采集。在模块接收到方波的输入后,超声波发射器会向正前方自动发射8个40KHz的声波信号,于此同时,回响信号的输出端会从低电平跳转为高电平。发射出去的超声波经过前方障碍物的反射,产生相同频率的反射回波,超声波接收器接受到反射回波后,回响信号输出端会从高电平跳转为低电平。对于外部采集电路,需要利用定时器采集回响信号为高电平的总时长T秒,然后根据声音在空气中的传播速度344米/秒计算出模块到障碍物之间的距离D=T*344/2米。

STM32芯片中集成了强大的定时器模块,其工作状态主要有以下几种模式:输入捕获模式、PWM输入模式、强制输出模式、输出比较模式、PWM模式、单脉冲模式等。在本实验中需要用到的是定时器模块的输入捕获模式。当定时器工作在输入捕获模式下时,当芯片检测到ICx信号引脚上相应的跳变沿后,定时器会将当前的数值锁存在TIMx_CCRx(捕获/比较寄存器)中,同时,在TIMx_SR寄存器中相应的CCxIF标志位被置‘1’,若预先配置使能了中断操作,则同时会响应中断函数。

图1 HC-SR04超声波测距模块示意图

三、硬件连接和相关库函数介绍


图2 硬件连接示意图
TIM_TimeBaseInitTypeDef结构体参数的配置如下:

typedef struct
{uint16_t TIM_Prescaler; // 预分频器uint16_t TIM_CounterMode; // 计数模式uint32_t TIM_Period; // 定时器周期uint16_t TIM_ClockDivision; // 时钟分频uint8_t TIM_RepetitionCounter; // 重复计算器
} TIM_TimeBaseInitTypeDef;

(1) TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器时钟,它设定TIMx_PSC 寄存器的值。可设置范围为 0 至 65535,实现 1 至 65536 分频。
(2) TIM_CounterMode:定时器计数方式,可是在为向上计数、向下计数以及三种中心对齐模式。基本定时器只能是向上计数,即 TIMx_CNT 只能从 0 开始递增,并且无需初始化。
(3) TIM_Period:定时器周期,实际就是设定自动重载寄存器的值,在事件生成时更新到影子寄存器。可设置范围为 0 至 65535。
(4) TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与数字滤波器采样时钟频率分频比,基本定时器没有此功能,不用设置。
(5) TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可以非常容易控制输出 PWM 的个数。这里不用设置。

四、软件流程图

本实验中使用到的库文件有:oled.c显示屏库函数、sys.c系统库函数、delay.c延时库函数。实验的流程示意图如图3所示:

图3 程序流程示意图

【实验环境】

硬件设备

双轮自平衡机器人。如图4所示,在平衡车背面中间安装了HC-SR04超声波测距模块。
ST-Link下载器(包含USB线与下载线)。如图5所示。
操作系统:
Windows7/8/10,32bit/64bit


图4 双轮自平衡机器人

图5 ST-Link下载器与下载线

软件环境

Keil 5

实验场地

为了直观感受测距效果,试验场地最好设有平整无遮挡墙面。

【实验步骤】

第一步 配置工程环境

打开已经建立好的工程模板,在新建立的工程模板中已经添加五个文件夹,分别命名为USER、HARDWARE、SYSTEM、CORE、FWLib文件夹,如图6所示。其中USER文件夹存放的是主函数,HARDWARE文件夹存放的是本实验对应的硬件设备函数,SYSTEM存放的是本课程所有实验通用的函数,CORE文件夹存放的是启动文件,FWLib文件夹存放的是底层驱动函数。

图6 工程模板对应的文件夹
在HARDWARE文件夹下新建两个文件,分别为timer.c和timer.h。分别存放定时器行数的函数文件和头文件,如图7所示。

图7 在HARDWARE文件夹下建立tiner.c与timer.h文件

第二步 编写定时器函数,完成定时器的配置和启用

打开程序中的timer.c文件,首先将timer.h文件包含进来。其次对TIM3_Cap_Init 函数进行编写,选择要使用的时钟,输入捕获的引脚及其参数,并初始化定时器中断。

#include "timer.h"
/****************************************************************
函数功能:定时器3通道3输入捕获初始化
入口参数:arr::自动重载值  psc:时钟预分频数
返回值:无
****************************************************************/
TIM_ICInitTypeDef  TIM3_ICInitStructure;
void TIM3_Cap_Init(u16 arr,u16 psc)
{    //初始化结构体
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//(1) TIM时钟使能, GPIO 时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);    //使能GPIO 时钟
//(2) GPIO 端口模式设置
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0; //PBO输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//(3)初始化定时器3(TIM3)
TIM_TimeBaseStructure.TIM_Period = arr;    //设定计数器自动重载值
TIM_TimeBaseStructure.TIM_Prescaler =psc;    //预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TimeBaseStructure中指定的参数初始化TIMx的时间基数单位//(4)初始化TIM3输入捕获参数
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC1S=03选择输入端
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置不分频
TIM3_ICInitStructure.TIM_ICFilter = 0x00;  //配置输入滤波器,不滤波
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
//(5)中断分组初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   //先占优先级,2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级,0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
//(6) 使能捕获和更新中断
TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC3,ENABLE);  //允许更新中断,允许CC3IE捕获中断
//(7) 使能定时器
TIM_Cmd(TIM3, ENABLE);   //使能定时器3
}

编写超声波中断脉宽读取中断函数

void TIM3_IRQHandler(void)
{
u16 tsr;
tsr=TIM3->SR;
if((TIM3CH3_CAPTURE_STA&0X80)==0)  //还未成功捕获
{if(tsr&0X01)  //溢出{        if(TIM3CH3_CAPTURE_STA&0X40)  //已经捕获到高电平{if((TIM3CH3_CAPTURE_STA&0X3F)==0X3F) //高电平过长{TIM3CH3_CAPTURE_STA|=0X80; //标记成功捕获一次TIM3CH3_CAPTURE_VAL=0XFFFF;}else
TIM3CH3_CAPTURE_STA++;}    }
if(tsr&0x08)  //发生捕获事件
{
if(TIM3CH3_CAPTURE_STA&0X40)      //捕获到一个下降沿
{
TIM3CH3_CAPTURE_STA|=0X80; //标记成功捕获一次高电平脉宽
TIM3CH3_CAPTURE_VAL=TIM3->CCR3; //获取当前的捕获值
TIM3->CCER&=~(1<<9);  //CC1P=0 设置为上升沿捕获
}
else       //第一次捕获到上升沿
{TIM3CH3_CAPTURE_STA=0;  //清空
TIM3CH3_CAPTURE_VAL=0;
TIM3CH3_CAPTURE_STA|=0X40;  //标记捕获到了上升沿
TIM3->CNT=0;         //计数器清空
TIM3->CCER|=1<<9;       //CC1P=1 设置为下降沿捕获
}
}
}
TIM3->SR=0;  //清除中断标志位
}

(5)编写超声波接受回波函数,计算距离

/*************************************************************
函数功能:超声波接收回波函数
入口参数: 无
返回值: 无
*************************************************************/
// TIM3CH3_CAPTURE_STA与TIM3CH3_CAPTURE_VAL; 为定时器库里预定义变量,分别指代TIM3通道3的捕获状态寄存器和计时器捕获时间寄存器
void Read_Distane(void)
{   PBout(1)=1;delay_us(15);  PBout(1)=0; if(TIM3CH3_CAPTURE_STA&0X80)  //成功捕获到一次高电平{Distance=TIM3CH3_CAPTURE_STA&0X3F;Distance*=65536;               //溢出时间总和Distance+=TIM3CH3_CAPTURE_VAL;    //得到总的高电平时间Distance=Distance*170/1000;TIM3CH3_CAPTURE_STA=0;      //开启下一次捕获}
}

(6)打开timer.h,编写函数声明

#ifndef __TIMER_H
#define __TIMER_H
#include <sys.h>
void TIM3_Cap_Init(u16 arr,u16 psc);
void Read_Distane(void);
void TIM3_IRQHandler(void);
#endif

第三步 编写main.c文件

(7)将工程编译需要用到的头文件包含进来,并预定义显示函数和全局变量。
#include “timer.h” //包含定时器函数头文件
#include “sys.h” //包含系统头文件
#include “stm32f10x.h” //包含系统寄存器定义声明的头文件
void oled_show(void);
u32 Distance; //超声波测距变量
(8)在主函数中调用延时函数、显示函数和定时器函数的初始化函数。
int main(void)
{
delay_init(); //延时函数初始化
OLED_Init(); //OLED初始化
TIM3_Cap_Init(0XFFFF,72-1); //超声波初始化
(9)定义主循环,在主循环中调用超声波读取函数和显示函数
while(1)
{
Read_Distane();
oled_show();
delay_ms(500);
}
(10)编写OLED显示函数
void oled_show(void)
{
OLED_ShowString(00,20,“Distance”);
OLED_ShowNumber(95,20,Distance,4,12);
//=刷新==========//
OLED_Refresh_Gram();
}

第四步 编译并下载,观察实验现象

(11)本实验采用仿真器为STLink V2,将仿真器与小车相连,注意正负极不要接反,如图8所示。

图8仿真器与下载线连接图
(12)编译程序:点击如图9所示的编译按键。

图1.9 Keil编译环境下的编译按键
当编译完成后,如果没有问题,Build Output栏会出现无错误、无警告的提示,如图10所示。

图10 编译通过后Build Output栏提示信息
(13)下载程序:点击如图所示的下载按键,程序就会下载到STM32的芯片中。下载按键如图11所示。

图11 Keil编译环境下的下载按键
(14)观察实验现象,OLED显示屏上显示出当前超声波传感器测量的距离信息,改变超声波传感器与墙面的距离,观察数值的变化。

图12 平衡车上的超声波传感器测量数据

【思考题】

1、选择题

题目1:HC-SR04超声波传感器模块返回的数据类型是(D)
A:距离数值的数字信号
B:距离数值的模拟信号
C:发送接收时刻的脉冲信号
D:发送接收时刻的跳变沿信号

题目2:超声波传感器不能运用在以下哪种环境(C)
A:空气中
B:水中
C:真空中
D:固体中

2、简答题

题目1:STM32通用定时器分别有哪些工作模式?简单介绍输入输出模式的。

STM32通用定时器的工作模式有计数器模式、输入捕获模式、PWM输入模式、强制输出模式、PWM模式、单脉冲模式、编码器接口模式。

在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中。当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置’1’。

附录:TIM库函数


嵌入式课程 之 超声波传感器实验相关推荐

  1. 树莓派基础实验24:超声波测距传感器实验

    一.介绍    超声波传感器使用超声波来准确检测物体并测量距离.他发出超声波并将它们转换成电信号,主要应用于汽车的倒车雷达.机器人自动避障行走.建筑施工工地以及一些工业现场. 二.组件 ★Raspbe ...

  2. 超声波传感器与液晶屏显示实验

    实验二  超声波传感器与液晶屏显示实验 一.实验目的 了解液晶屏显示的基本原理以及电路连接. 二.实验内容  了解液晶屏的工作原理和工作情况. 三.实验仪器 导线若干,1602液晶显示屏,LY-F2 ...

  3. Arduino 入门学习笔记7 I2C LCD1602液晶显示实验 及 超声波传感器距离检测

    I2C 简介 I2C总线是由Philips公司开发的一种简单.双向二线制同步串行总线.它只需要两根线即可在连接于总线上的器件之间传送信息. 主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时 ...

  4. 基于超声波传感器的液位测量及控制系统设计(STM32)

    一.引言 随着工业的发展,计算机.微电子.传感器等高新技术的应用和研究,液位仪表的研制得到了长足的发展,以适应越来越高的应用要求.液位的测量在工业生产过程中已经起着相当重要的作用,其类型大概可以分为接 ...

  5. 利用STM32CubeMX配置基于STMF32F407的FREERTOS操作系统控制直流电机速度和超声波测距实验

    前两周做基于STM32F407芯片的嵌入式系统设计的实验,主要完成利用超声波测距(电脑上用串口显示超声波所测距离,障碍物近于20cm时,使LED灯闪烁,并且可以通过串口更改报警距离)和利用编码器读取电 ...

  6. 聊城大学理工学院-嵌入式课程设计-stm32f407小车

    最近两天有点偷懒了,什么都不想做,所以今天不接着弄上次的GPS模块了,今天就分享点别的-----大三时做的嵌入式课程设计.当时做好后也算是好几个班流传最广的版本了,所以多少还是很有点成就感的. 实现的 ...

  7. 超声波传感器特性测量:发送与接收传感器之间的差异

    简 介: 本文针对超声波传感器的测量方法,探讨了使用NanoVNA测量过程, 对比发射和接收传感器在特性方面的不同. 对于整个过程编写了APPLE脚本. 关键词: 超声波传感器,发送,接收,NanoV ...

  8. 嵌入式Linux结课报告,嵌入式课程报告.doc

    嵌入式课程报告 嵌入式系统及应用设计报告 题 目 嵌入式Linux系统移植 专 业 电子与通信工程 姓 名 王文平 学 号 1320610012 一.硬件设备介绍 此次实验用的板子是友善之臂的Mini ...

  9. c语言电子时钟课程设计报告,电子时钟嵌入式课程设计报告

    <电子时钟嵌入式课程设计报告>由会员分享,可在线阅读,更多相关<电子时钟嵌入式课程设计报告(19页珍藏版)>请在人人文库网上搜索. 1.合海大学计算机信息工程学院(常州)课程设 ...

  10. 几块钱的超声波也能仿真?ROS2仿真之添加超声波传感器

    大家好,我是小鱼,最近有些偷懒了,对了,ROS2的第一个五年支持版本发布了,动手学ROS2相关课程和文档也开始正式迁移至Humble版本啦~ 本节是拓展章节,主要讲解一下如何给FishBot添加一个超 ...

最新文章

  1. 高频开关电源原理_程控开关电源的工作原理
  2. 《JavaScript设计模式与开发实践》模式篇(5)—— 观察者模式
  3. LeetCode Algorithm 1566. 重复至少 K 次且长度为 M 的模式
  4. LVS负载均衡DR模式实现
  5. mysql 恢复root用户_mysql误删root用户恢复方案
  6. netcore实践:跨平台动态加载native组件
  7. [html] 使用递归时应该注意哪些问题?
  8. android 微信支付,body为中文字符,签名错误
  9. idea ssm项目移包报错问题
  10. Redis系列教程(八):分布式锁的由来、及Redis分布式锁的实现详解
  11. TensorFlow全球下载量破1亿,Jeff Dean激动不已
  12. parseInt 的使用方式,基数表达
  13. 基于Spring + Spring MVC + Mybatis 高性能web构建
  14. 一款非常牛逼的 Java 爬虫框架!(请低调使用)
  15. 史上最全的 Java 高质量博客与网站推荐(国内篇)
  16. 金九银十,23届秋招信息超全汇总表!各大名企优质岗位持续更新中···
  17. Ubuntu18.04无法安装软件的问题
  18. K - Tourists' Tour(图染色)
  19. ViewPager的翻页动画
  20. Uni-App 简单引导页示例

热门文章

  1. C语言实现循环缓冲fifo及总结
  2. 认知电子战 (1.3):认知电子战概述
  3. matlab 保存.fig文件后无法保存的问题
  4. java px pt转化_pt和px的转换
  5. Word怎么压缩变小?压缩word文档不妨试试这个方法
  6. 贪心科技机器学习训练营(十二)
  7. 在张朝阳的直播间里,没有搜狐的未来
  8. openwrt中br-lan,eth0,eth0.1,eth0.2
  9. 浅谈 Mlp-Mixer(pytorch and keras)
  10. Linux系统中修复SambaCry漏洞(CVE-2017-7494)