完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
#include
#include #include #include #include #include #include #include #include #include #include #include #include #define DS18B20_DEVICE_NAME "DS18B20" #define DS18B20_DEVICE_FILENAME "/dev/DS18B20" typedef unsigned char uchar ; //////////////////////设定寄存器使io为输入状态///////////// void shuru(void ) { uint tmp; tmp=readl(S3C64XX_GPNCON); //设置GPN寄存器,使用GPN的io口可以输入输出,读出GPNCON内部存的值 tmp &= 0xFFFCFFFF; //设置寄存器的16口为0,17口为0使其为输入状态 writel(tmp,S3C64XX_GPNCON); //在写入回到GPNCON中,设定为输入io } ///////////////////////设定寄存器使io为输出状态///////////////////////////// void shuchu(void) { uint tmp; tmp=readl(S3C64XX_GPNCON); //设置GPN寄存器,使用GPN的io口可以输入输出,读出GPNCON内部存的值 tmp |= 0x00010000; //设置寄存器的16口为1,17口为0 writel(tmp,S3C64XX_GPNCON); //在写入回到GPNCON中,设定为输出io } //////////////////////////把io口拉高//////////////////// void tmph(void) { uint tmp; tmp=readl(S3C64XX_GPNDAT); //读取p1.30口的值 tmp|=0x00000100; //把io口电平拉高 writel(tmp,S3C64XX_GPNDAT); //写入到18b20 } //////////////////////////把io口拉低//////////////////// void tmpl(void) { uint tmp; tmp=readl(S3C64XX_GPNDAT); //读取p1.30口的值 tmp&=0xFFFFFEFF; //把io口电平拉低 writel(tmp,S3C64XX_GPNDAT); //写入到18b20 } ///////////////////////////////初始化18b20///////////////////////// uchar reset(void) { uint tmp; uchar fuwei; shuchu(); //设置为输出状态 tmph(); //拉高io口 tmpl(); //拉低io口 udelay(400); //延迟400us tmph(); //拉高io口 udelay(80); //延迟80us tmp=readl(S3C64XX_GPNDAT); //读出GPNSAT内部存的值 udelay(150); //延迟150us tmp&=0x00000100; tmp>>=8; fuwei=tmp; tmph(); return fuwei; //返回存在信号 } ////////////////////写一个位进去//////////////////// void wrbt(uchar bite) { shuchu(); tmpl(); //把io口拉低 if(bite==1) tmph(); //把io拉高 udelay(30); //延迟30us tmph(); //释放总线 udelay(15); //稍作延迟 } /////////////////读一个位出来//////////////////////// uchar rdbt(void) { uint i=0; uchar m=0; shuru(); tmpl(); //拉低 udelay(1); tmph(); //拉高 udelay(10); //延时不得超过4us i=readl(S3C64XX_GPNDAT); //读取io口的值 udelay(10); i=(i>>8); //读出的值(第一次为最低位) m=(i&0x01); printk("%daaaaan ",m); return m; //返回读出的值 } //////////////////写一个字节///////////////////////// void wrbyte(uchar k) { uchar i=0,tmp=0; for(i=0;i<8;i++) { tmp=(k>>i); //先写第一位数值 tmp=tmp&0x01; wrbt(tmp); //调用函数写入值 udelay(100); //延时保证写入 } } ///////////////////读一个字节////////////////////////// uchar rdbyte(void) { uchar i=0,n=0,tmp=0; for(i=0;i<8;i++) { n=rdbt(); n=(n< tmp=tmp+n; udelay(100); } return tmp; } int DS18B20status=0; //////////////////////////////////////////////////////////////////////////////////////////// // 实际工作部分 /// /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////打开设备文件,并初始化设备文件////////////////////////// int DS18B20_open(struct inode *inode,struct file *file) { uchar fuwei; printk("DS18B20 openn"); fuwei=reset(); udelay(20); if(fuwei) printk("no node at heren"); else printk("There is a noden"); return 0; } //////////////////////////////////关闭文件操作/////////////////////////////////// int DS18B20_release(struct inode *inode,struct file *file) { uint tmp; shuru(); tmp=readl(S3C64XX_GPNDAT); tmp &= 0xFFFFFEFF; writel(tmp,S3C64XX_GPNDAT); printk("DS18B20 closen"); return 0; } ///////////////////////////////////////读温度传感器并转还为温度值/////////////////////////////////////// static ssize_t DS18B20_read(struct file *filp,unsigned char __user *buf,size_t count,loff_t *ppos) { uchar arry[2]={0}; reset(); udelay(420);////////////////////////////////////////// wrbyte(0xcc); //给传感器写一个skipROM命令 wrbyte(0x44); //写一个温度转换命令convertT mdelay(1000);///////////////////////////////////////////// reset(); //等待转换成功 udelay(400);////////////////////////////////////////// wrbyte(0xcc); //一个skipROM命令 wrbyte(0xbe); //写一个读取命令 arry[0]=rdbyte(); //读取低八位 arry[1]=rdbyte(); //读取高八位 // buf[0]=arry[0]; // buf[1]=arry[1]; /* if(arry[1]>>8!=0) //如果高八位不为0则为负摄氏温度 { arry[1]=~arry[1]; // arry[0]=~arry[0]; arry[0]+=1; //取反加一,求出原码 } */ *buf=arry[0]/16+arry[1]*16; // *(buf+1)=(arry[0]&0x0f)*10/16+(arry[1]&0x0f)*100/16%10; //copy_to_user(buf,&DS18B20status,1); printk("DS18B20 readn"); printk("%d %d n",arry[0],arry[1]); printk("bufaaaaaaddddddddddddddd = %dn",*(buf+1)); return 0; } ////////////////////////////////////////写温度值//////////////////////////////////////////////////// static ssize_t DS18B20_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos) { reset(); wrbyte(0xCC); wrbyte(0x4E); wrbyte(buf[0]); // 写入上限值 wrbyte(buf[1]); //写入下限值 wrbyte(0x48); //把暂存器的值复制到E2存储器 printk("DS18B20 writen"); return 0; } long int DS18B20_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) //IO口控制函数,操作的时寄存器,cmd微操作命令,传递一个参数arg { //uint tmp; printk("DS18B20 ioctln"); /*switch(cmd) { case 0: tmp=readl(S3C64XX_GPNDAT); tmp &= 0xFFFFBFFF; writel(tmp,S3C64XX_GPNDAT); printk("BEEP1 OFFn"); return 0; case 1: tmp=readl(S3C64XX_GPNDAT); tmp |= 0x00004000; writel(tmp,S3C64XX_GPNDAT); printk("BEEP1 ONn"); return 0; default: printk("unsupported commandn"); return -EINVAL; }*/ return 0; } static struct file_operations DS18B20_fops= { .owner = THIS_MODULE, //拥有该结构模块的指针,避免在操作时被卸载,一般初始化为THIS_MODULE .open = DS18B20_open, //对外提供打开操作 .release = DS18B20_release, //当file结构指针释放时,调用次函数,即:当最后一个打开该设备文件的用户调用close时,将调用此函数 //release 函数的主要任务是清理未结束的输入/输出操作、释放资源、用户自定义排他标志的复位等 .read = DS18B20_read, //对外提供读操作 .write = DS18B20_write, //对外提供写操作 .unlocked_ioctl = DS18B20_ioctl, //该函数是特殊的控制函数,可以通过它向设备传递控制信息或从设备取得状态信息,即为io控制函数 }; static struct cdev DS18B20_devs; int major=0; static void DS18B20_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops) { int err,devno=MKDEV(major,minor);//把0和原来生成的设备号再合并到一块去 ,再生成一个设备号,表示有一个设备 cdev_init(dev,fops); dev->owner=THIS_MODULE; dev->ops=fops; //把dev的ops设置成为fops err=cdev_add(dev,devno,1); //向内核注册新生成的devno信息,1表示和设备关联的的设备书目 if(err) //判断设备是否存活,如果cdev_add()调用成功的话,设备就可以使用了,外部的应用程序对它的操作,内核就会允许了 { printk("Error %s adding DS18B20 %dn",KERN_ALERT,minor); printk("Error %d adding DS18B20 %dn",err,minor); } } static int DS18B20_init(void) { int result; dev_t dev=MKDEV(major,0); //申请设备,major为主设备号,0为次设备号,表示自动分配设备号 if(major) //表示如果已经有了主设备号,就直接注册设备号 { result=register_chrdev_region(dev,1,DS18B20_DEVICE_NAME); } else //如果没有主设备号, { result=alloc_chrdev_region(&dev,0,1,DS18B20_DEVICE_NAME);//自动申请主设备号 major=MAJOR(dev); //通过访问设备号,获得主设备号 } if(result<0) { printk("DS18B20:unable to get major %sn",KERN_ALERT);//报告错误,立即采取措施宏为1 printk("DS18B20:unable to get major %dn",major); return result; } DS18B20_setup_cdev(&DS18B20_devs,0,&DS18B20_fops);//这里的0表示的是第一个设备,因为咱们就有一个设备,以后在使用中,不一定是一个,拿着就是变量两 printk(KERN_ALERT"The major of DS18B20 device is %dn",major); printk("The major of DS18B20 device is %dn",major); return 0; } static void DS18B20_cleanup(void) { cdev_del(&DS18B20_devs); unregister_chrdev_region(MKDEV(major,0),1); printk("DS18B20 device uninstalDS18B20n"); printk(KERN_ALERT"DS18B20 device uninstalln"); } module_init(DS18B20_init); module_exit(DS18B20_cleanup); MODULE_LICENSE("Dual BSD/GPL"); |
|
相关推荐
3个回答
|
|
框架没问题,但时序好像有问题,给解决下,看看哪儿的事l
|
|
|
|
知道时序就自己找一下时序的问题,单总线对时序要求严格
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
飞凌嵌入式ElfBoard ELF 1板卡-CAN编程示例之开发板测试
654 浏览 0 评论
该问题是用APP给芯海科技的CST92F25芯片发指令是出现的
2242 浏览 1 评论
771 浏览 0 评论
1530 浏览 1 评论
2276 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 06:01 , Processed in 0.644252 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号