当前位置:文档之家› 嵌入式系统综合实验一

嵌入式系统综合实验一

嵌入式系统综合实验一学号:装 订线实验报告课程名称: 嵌入式系统设计 指导老师:马永昌 成绩:________________实验名称:综合实验一dht11和人体感应传感器 实验类型:验证型 同组学生姓名:孙凡原三、主要仪器设备(必填) 四、操作方法和实验步骤五、实验数据记录和处理 六、实验结果与分析(必填) 七、讨论、心得一、实验目的和要求1.掌握字符设备驱动程序的基本结构和开发方法2.掌握用户空间调用设备驱动的方法3.掌握用户和内核的交互二、实验内容和原理专业:测控技术与仪器姓名:颜睿装订线1.编写温湿度传感器DHT11驱动,传输打印温湿度信息2.编写人体感应传感器驱动,控制LED灯亮灭原理:温湿度传感器DHT11:1.引脚图实际使用传感器没有NC引脚2.数据采集a.数据总时序用户主机发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束后,DHT11 发送响应信号,送出40bit 的数据,幵触发一次信采集。

b.主机发送起始信号连接DHT11的DATA引脚的I/O口输出低电平,且低电平保持时间不能小于18ms,然后等待DHT11 作出应答信号。

装线订c.检测从机应答信号DHT11 的DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后DHT11 的DATA引脚处于输出状态,输出80 微秒的低电平作为应答信号,紧接着输出80 微秒的高电平通知外设准备接收数据。

装订线d.接收数据(1)数据判定规则位数据“0”的格式为:50 微秒的低电平和26-28 微秒的高电平,位数据“1”的格式为:50 微秒的低电平加70微秒的高电平。

接收数据时可以先等待低电平过去,即等待数据线拉高,再延时60us,因为60us大于28us且小于70us,再检测此时数据线是否为高,如果为高,则数据判定为1,否则为0。

(2)数据格式一次传送40 位数据,高位先出8bit 湿度整数数据+ 8bit 湿度小数数据+8bit 温度整数数据+ 8bit 温度小数数据+8bit 校验位。

(3)数据校正判断“8bit 湿度整数数据+ 8bit 湿度小数数据+8bit 温度整数数据+ 8bit 温度小数数据”的结果是否等于8bit校验位。

如果等于则数据接收正确,否则应该放弃这一次的数据,重新接收。

人体感应传感器HCSR-501:装线订1、全自动感应:人进入其感应范围则输出高电平,人离开感应范围则自动延时关闭高电平,输出低电平2、光敏控制(可选择,出厂时未设)可设置光敏控制,白天或光线强时不感应。

3、温度补偿(可选择,出厂时未设):在夏天当环境温度升高至 30~32℃,探测距离稍变短,温度补偿可作一定线的性能补偿。

4、两种触发方式:(可跳线选择)a、不可重复触发方式:即感应输出高电平后,延时时间段一结束,输出将自动从高电平变成低电平;b、可重复触发方式:即感应输出高电平后,在延时时间段内,如果有人体在其感应范围活动,其输出将一直保持高电平,直到人离开后才延时将高电平变为低电平(感应模块检测到人体的每一次活动后会自动顺延一个延时时间段,并且以最后一次活动的时间为延时时间的起始点)。

5、具有感应封锁时间(默认设置:2.5S 封锁时间):感应模块在每一次感应输出后(高电平变成低电平),可以紧跟着设置一个封锁时间段,在此时间段内感应器不接受任何感应信号。

此功能可以实现“感应输出时间”和“封锁时间”两者的间隔工作,可应用于间隔探测产品;同时此功能可有效抑制负载切换过程中产生的各种干扰。

(此时间可设置在零点几秒—几十秒钟)。

6、工作电压范围宽:默认工作电压 DC4.5V-20V。

7、微功耗:静态电流<50 微安,特别适合干电池供电的自动控制产品。

线8、输出高电平信号:可方便与各类电路实现对接。

