SR04 超声波测距模块

news2025/2/22 16:12:48

文章目录

  • 前言
  • 一、SR04 模块介绍
  • 二、设备树设置
  • 三、驱动程序
  • 四、测试程序
  • 五、上级测试及效果
  • 总结


前言

超声波测距模块 是利用超声波来测距。模块先发送超声波,然后接收反射回来的超声波,由反射经历的时间和声音的传播速度 340m/s,计算得出距离。本实验采用 中断 的方法,来进行测距。


一、SR04 模块介绍

在这里插入图片描述
引脚 :VCCTrigEchoGND
Trig脉冲触发 引脚.
Echo回响接收 引脚.

测距原理 :

  1. 触发:
    向Trig(脉冲触发引脚)发出一个大约10us的高电平。
  2. 发出超声波,接收反射信号:
    模块就自动发出8个40Khz的超声波,超声波遇到障碍物后反射回来,模块收到返回来的超声波。
  3. 回响:
    模块接收到反射回来的超声波后,Echo引脚输出一个与检测距离成比例的高电平。
    我们只要在该引脚为高时,开启定时器计数,在该引脚变为低时,结束定时器计数。根据定时器的计数和定时器频率就可以算出经历时间,根据时间即可推导出距离。
    在这里插入图片描述

二、设备树设置

设备树 中 compatible 与 驱动程序 进行匹配。
通过原理图可知 TrigEcho 引脚是低电平有效,将其分别接到 开发板的 gpio4-19gpio4-20 引脚。每一组 GPIO 有 32 个引脚。

配置设备树需要对 GPIO 引脚 以及相关的 pincontrol 配置。由于本实验是使用 SR04 模块,所以不需要配置 pincontrol 。

在这里插入图片描述

三、驱动程序

  1. 首先 定义、注册一个file_operations 结构体。read 函数便于读取引脚电平。major 是返回的主设备号。

在入口函数里进行 class_create 创建类 , device_create 创建设备节点,register_chrdev 注册 file_operations 结构体。
出口函数里 device_destroyclass_destroy 将其逐个销毁 ,platform_driver_unregister 卸载 file_operations 结构体 。

函数的详细使用可参考 上一篇文章:SR501人体红外模块

	static struct file_operations sr04_fops = {
		.owner	 = THIS_MODULE,
		.read    = sr04_drv_read,
	};

	/* 注册结构体 */
	major = register_chrdev(0, "sr04", &sr04_fops);  
  1. 定义、注册一个platform_driver
    ask100_sr04 用于 设备树和驱动设备匹配。
static const struct of_device_id ask100_sr04[] = {
    { .compatible = "my,sr04"},
    { },
};

static struct platform_driver sr04s_driver = {
    .probe      = sr04_probe,
    .remove     = sr04_remove,
    .driver     = {
        .name   = "100ask_sr04",
        .of_match_table = ask100_sr04,
    },
};

/* 注册 platform_driver */
err = platform_driver_register(&sr04s_driver);
  1. probe 函数里进行 获取引脚,并对其引脚 初始化。
    使用 gpiod_get 获取对应引脚。参数二 是对应引脚的名字(设备树中自定义节点中的引脚名)。
	/* 设置 trig 初始化时为低电平状态 */
	trig_gpio = gpiod_get(&pdev->dev, "trig",GPIOD_OUT_LOW);
	
	/* 设置 echo初始化时为输入引脚 */
	echo_gpio = gpiod_get(&pdev->dev, "echo",GPIOD_IN);

在这里插入图片描述

  1. 获取中断号 irq ,request_irq 请求中断。

