一 操作流程

二 传感器指标与信息
基本信息
- 工作电压:通常为5V3。
- 工作电流:静态工作电流小于5mA,最大工作电流约为15mA2。
- 测量范围:2cm至400cm,某些版本可能支持更远的测量距离3。
- 测量精度:可达3mm3。
- 工作频率:40kHz2。
- 工作温度:通常为-10℃至70℃1。
阴脚定义
- VCC:电源正极,通常接5V。
- Trig:触发信号输入,用于启动测距。
- Echo:回响信号输出,用于接收测距结果3。
- GND:电源负极,接地。
代码实现
配置GPIO口

超声波测距的实现
测速时序图 
代码实现函数

实现总架构
内核层:device.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
static void hcsr04_release(struct device *dev);
static struct resource res[] = {
[0] = {
.start = 0x56000050,
.end = 0x56000050 + 8 - 1,
.name = "GPF",
.flags = IORESOURCE_MEM,
},
};
static struct platform_device hcsr04_device = {
.name = "hcsr04",
.id = -1,
.dev.release = hcsr04_release,
.resource = res,
.num_resources = sizeof(res) / sizeof(res[0]),
};
static void hcsr04_release(struct device *dev)
{
return;
}
static int __init init_hcsr04_device(void)
{
int ret = 0;
ret = platform_device_register(&hcsr04_device);
if (ret != 0)
{
return -1;
}
printk("platform hcsr04 device register success!\n");
return 0;
}
static void __exit exit_hcsr04_device(void)
{
platform_device_unregister(&hcsr04_device);
printk("platform hcsr04 device unregister success!\n");
return;
}
module_init(init_hcsr04_device);
module_exit(exit_hcsr04_device);
MODULE_LICENSE("GPL");
内核层:drive.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
static volatile unsigned int *pGPFBase = NULL;
static int hcsr04_probe(struct platform_device *device);
static int hcsr04_open(struct inode *node, struct file *fp);
static ssize_t hcsr04_read(struct file *fp, char __user *puser, size_t n, loff_t *off);
static int hcsr04_release(struct inode *node, struct file *fp);
#define SET_TRIG_OUT (*(pGPFBase+0) = ((*(pGPFBase+0) & ~(0x3)) | (0x1)))
#define SET_TRIG_IN (*(pGPFBase+0) = ((*(pGPFBase+0) & ~(0x3))))
#define SET_TRIG_HIGH (*(pGPFBase+1) = ((*(pGPFBase+1)) | (0x1)))
#define SET_TRIG_LOW (*(pGPFBase+1) = ((*(pGPFBase+1)) & ~(0x1)))
#define GET_TRIG_STAT (*(pGPFBase+1) & (0x1))
#define SET_ECHO_OUT (*(pGPFBase+0) = ((*(pGPFBase+0) & ~(0x3 << 2)) | (0x1 << 2)))
#define SET_ECHO_IN (*(pGPFBase+0) = ((*(pGPFBase+0) & ~(0x3 << 2))))
#define SET_ECHO_HIGH (*(pGPFBase+1) = ((*(pGPFBase+1)) | (0x1 << 1)))
#define SET_ECHO_LOW (*(pGPFBase+1) = ((*(pGPFBase+1)) & ~(0x1 << 1)))
#define GET_ECHO_STAT (*(pGPFBase+1) & (0x1 << 1))
static struct platform_driver hcsr04_driver = {
.probe = hcsr04_probe,
.driver.name = "hcsr04",
};
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = hcsr04_open,
.read = hcsr04_read,
.release = hcsr04_release,
};
static struct miscdevice misc_hcsr04 = {
.minor = MISC_DYNAMIC_MINOR,
.name = "hcsr04",
.fops = &fops,
};
static int hcsr04_open(struct inode *node, struct file *fp)
{
SET_TRIG_OUT;
SET_TRIG_LOW;
SET_ECHO_OUT;
SET_ECHO_LOW;
return 0;
}
static int hcsr04_release(struct inode *node, struct file *fp)
{
SET_TRIG_OUT;
SET_TRIG_LOW;
SET_ECHO_OUT;
SET_ECHO_LOW;
return 0;
}
static ssize_t hcsr04_read(struct file *fp, char __user *puser, size_t n, loff_t *off)
{
unsigned int consttime = 0;
//发送声波
SET_TRIG_HIGH;
udelay(10);
SET_TRIG_LOW;
SET_ECHO_IN;
while (!GET_ECHO_STAT);
while (GET_ECHO_STAT)
{
consttime++;
udelay(1);
}
SET_ECHO_OUT;
SET_ECHO_LOW;
copy_to_user(puser, &consttime, sizeof(consttime));
return sizeof(consttime);
}
static int hcsr04_probe(struct platform_device *device)
{
int ret = 0;
ret = misc_register(&misc_hcsr04);
if (ret != 0)
{
return -1;
}
pGPFBase = ioremap(device->resource[0].start, device->resource[0].end - device->resource[0].start);
if (NULL == pGPFBase)
{
return -1;
}
return 0;
}
static int __init init_hcsr04_driver(void)
{
int ret = 0;
ret = platform_driver_register(&hcsr04_driver);
if (ret != 0)
{
return -1;
}
printk("platform hcsr04 driver init success!\n");
return 0;
}
static void __exit exit_hcsr04_driver(void)
{
platform_driver_unregister(&hcsr04_driver);
printk("platform hcsr04 driver exit success!\n");
return;
}
module_init(init_hcsr04_driver);
module_exit(exit_hcsr04_driver);
MODULE_LICENSE("GPL");
应用层代码实现:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdlib.h>
int main(void)
{
int fd = 0;
unsigned int costtime = 0;
ssize_t nret = 0;
fd = open("/dev/hcsr04", O_RDWR);
if (-1 == fd)
{
perror("fail to open");
return -1;
}
while (1)
{
nret = read(fd, &costtime, sizeof(costtime));
printf("%.2lf cm\n", (0.034 * costtime) / 2);
sleep(1);
}
close(fd);
return 0;
}