十五、【SR04】超声波测距模块驱动
1、代码
1 |
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/gpio.h>
#include <cfg_type.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <mach/platform.h>
#include <mach/devices.h>
#include <mach/soc.h>
static ssize_t sr04_read(struct file *filp, char __user * buf, size_t size, loff_t *oft)
{
int ret;
unsigned int sr04distance=0,count=0;
//float timestart=0;
//bool flag=false;
if(size!=4)
{
return -EINVAL;
}
gpio_set_value(PAD_GPIO_E + 13,1);
udelay(12);
gpio_set_value(PAD_GPIO_E + 13,0);
while(!gpio_get_value(PAD_GPIO_C+17))
{
count++;
udelay(1);
if(count>10000)
{
printk("timeout\n");
return -EAGAIN;
}
}
count =0;
//340m/s-->340000mm/1000000us=0.34mm/us
/*3mm/0.34 = 8.82....us 约等于 9us 也就是说一个3mm就需要9us*/
while(gpio_get_value(PAD_GPIO_C + 17) == 1)
{
udelay(9);
if(count > 30000 )
{
printk("timeout\n");
return -EAGAIN;
}
count++; //一个count对应3mm
}
count = count /2; //超声波一个来回,除以2
sr04distance = count*3/10;//CM
ret = copy_to_user(buf, &sr04distance, size);
if(ret != 0)
{
return (size -ret);
}
return size;
}
struct file_operations sr04_misc_fops=
{
.read= sr04_read,
};
static struct miscdevice sr04_misc={
.minor = MISC_DYNAMIC_MINOR,
.name = "sr04_misc",
.fops = &sr04_misc_fops,
};
static int __init sr04_init(void)
{
int ret;
printk(KERN_INFO"sr04_init\n");
ret = misc_register(&sr04_misc);
if(ret < 0)
{
printk(KERN_INFO"sr04 misc register fail.\n");
goto misc_register_err;
}
ret = gpio_request(PAD_GPIO_E+13, "gpio_trig");
if(ret < 0)
{
printk(KERN_INFO"gpio_trig request fail.\n");
goto gpio_trig_request_err;
}
gpio_direction_output(PAD_GPIO_E+13, 0);
ret = gpio_request(PAD_GPIO_C+17, "gpio_echo");
if(ret < 0)
{
printk(KERN_INFO"gpio_echo request fail.\n");
goto gpio_echo_request_err;
}
gpio_direction_input(PAD_GPIO_C+17);
return 0;
gpio_echo_request_err:
gpio_free(PAD_GPIO_E+13);
gpio_trig_request_err:
misc_deregister(&sr04_misc);
misc_register_err:
return ret;
}
static void __exit sr04_exit(void)
{
printk(KERN_INFO"sr04__exit\n");
gpio_free(PAD_GPIO_E+13);
gpio_free(PAD_GPIO_C+17);
misc_deregister(&sr04_misc);
}
module_init(sr04_init);
module_exit(sr04_exit);
MODULE_LICENSE("GPL");
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <stdio.h> #include <sys/ioctl.h> int main( void ) { int distance = 0; int ret; int fd = open( "/dev/sr04_misc" ,O_RDWR); if (fd < 0) { perror ( "open failed" ); return -1; } while (1) { ret = read(fd,&distance,4); if (ret <0) { perror ( "read failed" ); continue ; } printf ( "distance = %d CM\n" ,distance); usleep(200*1000); } close(fd); return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2019-12-26 DVB-T和DVB-T2区别
2017-12-26 socket网络编程
2017-12-26 Python正则表达式
2017-12-26 python类的使用