前面了解到 echo 为输入引脚,trig 为 输出引脚。 (获取中断号 和 请求中断 可以在 probe 函数里实现。)

	/* 获取中断号 */
	irq = gpiod_to_irq(echo_gpio);

	/* 申请中断 */
	request_irq(irq, sr04_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr04", NULL);

那什么时候发生中断呢?

request_irq 函数里 可以看到 参数三 IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING。当 电平处于上升沿 或者 下降沿时发生中断(电平发生变化)。

  • 当 电平由 低变高 时,触发中断,记录时间为 t1。此时并不唤醒处于休眠的函数。
  • 当 电平由 高变低 时,触发中断,记录时间为 t2。t = t2 - t1 。 t 是 超声波 从发出到接受的时间,就是声波在待测距离上的往返时间。 这时 就可以唤醒休眠的 read 函数了。

read 函数读取时间 t 后,即可在测试程序中 算出距离 D = 340 * t / 2
在这里插入图片描述

  1. 在 入口函数里 初始化等待队列头。
static wait_queue_head_t sr04_wq;				 // 定义等待队列头对象

init_waitqueue_head(&sr04_wq);					// 初始化等待队列头
  1. 中断处理函数,wake_up 唤醒 休眠函数。
    触发中断后调用中断处理函数。

gpiod_get_value 获取相应引脚电平。

ktime_get_ns(); 获取内核启动到现在的时间,在挂起时会暂停。单位是 ns (纳秒)

wake_up 唤醒 在 read 函数里休眠的队列。

static irqreturn_t sr04_isr(int irq, void *dev_id)
{
	int val = gpiod_get_value(echo_gpio);

	if(val)
	{
		sr04_data_ns = ktime_get_ns();			//获取上升沿时的时间
	}
	else
	{
		sr04_data_ns = ktime_get_ns() - sr04_data_ns;		//获取下降沿时的时间,并相减得到高电平时间
		wake_up(&sr04_wq);							//唤醒队列
	}
	
	return IRQ_HANDLED; // IRQ_WAKE_THREAD;
}
  1. 实现 read 函数。
    wait_event_interruptible_timeout 负责 等待队列和超时控制。它的作用是使当前执行的线程(或进程)进入睡眠状态,直到满足指定的条件,或者经过指定的时间。
    gpiod_set_value 设置 trig 输出 不少于 10 us 的高电平。
static ssize_t sr04_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	int timeout=0;

	/* 发送10us高电平    , 测量距离 2cm-450cm */
	gpiod_set_value(trig_gpio, 1);
	udelay(15);
	gpiod_set_value(trig_gpio, 0);

	timeout = wait_event_interruptible_timeout(sr04_wq, sr04_data_ns, HZ);
	if(timeout)
	{
		copy_to_user(buf, &sr04_data_ns, 4);
		sr04_data_ns = 0;
		return 4;
	}
	else
	{
		return -EAGAIN;
	}
}

四、测试程序

判断参数,打开文件,读取电平。若引脚为高电平 则读取距离,否则读取错误。

	if (argc != 2) 
	{
		printf("Usage: %s <dev>\n", argv[0]);
		return -1;
	}
	fd = open(argv[1], O_RDWR);
	if (fd == -1)
	{
		printf("can not open file %s\n", argv[1]);
		return -1;
	}
	
	while (1)
	{
		if (read(fd, &ns, 4) == 4)
		{
			printf("get distance: %d ns\n", ns);
			printf("get distance: %d mm\n", ns*340/2/1000000);  /* mm */
		}
		else
			printf("get distance: -1\n");
		sleep(1);
	}
	close(fd);

五、上级测试及效果

执行 insmod 命令可以将 .ko 文件加载到内核中,再 执行测试程序。(rmmod命令可以卸载已加载的模块,lsmod 命令 可以观察已加载到内核的文件。)
在这里插入图片描述
将 遮挡物 置于 超声波模块 前,前后移动即可。 /dev/sr04 是 驱动程序中创建的设备节点( device_create )。
在这里插入图片描述


总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/785292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指offer40.最小的k个数

简直不要太简单了这道题&#xff0c;先给数组排个序&#xff0c;然后输出前k个数就好了。我用的是快排&#xff0c;这是我的代码&#xff1a; class Solution {public int[] getLeastNumbers(int[] arr, int k) {int n arr.length;quickSort(arr, 0, n-1);int[] res new int…

