超声波测距驱动


/****************************************
* 文件名:   ceju.c
* 作者:     GTY
* 时间:     2016-11-10
* 文件说明: 超声波测距驱动实现文件
****************************************/


/*头文件*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <asm/uaccess.h>


#define   EINT14             S3C2410_GPG6//echo
#define   E14_IN         S3C2410_GPG6_INP
#define   E14_OUT        S3C2410_GPG6_OUTP


#define   EINT15             S3C2410_GPG7//trig
#define   E15_IN         S3C2410_GPG7_INP
#define   E15_OUT        S3C2410_GPG7_OUTP


#define   EINT19             S3C2410_GPG11//echo
#define   E19_IN         S3C2410_GPG11_INP
#define   E19_OUT        S3C2410_GPG11_OUTP


struct cdev cdev;                    //字符设备结构体,静态分配 
dev_t devno;                         //设备号
unsigned long ret=0x0;                   




/*宏定义命令*/


#define L  0     //超声波测距命令1
#define H  1    //超声波测距命令2


#define DEVICE_NAME "ceju"  
#define chaoshen_MAJOR 230


/****************************************
* 函数名:  CEJU_Open()
* 入口参数:struct inode *node:inode文件结构体;struct file *filp:file文件结构体
* 出口参数:返回0
* 函数功能:文件打开函数
****************************************/
int Ceju_Open(struct inode *node, struct file *filp)
{
	s3c2410_gpio_cfgpin(EINT15, CPG_OUT);   // 配置GPG11输出模式
  s3c2410_gpio_cfgpin(EINT19, CPG_OUT);   // 配置GPG11输出模式
  
  s3c2410_gpio_setpin(EINT15, 1); // 向18B20发送一个上升沿
  
  s3c2410_gpio_setpin(EINT19, 1); // 向18B20发送一个上升沿
	
	return 0;
}


/****************************************
* 函数名:  Ceju_Ioctl()
* 入口参数:struct file *filp:文件结构指针;
            unsigned int cmd:控制命令;
            unsigned long arg:命令参数
* 出口参数:成功:返回0;失败:返回-EINVAL
* 函数功能:命令控制函数
****************************************/
long Ceju_Ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch (cmd)
	{
	    case L:
	    		s3c2410_gpio_cfgpin(EINT15, E15_OUT);   
	        s3c2410_gpio_setpin(EINT15, 0);
	        return 0;
	    
	    case H:
	    		s3c2410_gpio_cfgpin(EINT15, E15_OUT);   
	        s3c2410_gpio_setpin(EINT15, 1);
	        return 0;


	    default:
	    	return -EINVAL;
	}
}




/****************************************
* 函数名:  Ceju_Read
* 入口参数:struct file *filp:文件指针
            char __user *buf:存放读取数据的缓冲区
            size_t size:读取的数据大小
            loff_t *p:文件偏移量
* 出口参数:返回4
* 函数功能:按键读取数据
****************************************/
ssize_t Ceju_Read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
{
		s3c2410_gpio_cfgpin(EINT19, E19_IN); 
    ret = s3c2410_gpio_getpin(EINT19); 	
    copy_to_user(buf, &ret, 4);
  
    return 4;
}


/*文件操作结构体*/
static struct file_operations ceju_fops =
{
    .open = Ceju_Open,
    .unlocked_ioctl = Ceju_Ioctl,
    .read = Ceju_Read,


};


static char __initdata banner[] = "TQ2440/SKY2440 ceju\n";//打印信息
static struct class *ceju_class;
static int Ceju_Init()
{
  int ret;
 printk(banner);
 ret = register_chrdev(ceju_MAJOR, DEVICE_NAME, &ceju_fops);
 if (ret < 0)
 {
  printk(DEVICE_NAME " can't register major number\n");
  return ret;
 }//错误处理
 
 ceju_class = class_create(THIS_MODULE, DEVICE_NAME);
 if(IS_ERR(ceju_class))
 {
  printk("Err: failed in tope-leds class. \n");
  return -1;
 }
 device_create(ceju_class, NULL, MKDEV(ceju_MAJOR, 0), NULL, DEVICE_NAME);//创建一个设备节点,节点名为DEVICE_NAME
 printk(DEVICE_NAME " initialized\n");//打印信息,内核中的打印用printk函数
 return 0;
}


/****************************************
* 函数名:  Ceju_Exit()
* 入口参数:无
* 出口参数:无
* 函数功能:模块卸载函数
****************************************/
static void Ceju_Exit()
{
	printk(DEVICE_NAME " exit\n");//打印信息,内核中的打印用printk函数
  unregister_chrdev(ceju_MAJOR, DEVICE_NAME);//取消注册设备
  device_destroy(ceju_class, MKDEV(ceju_MAJOR, 0)); //删掉设备节点
  class_destroy(ceju_class);     //注销类
}


MODULE_LICENSE("GPL");                       //遵守的协议


module_init(Ceju_Init);
module_exit(Ceju_Exit);

以下是应用程序

/****************************************
* 文件名:   ceju.c
* 作者:     GTY
* 时间:     2016-11-10
* 文件说明: 超声波测距
****************************************/

/*头文件*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>

/*宏定义命令*/

#define L  0     //超声波测距命令1
#define H  1    //超声波测距命令2

int main(int argc, char **argv)
{
    int fd;
    unsigned long ret,timeuse;
    int i = 0;
		struct timeval start,end;
		
    fd = open("/dev/ceju", O_RDWR);
    
    if (fd<0)
        printf("open fail\n");
		
    ioctl(fd,L);
    usleep(10);
    ioctl(fd,H);
    usleep(15);
    ioctl(fd,L);
   
    while(1)
    {
    read(fd, &ret, 4);
    if (1 == ret)break;
    
    	gettimeofday(&start,NULL);
    	while(1)
    	{
    		read(fd, &ret, 4);
   			if(0 == ret) break;
   			
    	}
    	gettimeofday(&end,NULL);
    	timeuse = (1000000*(end.tv_sec-start.tv_sec)+(end.tv_usec-start.tv_usec));
    	distance = 345* timeuse / 2000000;
    	printf("ceju is %d cm\n",distance);
   	//	break;
    
		}
		
    }
    
    close(fd);

    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值