当前位置: 首页 > news >正文

网站开发 兼职挣钱吗建设公司企业简介

网站开发 兼职挣钱吗,建设公司企业简介,wordpress uehtml,app001推广平台目录 概述 1 认识DHT11 1.1 DHT11特性 1.2 DHT11数据格式 1.3 DHT11与MCU通信 1.4 DHT11信号解析 1.4.1 起始信号 1.4.2 解析信号0 1.4.3 解析信号1 2 驱动开发 2.1 硬件接口 2.2 更新设备树 2.2.1 添加驱动节点 2.2.2 编译.dts 2.2.3 更新板卡中的.dtb 2.3 驱…目录 概述 1 认识DHT11 1.1 DHT11特性 1.2 DHT11数据格式 1.3 DHT11与MCU通信 1.4 DHT11信号解析 1.4.1 起始信号 1.4.2 解析信号0 1.4.3 解析信号1 2 驱动开发 2.1 硬件接口 2.2 更新设备树 2.2.1 添加驱动节点 2.2.2 编译.dts 2.2.3 更新板卡中的.dtb 2.3 驱动程序实现 2.3.1 编写驱动程序 2.3.2 编写Makefile  3 测试程序 3.1 编写测试程序 3.2 编写Makefile 4 编译和运行 4.1 编译和安装驱动程序 4.2 编译和运行测试程序 5 波形分析 5.1 起始信号波形 5.2 信息bit 0波形 5.3 信息bit 1波形 概述 本文介绍platform tree下如何设计一个单总线设备的驱动根据datasheeet提供的波形图使用代码来实现该驱动程序。然后用逻辑分析仪捕捉信号波形分析其是否和datasheet中的波形一致。 1 认识DHT11 1.1 DHT11特性 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。 它应用专用的数字模块采集技术和温湿度传感技术确保产品具有极高的可靠性与卓越的长期稳定性。 由上表可得 温度范围 0~ 50℃ 低于或者高于这个范围的温度不能测量 湿度范围20~90%RH 1.2 DHT11数据格式 DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右读一次数据总共包括8bytes( 40 bit )具体格式如下: Byte-0: 8bit 湿度 整数 数据 Byte-1: 8bit 湿度 小数 数据 Byte-2: 8bit 温度 整数 数据 Byte-3: 8bit 温度 小数 数据 byte-4: 8bit校验和 Byte-0 Byte-1 Byte-2 Byte-3 1.3 DHT11与MCU通信 Step-1: Master 发送起始信号-------dth11, 信号变化规律为 1 - 0 - 1 Step-2: dht11发出响应信号信号特征为 0 -1 Step-3dht11发送数据bit位总共40个bit 1.4 DHT11信号解析 1.4.1 起始信号 Step-1 Master 发出触发信号1 - 0, 该信号至少持续18ms step-2 Master电平0 -1,该电平持续20~40us Step-3 dht11发送响应信号0-1该电平持续80us step-4 dht11发送信号1准备发送数据信息该电平持续时间80us 1.4.2 解析信号0 信号0特征 10 -1持续 50us 21-0持续26~28us 1.4.3 解析信号1 信号1特征 10 -1持续 50us 21-0持续70us 2 驱动开发 2.1 硬件接口 DHT-11与MCU之间的连接图 在板卡ATK-DL6Y2C上DTH-11的对应接口 GPIO4_19: DHT11-IO 硬件实物图 DHT11引脚说明: 2.2 更新设备树 2.2.1 添加驱动节点 DHT11引脚和IMX.6ULL引脚对应关系 GPIO4_19: DHT11-IO .dts文件路径 /home/mftang/linux_workspace/study_atk_dl6y2c/kernel/atk-dl6u2c/arch/arm/boot/dts/imx6ull-14x14-evk.dts 在.dts文件中添加如下代码 //mftang: users dht11, 2024-2-14// IO: GPIO-4-PIN19mftangdht11 {compatible atk-dl6y2c,dht11;pinctrl-names default;pinctrl-0 pinctrl_gpio_mftang_1_wire;gpios gpio4 19 GPIO_ACTIVE_HIGH;status okay;}; 其在imx6ull-14x14-evk.dts中位置 2.2.2 编译.dts 编译.dts文件并把编译生成的.dtb文件发送到NFS共享目录下便于在板卡中操作该文件。 1在内核根目录下使用如下命令编译.dts文件 make dtbs 2 复制 .dtb 文件至NFS共享目录 cp arch/arm/boot/dts/imx6ull-14x14-emmc-4.3-480x272-c.dtb /home/mftang/nfs/atk_dl6y2c/ 2.2.3 更新板卡中的.dtb 复制.dtb文件到相应的运行目录然后重新板卡 cp /mnt/atk_dl6y2c/imx6ull-14x14-emmc-4.3-480x272-c.dtb /run/media/mmcblk1p1 reboot板卡后内核会重新读取.dtb文件。然后在/proc/device-tree目录下查看板卡device tree使用如下命令 cd /proc/device-tree ls -l 运行该命令后在该目录下可以看见sensor信息说明device已经加载到内核 2.3 驱动程序实现 2.3.1 编写驱动程序 创建drv_dht11.c并在该文件中编写驱动程序驱动程序代码地址 /*************************************************************** Copyright 2024-2029. All rights reserved. 文件名 : drv_14_dht11.c 作者 : tangmingfei2013126.com 版本 : V1.0 描述 : dht11 驱动程序, GPIO4_PIN19-----DHT11 IO port 其他 : 无 日志 : 初版V1.0 2024/1/30 使用方法 1) 在.dts文件中定义节点信息//mftang: users dht11, 2024-2-14// IO: GPIO-4-PIN19mftangdht11 {compatible atk-dl6y2c,dht11;pinctrl-names default;pinctrl-0 pinctrl_gpio_mftang_1_wire;gpios gpio4 19 GPIO_ACTIVE_HIGH;status okay;};2) 在驱动匹配列表 static const struct of_device_id dht11_of_match[] {{ .compatible atk-dl6y2c,dht11 },{ } // Sentinel }; ***************************************************************/ #include linux/types.h #include linux/kernel.h #include linux/delay.h #include linux/ktime.h #include linux/ide.h #include linux/init.h #include linux/module.h #include linux/errno.h #include linux/gpio.h #include linux/cdev.h #include linux/device.h #include linux/of_gpio.h #include linux/semaphore.h #include linux/timer.h #include linux/irq.h #include linux/wait.h #include linux/poll.h #include linux/fs.h #include linux/fcntl.h #include linux/platform_device.h #include asm/mach/map.h #include asm/uaccess.h #include asm/io.h#define DEVICE_NAME treedht11 // dev/treedht11/* dht11dev设备结构体 */ struct dht11stru_dev{dev_t devid; /* 设备号 */struct cdev cdev; /* cdev */struct class *class; /* 类 */struct device *device; /* 设备 */int major; /* 主设备号 */struct device_node *node; /* dht11设备节点 */int userdht11; /* dht11 GPIO标号*/struct gpio_desc *pin; };struct dht11stru_dev dht11dev; /* dht11设备 */ int us_low_array[40]; int us_low_index; int us_array[40]; int time_array[40]; int us_index;/*dht11 driver */ static void dht11_release( void ) {gpiod_direction_output(dht11dev.pin, 1); }static void dht11_start(void) {gpiod_direction_output(dht11dev.pin, 1);mdelay(30);gpiod_set_value( dht11dev.pin, 0);mdelay(20);gpiod_set_value(dht11dev.pin, 1);udelay(40);gpiod_direction_input(dht11dev.pin); }static int dht11_wait_ack(void) {int timeout_us 20000;/* 等待低电平 */while (gpiod_get_value(dht11dev.pin) --timeout_us){udelay(1);}if (!timeout_us){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}/* 现在是低电平 *//* 等待高电平 */timeout_us 200;while (!gpiod_get_value(dht11dev.pin) --timeout_us){udelay(1);}if (!timeout_us){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}/* 现在是高电平 *//* 等待低电平 */timeout_us 200;while (gpiod_get_value(dht11dev.pin) --timeout_us){udelay(1);}if (!timeout_us){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}return 0; }static int dht11_read_byte( unsigned char *datalist ) {int i;int us 0;unsigned char data 0;int timeout_us 200;u64 pre, last;for (i 0; i 8; i){/* 现在是低电平 *//* 等待高电平 */timeout_us 400;us 0;while (!gpiod_get_value(dht11dev.pin) --timeout_us){udelay(1);us;}if (!timeout_us){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}us_low_array[us_low_index] us;/* 现在是高电平 *//* 等待低电平,累加高电平的时间 */timeout_us 20000000;us 0;/* set another gpio low */pre ktime_get_boot_ns();while (1) {last ktime_get_boot_ns();if (last - pre 40000)break;}if (gpiod_get_value(dht11dev.pin)){/* get bit 1 */data (data 1) | 1;/* 当前位的高电平未结束, 等待 */timeout_us 400;us 0;while (gpiod_get_value(dht11dev.pin) --timeout_us){udelay(1);us;}if (!timeout_us){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}}else{/* get bit 0 */data (data 1) | 0;}}*datalist data;return 0; }static int dht11_get_value( unsigned char *data ) {unsigned long flags;int i;local_irq_save(flags); // 关中断us_index 0;us_low_index 0;/* 1. 发送高脉冲启动DHT11 */dht11_start();/* 2. 等待DHT11就绪 */if (dht11_wait_ack()){local_irq_restore(flags); // 恢复中断printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -EAGAIN;}/* 3. 读5字节数据 */for (i 0; i 5; i){if (dht11_read_byte(data[i])){local_irq_restore(flags); // 恢复中断printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -EAGAIN;}}/* 4. 释放总线 */dht11_release();local_irq_restore(flags); // 恢复中断/* 5. 根据校验码验证数据 */if (data[4] ! (data[0] data[1] data[2] data[3])){printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return -1;}return 0; }/*linux driver 驱动接口 实现对应的open/read/write等函数填入file_operations结构体 */ static ssize_t dht11_drv_read ( struct file *file, char __user *buf, size_t size, loff_t *offset) {unsigned char data[4];int err;if( !dht11_get_value( data ) ){printk( %s line %d \r\n, __FUNCTION__, __LINE__);err copy_to_user(buf, data, 4);return 4;}return -1; }static int dht11_drv_close(struct inode *node, struct file *file) {printk( %s line %d \r\n, __FUNCTION__, __LINE__);return 0; }static int dht11_drv_open(struct inode *inode, struct file *filp) {filp-private_data dht11dev; /* 设置私有数据 */return 0; }/* 定义driver的file_operations结构体 */ static struct file_operations dht11_fops {.owner THIS_MODULE,.read dht11_drv_read,.open dht11_drv_open,.release dht11_drv_close, };/* 1. 从platform_device获得GPIO* 2. gpioirq* 3. request_irq*/ static int dht11_probe(struct platform_device *pdev) {printk(dht11 driver and device was matched!\r\n);/* 1. 获得硬件信息 */dht11dev.pin gpiod_get(pdev-dev, NULL, 0);if (IS_ERR(dht11dev.pin)){printk(%s line %d get pin parameter error! \n, __FUNCTION__, __LINE__);}/* 2. device_create */device_create( dht11dev.class, NULL, MKDEV( dht11dev.major, 0 ), NULL, DEVICE_NAME); // device name return 0; }static int dht11_remove(struct platform_device *pdev) {printk(%s line %d\n, __FUNCTION__, __LINE__);device_destroy( dht11dev.class, MKDEV( dht11dev.major, 0));gpiod_put(dht11dev.pin);return 0; }static const struct of_device_id atk_dl6y2c_dht11[] {{ .compatible atk-dl6y2c,dht11 },{ }, };/* 1. 定义platform_driver */ static struct platform_driver dht11_driver {.probe dht11_probe,.remove dht11_remove,.driver {.name atk_dht11,.of_match_table atk_dl6y2c_dht11,}, };/* 2. 在入口函数注册platform_driver */ static int __init dht11_init(void) {int err;printk(%s line %d\n,__FUNCTION__, __LINE__);/* register file_operations */dht11dev.major register_chrdev( 0, DEVICE_NAME, /* device name */dht11_fops); /* create the device class */dht11dev.class class_create(THIS_MODULE, dht11_class);if (IS_ERR(dht11dev.class)) {printk(%s line %d\n, __FUNCTION__, __LINE__);unregister_chrdev( dht11dev.major, DEVICE_NAME);return PTR_ERR( dht11dev.class );}err platform_driver_register(dht11_driver); return err; }/* 3. 有入口函数就应该有出口函数卸载驱动程序时就会去调用这个出口函数* 卸载platform_driver*/ static void __exit dht11_exit(void) {printk(%s line %d\n, __FUNCTION__, __LINE__);platform_driver_unregister(dht11_driver);class_destroy(dht11dev.class);unregister_chrdev(dht11dev.major, DEVICE_NAME); }/*4. 驱动入口和出口函数 */ module_init(dht11_init); module_exit(dht11_exit);MODULE_LICENSE(GPL); MODULE_AUTHOR(tangmingfei2013126.com); 2.3.2 编写Makefile  在驱动程序同级目录中创建Makefile然后编写如下代码 PWD : $(shell pwd)KERNEL_DIR/home/mftang/linux_workspace/study_atk_dl6y2c/kernel/atk-dl6u2c ARCHarm CROSS_COMPILE/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-export ARCH CROSS_COMPILEobj-m: drv_14_dht11.oall:$(MAKE) -C $(KERNEL_DIR) M$(PWD) modulesclean:rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *.symvers 3 测试程序 3.1 编写测试程序 编写一个测试程序目的是验证驱动程序是否能正常工作 /*************************************************************** Copyright 2024-2029. All rights reserved. 文件名 : test_14_dht11.c 作者 : tangmingfei2013126.com 版本 : V1.0 描述 : 测试dth11驱动程序 其他 : 无 日志 : 初版V1.0 2024/02/15***************************************************************/ #include sys/types.h #include sys/stat.h #include linux/types.h #include linux/i2c-dev.h #include linux/i2c.h #include sys/ioctl.h #include unistd.h #include stdio.h #include string.h #include fcntl.h #include stdlib.h #include linux/fs.h #include errno.h #include assert.h #include string.h #include time.h#define DEV_FILE /dev/treedht11int main(void) {int fd;int count_run 0;unsigned char data[4];fd open(DEV_FILE, 0);if (fd -1){printf(can not open file: %s \n, DEV_FILE);return -1;}while( count_run 10000){count_run;if (read(fd, data, 4) 4) {printf(get humidity : %d.%d\n, data[0], data[1]);printf(get temprature: %d.%d\n, data[2], data[3]);} else {perror(read dht11 device fail!\n);}sleep(1);}close(fd);return 0; }3.2 编写Makefile CFLAGS -Wall -O2 CC/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc STRIP/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-striptest_14_dht11: test_14_dht11.o$(CC) $(CFLAGS) -o test_14_dht11 test_14_dht11.o$(STRIP) -s test_14_dht11clean:rm -f test_14_dht11 test_14_dht11.o 4 编译和运行 4.1 编译和安装驱动程序 1 编译驱动程序并将其copy到NFS的共享目录中方便在板卡中安装该程序 2 在板卡中安装该驱动程序 使用命令 insmod dev_14_dth11.ko 安装成功后使用命令查看驱动 ls /dev -l 4.2 编译和运行测试程序 1) 编译测试程序并将其copy到NFS的共享目录中方便在板卡中运行该程序 2在板卡中运行测试程序 5 波形分析 在板卡上运行测试程序然后使用逻辑分析仪捕捉DHT11-IO上的波形分析其信号特征以更好的理解驱动程序。 5.1 起始信号波形 datasheet 上提供的波形 逻辑分析仪上捕捉的波形 查看电平持续时间 5.2 信息bit 0波形 datasheet 上提供的波形 逻辑分析仪上捕捉的波形 5.3 信息bit 1波形 datasheet 上提供的波形 逻辑分析仪上捕捉的波形
http://www.w-s-a.com/news/670801/

