开发环境: RT-Thread版本:4.1.0 操作系统:Windows10 RT-Thread Studio版本:2.2.3 1 AHT10简介AHT10是一款精度高,完全校准,贴片封装的温湿度传感器,采用标准IIC 通信方式,超小的体积、极低的功耗。温湿度传感器均在高精度的恒温恒湿腔室中进行出厂校准,直接输出经温度补偿后的湿度、温度等信息,用户无需要对湿度进行温度补偿,便可得到准确的温湿度信息。 SDA和SCL都需要接上拉电阻;VDD脚需要外接10uF的滤波电容。 AHT10的读取比较简单,分为两步: 第一步:初始化 AHT10初始化相关的命令如下: 第二步:读取温湿度 这个就更简单了,发送数据读取命令即可。 关于AHT10更详细的说明请参看《AHT10技术手册》。 2 AHT10配置RT-Thread提供了AHT10的驱动软件包,配置如下: AHT10与主机是通过I2C通信的,因此这里还需要配置一个I2C接口。 笔者这里使用的是硬件I2C2,对应的引脚始PB10和PB11,当然也可使用软件I2C或者硬件I2C接口。 3 AHT10应初始化及实现首先要将 AHT10设备初始化,参考AHT10文档的示例即可。 #include "sensor_asair_aht10.h" #defineAHT10_I2C_BUS "i2c2" int rt_hw_aht10_port(void) { struct rt_sensor_config cfg; cfg.intf.dev_name = AHT10_I2C_BUS; cfg.intf.user_data = (void *)AHT10_I2C_ADDR; rt_hw_aht10_init("aht10", &cfg); return RT_EOK; } INIT_COMPONENT_EXPORT(rt_hw_aht10_port); 当初始化设备后,可以在终端查看相应的设备。 接下来就是应用程序的编写: //AHT10温湿度采集 #include "aht10.h" /* 定义一个温湿度采集线程句柄结构体指针 */ static rt_thread_t aht10_thread = RT_NULL; /* 温湿度采集线程入口函数*/ static void aht10_thread_entry(void *parameter) { aht10_device_t dev; float humidity, temperature; rt_hw_aht10_port(); dev = aht10_init(AHT10_I2C_BUS); if (dev == RT_NULL) { rt_kprintf(" The sensor initializes failure"); } else { rt_kprintf(" The sensor initializes ok!"); } while (1) { /* read humidity 采集湿度 */ humidity = aht10_read_humidity(dev); rt_kprintf("humidity : %d.%d %%n", (int)humidity, (int) (humidity * 10) % 10); /* former is integer and behind is decimal */ /* read temperature 采集温度 */ temperature =aht10_read_temperature(dev); rt_kprintf("temperature: %d.%d n", (int)temperature, (int)(temperature * 10) % 10); /* former is integer and behind isdecimal */ rt_thread_mdelay(1000); } } static int aht10_app_init(void) { /* 创建温湿度采集线程*/ aht10_thread = rt_thread_create("aht10 thread", /* 线程的名称 */ aht10_thread_entry, /* 线程入口函数 */ RT_NULL, /* 线程入口函数的参数 */ 1024, /* 线程栈大小,单位是字节 */ 25, /* 线程的优先级,数值越小优先级越高*/ 10); /* 线程的时间片大小 */ /* 如果获得线程控制块,启动这个线程 */ if (aht10_thread != RT_NULL) rt_thread_startup(aht10_thread); else rt_kprintf("aht10 thread create failure !!!n"); return RT_EOK; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(aht10_app_init,aht110 thread); 最后编译下载到板卡后,会在串口中每 1s 打印一次温湿度数据。
4 AHT10总结RT-Thread包含AHT10驱动,这里就没有去造轮子了,但是作为学习者,还是要去了解AHT10的原理及具体实现。下面就AHT10驱动在RTT中的实现做个总结。 熟悉RT-Thread系统都知道,RT-Thread将各个模块进行抽象,为上层提供统一的操作接口,依次提高上层代码的可重用性,自然也提高了应用开发效率。RT-Thread的驱动框架:
应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。 I/O设备模型框架位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。 l I/O设备管理层实现了对设备驱动程序的封装。应用程序通过 I/O 设备层提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,从而降低了代码的耦合性、复杂性,提高了系统的可靠性。 l 设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。 l 设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。它负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中。 更加详细的内容请参看RT-Thread官方手册。
这里主要讲解Sensor驱动,RT-Thread将各个Sensor进行抽象,将不同厂商的Sensor合并为Sensor设备,从而提高了代码的重用性,提高开发效率。既然是总结,这里就只说重点,先看看AHT10设备驱动的时序图:
传感器数据接收和发送数据的模式分为 3 种:中断模式、轮询模式、FIFO模式。在使用的时候,这 3 种模式只能选其一,若传感器的打开参数 oflags 没有指定使用中断模式或者 FIFO 模式,则默认使用轮询模式。 oflags 参数支持下列参数: #define RT_DEVICE_FLAG_RDONLY 0x001 /* 标准设备的只读模式,对应传感器的轮询模式 */ #define RT_DEVICE_FLAG_INT_RX 0x100 /* 中断接收模式 */ #define RT_DEVICE_FLAG_FIFO_RX 0x200 /* FIFO 接收模式 */ AHT10设备比较简单,采用的是轮询模式,其设备注册函数如下: result =rt_hw_sensor_register(sensor_humi, name, RT_DEVICE_FLAG_RDONLY, RT_NULL); 硬件初始化如下: int rt_hw_aht10_port(void) { struct rt_sensor_config cfg; cfg.intf.dev_name = AHT10_I2C_BUS; cfg.intf.user_data = (void *)AHT10_I2C_ADDR; rt_hw_aht10_init("aht10", &cfg); return RT_EOK; } INIT_COMPONENT_EXPORT(rt_hw_aht10_port); 注意INIT_COMPONENT_EXPORT表示组件初始化,初始化顺序为4。 好了,AHT10就讲到这里了。
|