Mysql 简介

Mysql 简介 学习目的 MySQL作为目前最流行的关系型数据库管理系统之一&#xff0c;因其开源免费的特性&#xff0c;成为小型Web应用的重点关注对象。几乎所有的动态Web应用基本都在使用MySQL作为数据管理系统。学习MySQL的目的也是为了更好地理解数据库相关的SQL注入漏洞&…

【性能优化】MySQL百万数据深度分页优化思路分析

业务场景 一般在项目开发中会有很多的统计数据需要进行上报分析&#xff0c;一般在分析过后会在后台展示出来给运营和产品进行分页查看&#xff0c;最常见的一种就是根据日期进行筛选。这种统计数据随着时间的推移数据量会慢慢的变大&#xff0c;达到百万、千万条数据只是时间问…

关于脑电睡眠分期,你应该知道的还有这些

导读 基于电生理信号(EEG&#xff0c;EOG和EMG)对睡眠阶段进行识别的建议源自Rechtschaffen和Kales手册&#xff0c;由美国睡眠医学学会于2007年发布&#xff0c;并定期更新多年。这些建议对于评估不同类型的睡眠/觉醒主观评定中的客观标志物非常重要。凭借研究的简单、可重复…

windows/linux/mac上编译open3d 0.17.0

目录 写在前面准备编译windows:linux/mac:注&#xff1a; 参考完 写在前面 1、本文内容 windows/linux/mac上编译open3d 0.17.0 2、平台 通过cmake构建项目&#xff0c;跨平台通用 3、转载请注明出处&#xff1a; https://blog.csdn.net/qq_41102371/article/details/1318918…

基于C++的QT基础教程学习笔记

文章目录&#xff1a; 来源 教程社区 一&#xff1a;QT下载安装 二&#xff1a;注意事项 1.在哪里写程序 2.如何看手册 3.技巧 三&#xff1a;常用函数 1.窗口 2.相关 3.按钮 4.信号与槽函数 5.常用栏 菜单栏 工具栏 状态栏 6.铆接部件 7.文本编辑 8…

[ELK安装篇]:基于Docker虚拟容器化(主要LogStash)

文章目录 一&#xff1a;前置准备-(参考之前博客)&#xff1a;1.1&#xff1a;准备Elasticsearch和Kibana环境&#xff1a;1.1.1&#xff1a;地址&#xff1a;https://blog.csdn.net/Abraxs/article/details/128517777 二&#xff1a;Docker安装LogStash(数据收集引擎&#xff…

SH-FAPI-4,新型tumor显像剂,其中FAPI通过与FAP结合

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ SH-FAPI-4 其中FAPI通过与FAP结合&#xff0c;可在PET-CT扫描中可视化tumor的位置和大小&#xff0c;从而帮助确定tumor的类型和位置&#xff0c;并指导tumor treatment的选择。FAPI被认为是一种具有潜在应用前景的新型tu…

vue检测数据变化的原理

vue监测数据变化的原理 vue会监视data中所有层次的数据。 监测对象类型的数据 原理 vue监测对象类型的数据通过setter实现&#xff0c;且要在new Vue时就传入要监测的数据。 对象中后追加的属性&#xff0c;Vue默认不做响应式处理&#xff1b;如需后续添加的属性做响应式&am…

吉林大学计算机软件考研经验贴

文章目录 简介政治英语数学专业课 简介 本人23考研&#xff0c;一战上岸吉林大学软件工程专硕&#xff0c;政治72分&#xff0c;英一71分&#xff0c;数二144分&#xff0c;专业课967综合146分&#xff0c;总分433分&#xff0c;上图&#xff1a; 如果学弟学妹需要专业课资料…

STM32MP157驱动开发——按键驱动(定时器)

“定时器 ”机制&#xff1a; 内核函数 定时器涉及函数参考内核源码&#xff1a;include\linux\timer.h 给定时器的各个参数赋值&#xff1a; setup_timer(struct timer_list * timer, void (*function)(unsigned long),unsigned long data)&#xff1a;设置定时器&#xf…

HALCON error #5504 Image too large for this HALCON version in operator问题解决

目录&#xff1a; 一&#xff0c;问题概述&#xff1a;二&#xff0c;解决方法 一&#xff0c;问题概述&#xff1a; &#x1f300;当你直接或间接使用Halcon来做图像读取的时候&#xff0c;你可能遇到5504错误&#xff1a;HalconDotNet.HOperatorException:HALCON error #5504…

传奇开区网站打开跳转到别的网站处理教程

打开跳转被劫持到其他网站如何处理教程。 在解决劫持之前&#xff0c;需要先确定一下身份&#xff0c;如果是网站被劫持了&#xff0c;或者是访客访问自己的网站被劫持到其他的网站上&#xff0c;解决起来的方法不一样&#xff0c;下面一休分类分享给大家 1、访客身份处理方法…

opencv-19 图像色彩空间转换函数cv2.cvtColor()

cv2.cvtColor() 函数是 OpenCV 中用于图像颜色空间转换的函数。它允许你将图像从一个色彩空间转换为另一个色彩空间。在 Python 中&#xff0c;你可以使用这个函数来实现不同色彩空间之间的转换。 函数的基本语法为&#xff1a; cv2.cvtColor(src, code[, dst[, dstCn]])参数…

提高可视性的五大方法可增强 Horizon Cloud 下一代平台的性能和用户体验

我们在 VMware Explore US 2022 推出了 VMware Horizon Cloud 下一代平台。该平台为使用现代化虚拟桌面和应用的客户提供了一个新的混合型桌面服务&#xff08;DaaS&#xff09;架构&#xff0c;其围绕降低成本和提高可扩展性而构建。首次发布后&#xff0c;我们在 VMware Expl…

Java | 数组排序算法

一、冒泡排序 冒泡排序的基本思想是对比相邻的元素值&#xff0c;如果满足条件就交换元素值&#xff0c;把较小的元素移到数组前面&#xff0c;把较大的元素移到数组后面&#xff08;也就是交换两个元素的位置&#xff09;&#xff0c;这样较小的元素就像气泡一样从底部升到顶…

Python2、python3的安装

目录 一、环境搭建和简单命令 1. 关于交互模式 2.执行文件 3. print 4. 安装/卸载包 5. 查看安装了哪些包 6. 升级pip本身 7. 查看包的具体信息 8. 搜索含有nose 9. 所有包升级到最新版本 二、其他说明 1. –m的使用 2. 切换盘符 资料获取方法 一、环境搭建和简单…

vue3 项目打包后白屏

根据Vue3.x文档&#xff0c;在 vue.config.js/vite.config.ts 统一对webpack、跨域、端口号等属性进行配置。 1.在 vue.config.js/vite.config.ts添加publicPath属性并将值更改成 ‘./’ 在这里插入图片描述 2.若还没有解决就去路由中将history模式设置成默认的Hash模式&…

MATLAB与ROS联合仿真——Simulink生成ROS代码

当我们用simulink完成控制程序的搭建后&#xff0c;我们期望下一次可以直接对ROS进行控制&#xff0c;而不是每次都需要启动matlab和simulink&#xff0c;因此我们可以使用simulink的代码生成器&#xff0c;生成ROS代码 1、生成代码前需要进行如下的设置 &#xff08;1&#xf…

Fuzz测试:提升自动驾驶安全性

目录 什么是Fuzz测试&#xff1f; 自动驾驶的潜在风险 Fuzz测试&#xff1a;自动驾驶和车联网 Fuzz测试方法有以下几种&#xff1a; 资料获取方法 纵观近百年来汽车制造业的发展历程&#xff0c;产业跨进的每一步背后都有着技术创新作为支撑。汽车技术创新对世界经济、社会…