相关文章:

  • 搞笑网站源码百度快照替代
  • 重庆网站建设哪家公司哪家好关键词是怎么排名的
  • 青县网站建设今天国际大事新闻
  • 深圳正规网站制作哪里好怎样优化网络
  • 米拓网站建设教程dw成品网站成品视频教学
  • 用jsp做的网站源代码天门网站网站建设
  • 百度如何把网站做链接地址有没有资源可以在线观看
  • 淮安做网站找哪家好电子商务网站建设规划书的内容
  • 开发网站建设用什么框架php黄页系统
  • 聊城制作网站全球十大电商平台排名
  • 用什么来网站开发好mega menu wordpress
  • 深圳制作网站有用吗wordpress的主题
  • 网站的规划与创建天津市南开区网站开发有限公司
  • 免备案网站主机建站哪个平台好
  • python做网站 不适合单页营销分享网站
  • 珠海市研发网站建设建设网站挣钱
  • 阿里巴巴国际站特点做wps的网站赚钱
  • wordpress更换域名后网站打不开宜昌建设银行网站
  • 写出网站开发的基本流程百度网页电脑版入口
  • 网站设计有限公司怎么样网站建设西班牙语
  • 网站安全解决方案宁波seo网络推广优化价格
  • 做网站带来好处wordpress可以做oa系统吗
  • 建筑设计人才招聘网站h5营销型网站suteng
  • 做app和网站怎样如何做html网站
  • php开发手机端网站开发更换网站标题
  • 提供网站建设报价延津县建设局网站
  • 江苏网站建设流程土巴兔全包装修怎么样
  • 环保网站建设方案带漂浮广告的网站
  • 淘宝客合伙人网站建设建站前端模板
  • 网站单页模板怎么安装中世纪变装小说wordpress