資源簡介
說明:通過內核驅動dht11實現溫度濕度的檢測
核心代碼:
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/wait.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
/*定義DHT11接入的IO口*/
#define DHT11_PIN EXYNOS4_GPB(4)
#define DEVNAME "dht11"
/* 用于接受采集到的數據*/
unsigned char dht11_data_buf[6];
/* 判斷校驗的標記*/
unsigned char check_flag;
/* read one bit */
static int dht11_read_bit(void)
{
gpio_direction_input(DHT11_PIN);
return gpio_get_value(DHT11_PIN);
}
/* read byte */
static unsigned char dht11_read_byte(void)
{
int i = 0;
int num ;
unsigned char flag = 0;
unsigned char data = 0;
for(num = 0; num < 8; num ){
i = 0;
/*沒一個位發送起始的時候,會有50us低電平*/
while(gpio_get_value(DHT11_PIN) == 0){
udelay(10);
i ;
if(i > 5){
break;
}
}
flag = 0x00;
/*26-28 us 高電平表示'0'*/
udelay(30);
if(gpio_get_value(DHT11_PIN)){
flag = 0x01;
}
i = 0;
/*如果讀到的數據為'1'的話,70us 高電平,將這段時間的高電平讀取完畢*/
while(gpio_get_value(DHT11_PIN)){
udelay(20);
i ;
if(i > 3)
break;
}
data <<= 1;
data |= flag;
}
return data;
}
/* 設備 read_data*/
static void dht11_read_data(void)
{
int i = 0;
/*
主機把總線拉低必須大于18毫秒,保證DHT11能檢測到起始信號。
DHT11接收到主機的開始信號后,等待主機開始信號結束,然后發送80us低電平響應信號.
主機發送開始信號結束后,延時等待20-40us后, 讀取DHT11的響應信號,
主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可, 總線由上拉電阻拉高。
*/
gpio_direction_output(DHT11_PIN,0);
mdelay(30);
gpio_direction_output(DHT11_PIN,1);
udelay(20);
if(dht11_read_bit() == 0){
while(!gpio_get_value(DHT11_PIN)){
udelay(10);
i ;
if(i > 8){
printk("dht11 read data %d error\n",__LINE__);
break;
}
}
i = 0;
while(gpio_get_value(DHT11_PIN)){
udelay(10);
i ;
if(i > 8){
printk("dht11 read data %d error\n",__LINE__);
break;
}
}
for(i = 0; i < 5; i ){
dht11_data_buf[i] = dht11_read_byte();
}
dht11_data_buf[5] = dht11_data_buf[0] dht11_data_buf[1]
dht11_data_buf[2] dht11_data_buf[3];
if(dht11_data_buf[5] == dht11_data_buf[4]){
check_flag = 0xff;
}else if(dht11_data_buf[4] != dht11_data_buf[5]){
check_flag = 0x00;
}
}
}
/* 設備 read*/
static ssize_t dht11_read(struct file *file, char __user *buffer, ssize_t size, loff_t *offset)
{
int ret;
// unsigned long flags;
// local_irq_save(flags);
dht11_read_data();
// local_irq_restore(flags);
if(check_flag == 0xff){
ret = copy_to_user(buffer,dht11_data_buf,sizeof(dht11_data_buf));
if(ret < 0){
printk("copy_to_user error\n");
return -EAGAIN;
}else{
return 0;
}
}else{
printk("check error\n");
return -EAGAIN;
}
}
/* 定義雜項設備操作的結構體并且初始化成員的函數指針 */
static const struct file_operations dht11_fops = {
.read = dht11_read,
};
/* 定義雜項設備結構體*/
static struct miscdevice dht11_miscdev = {
.minor = MISC_DYNAMIC_MINOR, /* 自動分配次設備號 */
.name = DEVNAME, /* 雜項設備的名字 */
.fops = &dht11_fops, /* 雜項設備操作的結構體(驅動函數集合)*/
};
static int dht11_init(void)
{
int ret;
ret = gpio_request(DHT11_PIN,DEVNAME);
if(ret){
printk("gpio_retquest for dht11 is filed\n");
return ret;
}
ret = misc_register(&dht11_miscdev);
return ret;
}
static void dht11_exit(void)
{
misc_deregister(&dht11_miscdev);
gpio_free(DHT11_PIN);
}
module_init(dht11_init);
module_exit(dht11_exit);
MODULE_LICENSE("GPL");
代碼片段和文件信息
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
/*定義DHT11接入的IO口*/
#define?DHT11_PIN?EXYNOS4_GPB(4)
#define?DEVNAME?“dht11“
/* 用于接受采集到的數據*/
unsigned?char?dht11_data_buf[6];
/*??判斷校驗的標記*/
unsigned?char?check_flag;
/*??read?one?bit?*/
static?int?dht11_read_bit(void)
{
gpio_direction_input(DHT11_PIN);
return?gpio_get_value(DHT11_PIN);
}
/*??read?byte?*/
static?unsigned?char?dht11_read_byte(void)
{
int?i?=?0;
int?num?;
unsigned?char?flag?=?0;
unsigned?char?data?=?0;
for(num?=?0;?num?8;?num?++){
i?=?0;
/*沒一個位發送起始的時候,會有50us低電平*/
while(gpio_get_value(DHT11_PIN)?==?0){
udelay(10);
i++?;
if(i?>?5){
break;
}
}
flag?=?0x00;
/*26-28?us 高電平表示‘0‘*/
udelay(30);
if(gpio_get_value(DHT11_PIN)){
flag?=?0x01;
}
i?=?0;
/*
評論
共有 條評論