#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/device.h>
/* 相关引脚定义,方便以后移植 */
#define DQ S3C2410_GPB(1)
#define CFG_IN S3C2410_GPIO_INPUT
#define CFG_OUT S3C2410_GPIO_OUTPUT
#define TIME_OUT_DEALY 100
// dht11主次设备号(动态分配)
static int dht11_major = 0;
static int dht11_minor = 0;
static int dht11_nr_devs = 1;
unsigned short temperature,humidity;
unsigned char checknum;
static volatile unsigned char values[6]={0,0,0,0,0,0};
// 定义设备类型
static struct dht11_device
{
struct cdev cdev;
};
struct dht11_device *dht11_devp; /*设备结构体指针 */
static struct class *dht11_class;
static struct class_device *dht11_class_dev;
/* 函数声明 */
static int dht11_open(struct inode *inode, struct file *filp);
static int dht11_init(void);
static ssize_t dht11_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos);
void dht11_setup_cdev(struct dht11_device *dev, int index);
static void set_pin_high(void)
{
s3c2410_gpio_cfgpin(DQ,CFG_OUT);
s3c2410_gpio_setpin(DQ, 1);
}
static void set_pin_low(void)
{
s3c2410_gpio_cfgpin(DQ,CFG_OUT);
s3c2410_gpio_setpin(DQ, 0);
}
static int set_pin_delay_get(unsigned int time)
{
s3c2410_gpio_cfgpin(DQ,CFG_IN);
udelay(time);
if(s3c2410_gpio_getpin(DQ))
return 1;
else
return 0;
}
static int set_pin_get(void)
{
if(s3c2410_gpio_getpin(DQ))
return 1;
else
return 0;
}
static int dht11_open(struct inode *inode, struct file *filp)
{
int flag = 0;
flag = dht11_init();
if (flag & 0x01)
{
printk(KERN_WARNING "open dht11 failed\n");
return -1;
}
printk(KERN_NOTICE "open dht11 successful\n");
return 0;
}
static int dht11_init(void)
{
int retval = 0;
set_pin_high();
return retval;
}
static int read_word_data(void)
{
int i;
int counter=0;
int timerout_counter=0;
int timerout_flag=0;
int ret=0;
start:
set_pin_low(); //
mdelay(20); //18ms
set_pin_high(); //
if(set_pin_delay_get(50)) //
{
printk(KERN_INFO"can not detect the low ack!");
counter++;
if(counter>5)
{
ret=-1;
goto stop;
}
goto start;
}
counter=0;
timerout_counter=0;
while((!set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);//
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
timerout_counter=0;
while((set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);// //
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
for(i=0;i<16;i++)
{
humidity <<=1; //<< must at the head,or the value will be the double to real value.
timerout_counter=0;
while((!set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);// //
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
if(set_pin_delay_get(45)) //40us
{
humidity |=1;
timerout_counter=0;
while((set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);// //
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
}
else //40us
humidity |=0;
}
for(i=0;i<16;i++)
{
temperature <<=1;
timerout_counter=0;
while((!set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);//
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
if(set_pin_delay_get(45)) //40us
{
temperature|=1;
timerout_counter=0;
while((set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);//
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
}
else //40us
temperature |=0;
}
for(i=0;i<8;i++)
{
checknum <<=1;
timerout_counter=0;
while((!set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);//
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
if(set_pin_delay_get(40)) //
{
checknum |=1;
timerout_counter=0;
while((set_pin_get())&&(timerout_counter++<TIME_OUT_DEALY))udelay(5);//
if(timerout_counter>=TIME_OUT_DEALY)
{
timerout_flag=1;
goto out_err;
}
}
else //
checknum |=0;
}
set_pin_high();
stop:
return ret;
out_err:
if (timerout_flag==1)
ret=-2;
return ret;
}
static ssize_t dht11_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos)
{
int ret = 0;
unsigned char temp;
// struct dht11_dev *dev = filp->private_data; /**/
ret=read_word_data(); //
if(ret>=0)
{
values[0]=(temperature & 0xff00)>>8;
values[1]=temperature & 0x00ff;
values[2]=(humidity & 0xff00)>>8;
values[3]=humidity & 0x00ff;
temp=values[0]+values[1]+values[2]+values[3];
//printk(KERN_WARNING "temp=%d",temp);
//printk(KERN_WARNING "checknum=%d",values[4]);
if(temp!=checknum)
{//crc
ret=-3;
goto out;
}
}
else
{
goto out;
}
/*printk is for test,hide it when test finished */
// printk(KERN_INFO"vaule is %hd %hd\n",temperature,humidity);
//printk(KERN_WARNING "vaule is %d %d %d %d %d\n",values[0],values[1],values[2],values[3],checknum);
if (copy_to_user(buf, (void*)values, count)) //if values[] is int,only can read values[0],donnot know why.
{
ret = - EFAULT;
}
else
{
// printk(KERN_INFO "read %d bytes(s) from %ld\n", count, p);
ret=count;
}
out:
return ret;
}
static struct file_operations dht11_dev_fops = {
.owner = THIS_MODULE,
.open = dht11_open,
.read = dht11_read,
};
void dht11_setup_cdev(struct dht11_device *dev, int index)
{
int err, devno = MKDEV(dht11_major, dht11_minor + index);
cdev_init(&dev->cdev, &dht11_dev_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&(dev->cdev), devno, 1);
if (err)
{
printk(KERN_NOTICE "ERROR %d add dht11\n", err);
}
}
static int __init dht11_dev_init(void)
{
int result;
dev_t dev = 0;
dev = MKDEV(dht11_major, dht11_minor);
if (dht11_major)
{
result = register_chrdev_region(dev, dht11_nr_devs, "dht11");
}
else
{
result = alloc_chrdev_region(&dev, dht11_minor, dht11_nr_devs, "dht11");
dht11_major = MAJOR(dev);
}
if (result < 0)
{
printk(KERN_WARNING "dht11: failed to get major\n");
return result;
}
/* 为新设备分配内存和初始化 */
dht11_devp = kmalloc(sizeof(struct dht11_device), GFP_KERNEL);
if (!dht11_devp)
{ /*申请失败 */
result = -ENOMEM;
goto fail_malloc;
}
memset(dht11_devp, 0, sizeof(struct dht11_device));
dht11_setup_cdev(dht
linux平台 DHT11驱动程序
5星 · 超过95%的资源 需积分: 9 159 浏览量
2014-07-27
15:23:46
上传
评论 1
收藏 7KB RAR 举报
whowhomy
- 粉丝: 0
- 资源: 23
最新资源
- J211-T1B-A-VB一款SOT23封装P-Channel场效应MOS管
- J210-VB一款SOT23封装P-Channel场效应MOS管
- J210-T1B-A-VB一款SOT23封装P-Channel场效应MOS管
- Suno V3 AI音乐生成神器,助你秒变音乐大师,suno AI音乐使用教程
- 自适应极化滤波完成P/S波分离
- 0b40adff-950d-44cf-88e6-f4a64292b638.apk
- J209-VB一款SOT23封装P-Channel场效应MOS管
- OLED12864模块(IIC接口)中文说明书.pdf
- 22304010116工管余文贤.bak
- 电路各单元电路的特点与作用
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页