mtk7688之openwrt平台下温湿度传感器应用
[复制链接]
mtk7688之openwrt平台下温湿度传感器应用
我之前测试了DS18B20和DHT11传感器,都测试通过,这篇主要讲解如何实现DHT11传感器在openwrt平台上的应用。
DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃,由于mtk7688基本引脚都复用了,板子也没引出什么IO引脚,正好我的板子引出了UART1的引脚排针,所以我使用了TX1引脚来作为DHT11的IO交互引脚,IO的配置方法之前我的几篇已经分析了很详细,就不讲了,我把重点的内核驱动需要改动的地方红色标注了,linux的内核驱动就是这样,基本都是依葫芦画瓢,90%的代码基本不需要改动,就是改动些相关具体的驱动代码,其他的传感器配置可以参考这篇来。
应用测试程序
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int fd;
unsigned int dht11 = 0;
unsigned int humi,temp;
//打开温度传感器驱动模块
fd = open("/dev/dht11", O_RDWR | O_NONBLOCK);
if (fd < 0)
{
printf("can't open /dev/dht11\n");
return -1;
}
read(fd, &dht11, sizeof(dht11));
temp = dht11>>8;
humi = dht11 &0x000000ff;
printf("the current temperature is: %d\n",temp);
printf("the current humidity is: %d\n",humi);
close(fd);
return 0;
}
DHT11内核驱动代码:
/*****************************
*
* 驱动程序模板
* 版本:V1
* 使用方法(末行模式下):
* :%s/dht11/"你的驱动名称"/g
*
*******************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//配置连接温度传感器的引脚
#define DHT11_L *GPIO45_DATA &= ~(1<<13) //低电平
#define DHT11_H *GPIO45_DATA |= (1<<13) //高电平
#define DHT11_OUT *GPIO45_DIR |= (1<<13) //输出
#define DHT11_IN *GPIO45_DIR &= ~(1<<13) //输入
#define DHT11_STA ((*GPIO45_DATA>>13) & 0x01)
//寄存器定义
volatile unsigned long *GPIO45_MODE;
volatile unsigned long *GPIO45_DIR;
volatile unsigned long *GPIO45_DATA;
/**************** 基本定义 **********************/
//初始化函数必要资源定义
//用于初始化函数当中
//device number;
dev_t dev_num;
//struct dev
struct cdev dht11_cdev;
//auto "mknode /dev/dht11 c dev_num minor_num"
struct class *dht11_class = NULL;
struct device *dht11_device = NULL;
/******************** dht11有关的函数 ****************************/
//从dht11中读取一个字节
static unsigned char read_byte(void)
{
unsigned char r_val = 0;
unsigned char t_count = 0; //计时器,防止超时;
unsigned char i;
for(i = 0 ; i < 8 ; i++)
{
t_count = 0;
while(!DHT11_STA)
{
udelay(1);
t_count++;
if(t_count>250)
{
printk("read_byte error1\n");
return 100;
}
}
t_count = 0;
udelay(32);
if(DHT11_STA == 1)
{
r_val <<= 1;
r_val |= 1;
}
else
{
r_val <<= 1;
continue;
}
while( DHT11_STA == 1 )
{
udelay(2);
t_count++;
if(t_count>250)
{
printk("read_byte error2\n");
return 100;
}
}
}
return r_val;
}
//从dht11中读出数据
static unsigned int read_dht11(void)
{
unsigned char t_count = 0; //计时器;
unsigned int dht11 = 0;
unsigned char h_i = 0 , h_f = 0;
unsigned char t_i = 0 , t_f = 0;
unsigned char check_sum = 0;
DHT11_OUT;
DHT11_L;
mdelay(30); //>18ms;
DHT11_H;
udelay(30);
DHT11_IN;
while(DHT11_STA == 1)
{
udelay(1);
t_count++;
if(t_count > 50)
{
printk("device error: dht11!\n");
return 0;
}
}
t_count = 0;
while(!DHT11_STA)
{
udelay(1);
t_count++;
if(t_count > 250)
{
printk("read_dht11 error1\n");
return 0;
}
}
t_count = 0;
udelay(50);
while(DHT11_STA)
{
udelay(1);
t_count++;
if(t_count > 250)
{
printk("read_dht11 error2\n");
return 0;
}
}
h_i = read_byte();
h_f = read_byte();
t_i = read_byte();
t_f = read_byte();
check_sum = read_byte();
if(check_sum == (h_i+h_f+t_i+t_f) || (h_i!=100 && t_i != 100))
{
dht11 = t_i;
dht11 <<= 8;
dht11 += h_i;
}
else
{
dht11 = 0;
printk("read_dht11 error3\n");
}
return dht11;
}
/**********************************************************************/
/**************** 结构体 file_operations 成员函数 *****************/
//open
static int dht11_open(struct inode *inode, struct file *file)
{
printk("dht11 drive open...\n");
DHT11_OUT;
DHT11_H;
return 0;
}
//close
static int dht11_close(struct inode *inode , struct file *file)
{
return 0;
}
//read
static ssize_t dht11_read(struct file *file, char __user *buffer,
size_t len, loff_t *pos)
{
unsigned int dht11;
printk("dht11 drive read...\n");
dht11 = read_dht11();
copy_to_user(buffer, &dht11, 4);
return 4;
}
/***************** 结构体: file_operations ************************/
//struct
static const struct file_operations dht11_fops = {
.owner = THIS_MODULE,
.open = dht11_open,
.release = dht11_close,
.read = dht11_read,
};
/************* functions: init , exit*******************/
//条件值变量,用于指示资源是否正常使用
unsigned char init_flag = 0;
unsigned char add_code_flag = 0;
//init
static __init int dht11_init(void)
{
int ret_v = 0;
printk("dht11 drive init...\n");
//函数alloc_chrdev_region主要参数说明:
//参数2: 次设备号
//参数3: 创建多少个设备
if( ( ret_v = alloc_chrdev_region(&dev_num,0,1,"dht11") ) < 0 )
{
goto dev_reg_error;
}
init_flag = 1; //标示设备创建成功;
printk("The drive info of dht11:\nmajor: %d\nminor: %d\n",
MAJOR(dev_num),MINOR(dev_num));
cdev_init(&dht11_cdev,&dht11_fops);
if( (ret_v = cdev_add(&dht11_cdev,dev_num,1)) != 0 )
{
goto cdev_add_error;
}
dht11_class = class_create(THIS_MODULE,"dht11");
if( IS_ERR(dht11_class) )
{
goto class_c_error;
}
dht11_device = device_create(dht11_class,NULL,dev_num,NULL,"dht11");
if( IS_ERR(dht11_device) )
{
goto device_c_error;
}
printk("auto mknod success!\n");
//------------ 请在此添加您的初始化程序 --------------//
GPIO45_MODE = (volatile unsigned long *)ioremap(0x10000060, 4);
GPIO45_DATA = (volatile unsigned long *)ioremap(0x10000624, 4);
GPIO45_DIR = (volatile unsigned long *)ioremap(0x10000604, 4);
//如果需要做错误处理,请:goto dht11_error;
*GPIO45_MODE |= (1u<<24);
*GPIO45_DIR |= (1u<<13);
add_code_flag = 1;
//---------------------- END ---------------------------//
goto init_success;
dev_reg_error:
printk("alloc_chrdev_region failed\n");
return ret_v;
cdev_add_error:
printk("cdev_add failed\n");
unregister_chrdev_region(dev_num, 1);
init_flag = 0;
return ret_v;
class_c_error:
printk("class_create failed\n");
cdev_del(&dht11_cdev);
unregister_chrdev_region(dev_num, 1);
init_flag = 0;
return PTR_ERR(dht11_class);
device_c_error:
printk("device_create failed\n");
cdev_del(&dht11_cdev);
unregister_chrdev_region(dev_num, 1);
class_destroy(dht11_class);
init_flag = 0;
return PTR_ERR(dht11_device);
//------------------ 请在此添加您的错误处理内容 ----------------//
dht11_error:
add_code_flag = 0;
return -1;
//-------------------- END -------------------//
init_success:
printk("dht11 init success!\n");
return 0;
}
//exit
static __exit void dht11_exit(void)
{
printk("dht11 drive exit...\n");
if(add_code_flag == 1)
{
//---------- 请在这里释放您的程序占有的资源 ---------//
printk("free your resources...\n");
iounmap(GPIO45_MODE);
iounmap(GPIO45_DATA);
iounmap(GPIO45_DIR);
printk("free finish\n");
//---------------------- END -------------------//
}
if(init_flag == 1)
{
//释放初始化使用到的资源;
cdev_del(&dht11_cdev);
unregister_chrdev_region(dev_num, 1);
device_unregister(dht11_device);
class_destroy(dht11_class);
}
}
/**************** module operations**********************/
//module loading
module_init(dht11_init);
module_exit(dht11_exit);
//some infomation
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("from Jafy");
MODULE_DESCRIPTION("dht11 drive");
/********************* The End ***************************/
运行结果如下:
root@Widora:/etc# dht11_app
[ 5105.220000] dht11 drive open...
[ 5105.220000] dht11 drive read...
the current temperature is: 29
the current humidity is: 34
此内容由EEWORLD论坛网友wateras1 原创,如需转载或用于商业用途需征得作者同意并注明出处