十三、【SR04】超声波测距模块驱动


 

 1、代码


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 
#include 
#include 
#include 
#include 
#include 
#include 

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;

}