Linux下18b20温度传感器驱动代码及测试实例
驱动代码:
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h> #define DEVICE_NAME "TEM0" #define TEM_SHOW_CODE 0x01 //static struct cdev cdev;
struct class *tem_class;
//static dev_t devno;
//static int major = 243;//可以用int alloc_chrdev_region(dev_t *dev,unsigned baseminor,
//unsigned count,const char *name);向系统动态申请未被占用的设备号。 struct tem_dev_t
{
struct cdev cdev;
}tem_dev; /**
* * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
* * @pin pin The pin number to configure.
* * @to to The configuration for the pin's function.
* *
* * Configure which function is actually connected to the external
* * pin, such as an gpio input, output or some form of special function
* * connected to an internal peripheral block.
* *
* * The @to parameter can be one of the generic S3C_GPIO_INPUT, S3C_GPIO_OUTPUT
* * or S3C_GPIO_SFN() to indicate one of the possible values that the helper
* * will then generate the correct bit mask and shift for the configuration.
* *
* * If a bank of GPIOs all needs to be set to special-function 2, then
* * the following code will work:
* *
* * for (gpio = start; gpio < end; gpio++)
* * s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
* *
* * The @to parameter can also be a specific value already shifted to the
* * correct position in the control register, although these are discouraged
* * in newer kernels and are only being kept for compatibility.
* */
unsigned int gpio=; void tem_reset(void)
{
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN());//当x=0时是输入功能,x=1时是输出功能
gpio_set_value(gpio, );
udelay();//延迟0.1ms
gpio_set_value(gpio, );
udelay();
gpio_set_value(gpio, );
udelay();
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN());
} void tem_wbyte(unsigned char data)
{
int i; s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN());
for (i = ; i < ; ++i)
{
gpio_set_value(gpio, );
udelay(); if (data & 0x01)
{
gpio_set_value(gpio, );
}
udelay();
gpio_set_value(gpio, );
udelay();
data >>= ;
}
gpio_set_value(gpio, );
} unsigned char tem_rbyte(void)
{
int i;
unsigned char ret = ; for (i = ; i < ; ++i)
{
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN());
gpio_set_value(gpio, );
udelay();
gpio_set_value(gpio, ); s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN());
ret >>= ;
if (gpio_get_value(gpio))
{
ret |= 0x80;
}
udelay();
}
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN()); return ret;
} static ssize_t tem_read(struct file *filp, char *buf, size_t len, loff_t *offset)
{
unsigned char low, high; tem_reset();
udelay();
tem_wbyte(0xcc);
tem_wbyte(0x44); mdelay();
tem_reset();
udelay();
tem_wbyte(0xcc);
tem_wbyte(0xbe); low = tem_rbyte();
high = tem_rbyte(); *buf = low / + high * ; *(buf + ) = (low & 0x0f) * / + (high & 0x0f) * / % ;
return ;
}
/*******************************************************************
*
*ioctl 还不准确,需要改进
* by mhb
*
**********************************************************************/
int tem_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
printk("in the ioctl!!\n");//debug
switch(cmd)
{
case TEM_SHOW_CODE:
{
int i;
unsigned char fc,sn[],crc;
tem_reset();
udelay();
tem_wbyte(0x33);
fc = tem_rbyte;
for (i = ; i < ; i++)
{
/* code */
sn[i]=tem_rbyte;
}
crc=tem_rbyte;
printk("familycode=%x\n",fc);
printk("serialnumber=%x%x%x%x%x%x\n",sn[],sn[],sn[],sn[],sn[],sn[]);
printk("crc=%x\n",crc);
break;
}
default:
{
return - ENOTTY;
}
}
} static struct file_operations tem_fops =
{
.owner = THIS_MODULE,
.read = tem_read,
.ioctl =tem_ioctl,
}; static int __init tem_init(void)
{
int result;
int major;
int minor; cdev_init(&tem_dev.cdev,&tem_fops);/*init cdev*/
tem_dev.cdev.owner=THIS_MODULE;
// devno = MKDEV(major, 0);
// result = register_chrdev_region(devno, 1, DEVICE_NAME);
result = alloc_chrdev_region(&tem_dev.cdev.dev,,,DEVICE_NAME);
major=MAJOR(tem_dev.cdev.dev);
minor=MINOR(tem_dev.cdev.dev);
if(major)
{
printk("majior=%d\n",major);
printk("minor=%d\n",minor);
}else
printk("can not get device num!!\n"); if (result)
{
printk("register failed\n");
return result;
}
#ifdef CONFIG_OK210_BOARD_V2
gpio=S5PV210_MP04();
#else
gpio=S5PV210_GPH3();
#endif
// cdev_init(&cdev, &tem_fops);
// cdev.owner = THIS_MODULE;
// cdev.ops = &tem_fops;
result = cdev_add(&tem_dev.cdev, tem_dev.cdev.dev, );
if (result)
{
printk("cdev add failed\n");
goto fail1;
} tem_class = class_create(THIS_MODULE, "tmp_class");/*在sys目录下创建tmp_class这个类,/sys/class/~*/
if (IS_ERR(tem_class))
{
printk("class create failed\n");
goto fail2;
} device_create(tem_class, NULL, tem_dev.cdev.dev, DEVICE_NAME, DEVICE_NAME);/*自动创建设备/dev/TEM0*/
return ;
fail2:
cdev_del(&tem_dev.cdev);
fail1:
unregister_chrdev_region(tem_dev.cdev.dev, );
return result;
} static void __exit tem_exit(void)
{
device_destroy(tem_class, tem_dev.cdev.dev);
class_destroy(tem_class);
cdev_del(&tem_dev.cdev);
unregister_chrdev_region(tem_dev.cdev.dev, );
} module_init(tem_init);
module_exit(tem_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("mhb");
测试代码:
#include "stdio.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"
#define TEM_SHOW 0x01
main()
{
int fd;
#if 1
unsigned char buf[];
#else
unsigned int tmp;
#endif
float result; if ((fd=open("/dev/TEM0",O_RDWR | O_NDELAY | O_NOCTTY)) < )
{
printf("Open Device DS18B20 failed.\r\n");
exit();
}
else
{
printf("Open Device DS18B20 successed.\r\n");
while()
{
// read(fd, buf, sizeof(buf));
// result = tmp * 1000;
// result = *(int *)buf;
read(fd, buf, sizeof(buf));
#if 0
printf("%d\n", buf[]);
printf("%d\n", buf[]);
result = (float)buf[];
result /= ;
result += ((float)buf[] * );
#endif
#if 0
// printf("%f .C\r\n", result);
sleep();
#else
printf("%d.%d C\r\n", buf[], buf[]);
sleep();
ioctl(fd,TEM_SHOW,);
#endif
}
close(fd);
}
}
Linux下18b20温度传感器驱动代码及测试实例的更多相关文章
- Linux下简易蜂鸣器驱动代码及测试实例
驱动代码: #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> ...
- 怎样在Windows和Linux下写相同的代码
目前,Linux在国内受到了越来越多的业内人士和用户的青睐.相信在不久的将来,在国内为Linux开发 的应用软件将会有很大的增加(这不,金山正在招兵买马移植WPS呢).由于未来将会是Windows和L ...
- Linux下几种常见压缩方式测试对比
目录 Linux下几种常见压缩方式测试对比 参考 简介 测试 总结 Linux下几种常见压缩方式测试对比
- Linux下四款Web服务器压力测试工具(http_load、webbench、ab、siege)介绍
一.http_load程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把 ...
- Linux下高并发socket链接数测试
一.如何增大service进程的max open files ulimit -n 只能改小max open files,不能改大.需要按照以下步骤: 修改/etc/security/limits.co ...
- 介绍linux下Source Insight强大代码编辑器sublime_text_3
背景 1 一. 运行环境 1 二.安装环境配置 1 三.创建快捷方式 1 四.配置全局环境 2 五.操作界面 3 背景 在windows操作系统系统下,文本代码编辑器众多,各路英雄豪杰争相写了许多强大 ...
- linux下使用indent整理代码(代码格式化)【转】
转自:https://blog.csdn.net/jiangjingui2011/article/details/7197069 常用的设置: indent -npro -kr -i8 -ts8 -s ...
- linux下重启oracle服务:监听器和实例
一.在Linux下重启Oracle数据库及监听器: 方法1: 用root以ssh登录到linux,打开终端输入以下命令: cd $ORACLE_HOME #进入到oracle的安装目录 dbstart ...
- [转载]以及部分总结--Linux下创建单机ASM存储的Oracle实例的过程---感谢方总
Linux下单机安装ASM流程总结 一.安装Linux ESXi上传iso镜像至存储目录 创建虚拟机,并且选择主机设备的ISO启动 选择完成时编辑虚拟机设置 配置镜像文件如下: 打开控制台: 并且选择 ...
随机推荐
- TCP/IP协议原理与应用笔记03:IP地址分类
1. 事实上,每个IP地址都包含两部分,即网络号和主机号. 例如:202.112.81.34指的 就是202.112.81这个网络的第34号机. 网络号:用于识别主机所在的网络: 主机号:用于识别该网 ...
- vs2012新建实体数据模型(EF)时无Mysql数据源
sql转mysql数据库,用到EF,遇到vs2012新建实体数据模型时无Mysql数据源的问题. 问题截图如下: 解决方法1:(简单的的解决方法,有可能解决问题,如不能解决问题,请看解决方法2): ( ...
- jsp 用application对象制作留言板
<%@ page contentType="text/html; charset=gb2312"%> <html> <body> <for ...
- 浅析PAC,教你动手修改你的PAC文件及user-rule文件实现自动代理
Shadowsocks作为现在一种很流行的穿墙工具,以其轻量级.速度感人等优点深受广大网友热捧.与VP_N相比,他就像一把锋利的”瑞士军刀”,不用受制于“系统全局代理”模式的困扰,控制更加便捷,基于S ...
- Android打包失败Proguard returned with error code 1. See console
问题一: [2013-06-28 11:12:10 - ] Proguard returned with error code 1. See console [2013-06-28 11:12:10 ...
- PHP输入流php://input介绍
在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$_POST数组.所以,这里主要探讨php输入流php://input 对一php://inpu ...
- JAXB - Hello World with Namespace
如果元素带有命名空间,那么处理方式与 JAXB - Hello World 会略有不同. 1. XML Schema: <xsd:schema xmlns:xsd="http://ww ...
- vs2010打开vs2012的sln文件
1.找到**.sln文件,然后选择用记事本打开. 2.最前面找到“Microsoft Visual Studio Solution File, Format Version 12.00 # Visu ...
- Mysql - 解决Access denied for user ''@'localhost' to database 'mysql'问题
http://361324767.blog.163.com/blog/static/11490252520124454042468/ 首先我想说一句话: 我极度鄙视国内搞IT的人,简直无语,同样是解决 ...
- ios Trace xcode buile count
前言: 1.记录xcode编辑次数很有必要,特别是在频繁发版本时和根据现有编译次数记录估算工期时间很有帮助 2.全部自动化处理,告别手动时代 正文: 1.新建工程或者现有工程里设置: 然后设置xcod ...