十五、【SR04】超声波测距模块驱动
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
#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;
}