三、主要仪器设备树莓派、PC机、温湿度传感器、人体感应传感器四、操作方法和实验步骤1.根据说明书编写传感器驱动2.编写可执行程序五、实验数据记录和处理1.传感器驱动demo.c#include<linux/init.h>#include<linux/module.h>#include<linux/device.h>#include<linux/gpio.h>#include<linux/interrupt.h>#include<linux/cdev.h>#include<linux/ioctl.h>线#include<linux/fs.h>#include<linux/delay.h>#include<asm/uaccess.h>#define DRIVER_NAME"Demo"#define DEVICE_NAME"Demo"static dev_t demo_devno; //设备号static struct class *demo_class;static struct cdev demo_dev;static struct gpio_config{int button_num;//人体传感器输出端int out_num;//温湿度传感器数据端int led_num;//人体红外传感器连接的ledint led1_num;//温湿度传感器连接的ledint humidity;//湿度值int temperature;//温度值}config;线static int i=0;static int flag = 0;//open 函数,应用程序调用open系统调用时会调用本函数static int demo_open(struct inode*inode,struct file *filp){printk(KERN_INFO"Demo open\n");return0;}//release 函数,应用程序调用close系统调用时会调用本函数static int demo_release(struct inode *inode, struct file *filp){线if(flag){gpio_free(config.button_num);gpio_free(config.led_num);flag = 0;}printk(KERN_INFO"Demo release\n");return0;}//ioctl 控制函数,应用程序调用ioctl系统调用时会调用本函数static long demo_ioctl(struct file*filp,unsigned int cmd,unsigned long arg) {int err = 0;int buff[40];int humi=0;int temper=0;线switch(cmd){case0://0 表示命令号,一般都用宏定义来控制{if(copy_from_user(&config,( void *)arg,sizeof(struct gpio_config))){ //从用户程序中获取配置数据printk(KERN_ERR"[%s %d] : copy_from userfailed !\n",__func__,__LINE__);return -EFAULT;}printk(KERN_INFO"[%s %d]: Get button gpio num: %d and led gpio num: %d\n ",__func__,__LINE__,config.button_num,confi g.led_num);err =gpio_request_one(config.button_num,GPIOF_IN ,"Light Button");if(err)线 {printk(KERN_ERR"[%s %d] :Request button gpiofailed\n",__func__,__LINE__);return -EFAULT;}err =gpio_request_one(config.led_num,GPIOF_OUT_I NIT_LOW,"LED light");if(err){printk(KERN_ERR"[%s %d] :Request led gpiofailed\n",__func__,__LINE__);gpio_free(config.button _num);return -EFAULT;}线 err =gpio_request_one(config.out_num,GPIOF_IN,"L ight Button");if(err){printk(KERN_ERR"[%s %d] :Request button gpiofailed\n",__func__,__LINE__);gpio_free(config.button _num);gpio_free(config.led_nu m);return -EFAULT;}err =gpio_request_one(config.led1_num,GPIOF_OUT_ INIT_LOW,"LED light");if(err){线printk(KERN_ERR"[%s %d] :Request led gpiofailed\n",__func__,__LINE__);gpio_free(config.out_nu m);gpio_free(config.button _num);gpio_free(config.led_nu m);}flag = 1;break;}case1:{gpio_direction_output(confi g.led_num,0);//设置led输出gpio_direction_input(config .button_num);//设置人体传感器输入线gpio_set_value(config.led_n um,0);//关ledif(gpio_get_value(config.bu tton_num)==0)//人体感应输入低电平,led灭{gpio_set_value(config.l ed_num,0);}elseif(gpio_get_value(config.button_num)==1)//人体感应输入高电平,led亮{gpio_set_value(config.l ed_num,1);}gpio_direction_output(confi g.led1_num,0);//设置led1输出(实际并未使用)线gpio_direction_output(confi g.out_num,1);//设置温湿度传感器数据端的引脚为输出gpio_set_value(config.led1_ num,0);gpio_set_value(config.out_n um,0);//根据dht11的数据传输规则进行操作mdelay(20);gpio_set_value(config.out_n um,1);udelay(40);gpio_direction_input(config .out_num);while(gpio_get_value(config .out_num)==0){}while(gpio_get_value(config .out_num)==1){}for(i=0;i<40;i++)线 {while(gpio_get_value(co nfig.out_num)==0){}udelay(50);if(gpio_get_value(confi g.out_num)==1)//获得的数据存入buff[40]数组 {buff[i]=1;while(gpio_get_valu e(config.out_num)==1){}}elsebuff[i]=0;}for(i=0;i<16;i++)//湿度移位相加{线 humi=humi*2+buff[i]; }for(i=16;i<32;i++)//温度移位相加{temper=temper*2+buff[i] ;}config.humidity=humi;config.temperature=temper;gpio_direction_output(confi g.out_num,1);//测量结束引脚置高电平gpio_set_value(config.out_n um,1);mdelay(2000);//延时一段时间再测量线if(copy_to_user((void*)arg,&config,sizeof(struct gpio_config)))//数据传入用户态{printk(KERN_ERR"[%s %d] : copy to user failed !\n",__func__,__LINE__);return -EFAULT;}flag=1;break;}default:printk(KERN_INFO"[%s %d]:In valid cmd", __func__,__LINE__);break;}return0;}线static struct file_operations demo_fops = { .owner = THIS_MODULE,.open = demo_open,.release = demo_release,.unlocked_ioctl = demo_ioctl,};static int __init demo_init(void){int err;printk(KERN_INFO"Demo Init \n");err =alloc_chrdev_region(&demo_devno,0,1,DRIVER_ NAME);if(err < 0){线goto err;}cdev_init(&demo_dev,&demo_fops);err = cdev_add(&demo_dev,demo_devno,1);if(err < 0){printk(KERN_ERR"[%s,%d]add cdev failed\n",__func__,__LINE__);goto FREE_DEVNO;}//自动生成设备文件在/dev目录下,文件名为DEVICE_NAMEdemo_class =class_create(THIS_MODULE,DEVICE_NAME);if(IS_ERR(demo_class)){printk(KERN_ERR"[%s,%d]class create failed\n",__func__,__LINE__);线goto DEV_FREE;}device_create(demo_class,NULL,demo_devn o,NULL,DEVICE_NAME);return0;DEV_FREE:cdev_del(&demo_dev);FREE_DEVNO:unregister_chrdev_region(demo_devno, 1); err:return err;}static void demo_exit(void){if(flag){gpio_free(config.button_num);gpio_free(config.led_num);线gpio_free(config.out_num);gpio_free(config.led1_num);}device_destroy(demo_class,demo_devno);class_destroy(demo_class);cdev_del(&demo_dev);unregister_chrdev_region(demo_devno, 1);printk(KERN_INFO"Demo exit\n");}module_init(demo_init);module_exit(demo_exit);MODULE_AUTHOR("hyg");MODULE_DESCRIPTION("BUTTON LED Driver"); MODULE_LICENSE("GPL");2.应用程序demo.c#include<stdio.h>线#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/ioctl.h>#include<sys/time.h>#include<sys/ioctl.h>#include<errno.h>#include<fcntl.h>struct gpio_config{int button_num;int out_num;int led_num;int led1_num;int humidity;int temperature;};int main(int argc, char **argv)线{int fd;float h;float t;struct gpio_config config;config.button_num = 26;//人体感应传感器引脚config.led_num = 3;//led引脚config.out_num = 5;//dht11引脚config.led1_num = 6;//未使用config.humidity = 0;//湿度config.temperature = 0;//温度fd = open("/dev/Demo", O_RDWR);if (fd < 0) {perror("/dev/Demo");exit(0);}ioctl(fd,0,&config);//分配引脚传入内核态线while(1){ioctl(fd,1,&config); //启动驱动进行数据采集h=(float)config.humidity/256;t=(float)config.temperature/256;printf("humidity: %0.2f %rh\n",h);printf("temperature: %0.2f C\n",t);sleep(0.5);}close(fd);return0;}3.makefile修改装 订线a 用户程序makefile 更改gcc 路径为本机路径: CC:=/home/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc b.驱动程序makefile修改linux 文件夹路径KERNELDIR:=/home/linux/4.硬件接线5.编译加载运行 a.环境变量装订线b.编译c.拷贝d.加载运行六、实验结果与分析人体传感器有反应,led灯亮装线订实验完成七、讨论、心得由于之前实现了超声波传感器的驱动,这次实验还是比较简单的,主要要看懂传感器说明书的流程,多调试几次就可以实现。

相关主题