开发环境:
主机:Ubuntu12.04
开发板:RT5350
Openwrt:Openwrt15.05
下图是我们温度传感器的接入引脚,3.3V 供电,io 口接 P13 的 GP0( GPIO0 的简称 )。DHT11数字温湿度传感器 是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测型号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。
关于字符设备驱动程序的使用,我们可以参照点亮 led 灯的那个实验,这里只给出跟DHT11 密切相关的驱动程序,详细的程序请查看我们的驱动文件!
//配置连接温度传感器的引脚#define DHT11_L *GPIO21_0_DATA &= ~(1< < 0) //低电平#define DHT11_H *GPIO21_0_DATA |= (1< < 0) //高电平#define DHT11_OUT *GPIO21_0_DIR |= (1< < 0) //输出#define DHT11_IN*GPIO21_0_DIR &= ~(1< < 0) //输入#define DHT11_STA*GPIO21_0_DATA & 0x01//寄存器定义volatile unsigned long *GPIO21_0_DIR;volatile unsigned long *GPIO21_0_DATA;//初始化函数必要资源定义//用于初始化函数当中//devICe number;dev_t dev_num;//struct devstruct cdev dht11_cdev;//auto "mknode /dev/dht11 c dev_num minor_num"struct class *dht11_class = NULL;struct device *dht11_device = NULL;//从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 error1n");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 error2n");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 error1n");return 0;} } t_count = 0; udelay(50); while(DHT11_STA) {udelay(1);t_count++;if(t_count > 250){printk("read_dht11 error2n");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 error3n"); } return dht11;}//openstatic int dht11_open(struct inode *inode, struct file *file){printk("dht11 drive open...n");DHT11_OUT;DHT11_H;return 0;}//closestatic int dht11_close(struct inode *inode , struct file *file){return 0;}//readstatic 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;}//structstatic const struct file_operations dht11_fops = {.owner = THIS_Module,.open = dht11_open,.release = dht11_close,.read = dht11_read,};//条件值变量,用于指示资源是否正常使用unsigned char init_flag = 0;unsigned char add_code_flag = 0;//initstatic __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 =