arm温湿度传感器(二)修改app和驱动

根据上一篇可以在内核里增加自己的驱动

这次我们让程序跑起来

app可以从驱动中提取出自己想要的值
发现传感器在arm上 有明显抖动

所以读取数值之前,大约要进行15次的数据读取,才能得到正常的数据
在这里插入图片描述

测试结果

在这里插入图片描述
最后app得到的数据已经稳定

代码

second_drv.c

#include<linux/module.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#include <asm/gpio.h>
#include <asm/delay.h>
#include <linux/clk.h>
#include <mach/gpio.h>
#include <mach/soc.h>
#include <mach/platform.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/errno.h>
#include <linux/serio.h>
#include <linux/wait.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>
#include <linux/gpio.h>



#define CFG_IO_X6818_Humity (PAD_GPIO_B + 29)

static struct class *seconddrv_class;
static struct class_device	*seconddrv_class_dev;



volatile unsigned long *gpbcon;
volatile unsigned long *gpbdat;

int data_in(void) {
    gpio_direction_input(CFG_IO_X6818_Humity);
    return gpio_get_value(CFG_IO_X6818_Humity);
}

/*************************************************
*管教设置为输出
*************************************************/
void data_out(int data) {
    gpio_direction_output(CFG_IO_X6818_Humity, data);
}


void DHT11_Rst(void)	   
{                 
	data_out(0); 	//SET OUTPUT
	mdelay(20);//拉低至少18ms
    data_out(1); 	//DQ=1 
	udelay(30);     	//主机拉高20~40us
}

u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
    while (data_in()&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		udelay(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!data_in()&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		udelay(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}

u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(data_in()&&retry<100)//等待变为低电平
	{
		retry++;
		udelay(1);
	}
	retry=0;
	while(!data_in()&&retry<100)//等待变高电平
	{
		retry++;
		udelay(1);
	}
	udelay(40);//等待40us
	if(data_in())return 1;
	else return 0;		   
}

u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}


u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}

static int second_drv_open(struct inode *inode, struct file *file)
{
	
	 //gpio_direction_input(CFG_IO_X6818_Humity);
	

	return 0;
}

ssize_t second_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	/* 返回4个引脚的电平 */
	unsigned int dht11_vals[2];
	u8 temperature; 		
	u8 humidity;  
	int i ;
	for (i = 0;i<15;i++)
		{
			DHT11_Read_Data(&temperature,&humidity);
			mdelay(2000);
			printk("the tem is %d,hum is %d\n",temperature,humidity);
		}
	DHT11_Read_Data(&temperature,&humidity);
	printk("the tem is %d,hum is %d\n",temperature,humidity);
	mdelay(2000);
	dht11_vals[0] = temperature;
	dht11_vals[1] = humidity;

	copy_to_user(buf, dht11_vals, sizeof(dht11_vals));
	
	return sizeof(dht11_vals);
}


static struct file_operations sencod_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   second_drv_open,     
	.read	=	second_drv_read,	   
};


int major;
static int second_drv_init(void)
{
	major = register_chrdev(0, "second_drv", &sencod_drv_fops);

	seconddrv_class = class_create(THIS_MODULE, "second_drv");

	seconddrv_class_dev = device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */
	

	return 0;
}

static void second_drv_exit(void)
{
	unregister_chrdev(major, "second_drv");
	device_unregister(seconddrv_class_dev);
	class_destroy(seconddrv_class);
	return 0;
}


module_init(second_drv_init);

module_exit(second_drv_exit);

MODULE_LICENSE("GPL");



seconddrvtest.c

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/termios.h>
int main()
{
    int fd;
    int ret ;
	unsigned int dht11_vals[2];
    fd = open("/dev/buttons", 0);
 	if (fd < 0)
	{
		printf("can't open!\n");
	}
	read(fd, dht11_vals, sizeof(dht11_vals));
	printf("end the tem is %d,hum is %d\n",dht11_vals[0],dht11_vals[1]);
    close(fd);
    return 0;
}

Makefile

#内核要提前编译好
KERN_DIR = /home/scholar/Desktop/6818GEC/kernel
#-C 是转到后面的目录'$(KERN_DIR)',使用这个目录下面的 Makefile 编译
#M是指当前目标是什么
#moudule 是指目标

all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= second_drv.o

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值