IO序列化操作的本质在于实现对象状态的持久化与可移植性。通过将对象及其状态信息编码为字节流系统能够在需要时准确还原数据结构。理解其底层实现原理有助于开发者在实际项目中合理选择序列化协议优化IO性能。一、概述ioqueue 模块提供了 IO 序列操作的功能可以通过硬件定时器精确控制 GPIO 的操作时序。注意事项对于 Air700EXX 系列、Air780EXX 系列、Air8000 系列模组硬件定时器有如下要求硬件定时器 id0-5六个硬件定时器定时器精度20 微秒为硬件支持的最小时间单位。3 和 5 固定被底层占用不可使用pwm 功能依赖硬件定时器ioqueue 不可与 pwm 功能同时使用pwm0 对应 0pwm4 对应 4以此类推注意Air6101/Air8101 不支持此功能1.1 使用场景ioqueue 主要是输出一些特殊的电平序列捕获自定义协议。如果有以下需要就可以使用该库精确控制多个 GPIO 的开关时序循环执行固定的 GPIO 操作序列捕获 GPIO 边沿变化的精确时间戳模拟非标准通信协议1.1.1 输入捕获场景以 DHT11 数据读取为例单总线协议要求严格的时序控制、主机需要先发送特定启动信号、传感器响应时间精确到微秒级、数据通过脉冲宽度编码使用流程下面演示使用硬件定时器精确控制 DHT11 通信时序通过捕获下降沿时间戳解码温湿度数据实现微秒级精确通信dht11 通讯协议介绍数据分为小数部分和整数部分一次完整的数据传输为 40bit高位先出数据格式8bit 湿度整数数据 8bit 湿度小数数据 8bit 温度整数数据 8bit 温度小数数据 8bit 校验8bit 校验 8bit 湿度整数数据 8bit 湿度小数数据 8bit 温度整数数据 8bit 温度小数数据校验可以判断数据是否正确发送DHT11 工作时序主机发送起始信号以后DHT11 发送响应信号然后发送 40bit 的数据高位在前总时序图如下起始信号总线空闲状态由 DHT11 内置上拉电阻拉高主机拉低总线至少 18ms后释放总线20-40usDHT11 响应存在的 DHT11 会及时响应主机同时拉低总线80us后释放总线80us然后拉低总线表示开始传送数据发送数据当总线是低电平是表示开始发送数据同时存在50us 低电平时隙之后拉高总线高电平的持续时间表示发送 0 或者 1当高电平持续时间为26us-28us表示发送0高电平持续时间为70us时表示发送1数据发送完毕由上拉电阻拉高置回空闲高电平状态具体波形如下1.1.2 输出精确脉冲场景需要不同的脉冲宽度、软件循环无法满足精度要求、需要连续输出大量脉冲使用流程下面演示利用硬件定时器生成固定频率或可变宽度的精确脉冲序列支持连续和单次延时模式实现微秒级脉冲控制固定间隔脉冲可变宽度脉冲序列二、核心示例示例可参考 1.1.1 章节具体使用分析。三、常量详解核心库常量顾名思义是由 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值在脚本代码中不需要声明可直接调用ioqueue 模块没有常量。四、函数详解ioqueue.init(hwtimer_id, cmd_cnt, repeat_cnt)功能初始化一个 io 操作队列。参数hwtimer_idcmd_cntrepeat_cnt返回值无返回值。示例ioqueue.setdelay(hwtimer_id, time_us, time_tick, continue)功能对 io 操作队列增加延时命令。参数hwtimer_idtime_ustime_tickcontinue返回值无返回值。示例ioqueue.delay(hwtimer_id)功能对 io 操作队列增加一次重复延时在前面必须有 setdelay 并且是连续延时。注意事项必须在前面的 ioqueue.setdelay 设置 continuetrue参数hwtimer_id返回值无返回值。示例ioqueue.setgpio(hwtimer_id, pin, is_input, pull_mode, init_level)功能对 io 操作队列增加设置 gpio 命令。参数hwtimer_idpinis_inputpull_modeinit_level返回值无返回值。示例ioqueue.input(hwtimer_id, pin)功能对 io 操作队列增加读取 gpio 命令。应用场景在精确时序点读取 GPIO 电平状态使用时必须先调用 ioqueue.setgpio 设置输入模式然后通过 ioqueue.get()读取输入数据参数hwtimer_idpin返回值无返回值。读取的数据需要通过 ioqueue.get 获取。示例ioqueue.output(hwtimer_id, pin, level)功能对 io 操作队列增加输出 GPIO 命令。参数hwtimer_idpinlevel返回值无返回值。示例ioqueue.set_cap(hwtimer_id, pin, pull_mode, irq_mode, max_tick)功能对 io 操作队列增加设置捕获某个 IO 命令。捕获的配置命令参数hwtimer_idpinpull_modeirq_modemax_tick返回值无返回值。示例ioqueue.capture(hwtimer_id)功能对 io 操作队列增加捕获一次 IO 状态命令。捕获的执行命令必须先经过 ioqueue.set_cap 配置后才能使用 ioqueue.capture 来捕获一个 set_cap 配置可以被多个 capture 命令复用参数hwtimer_id返回值无返回值。捕获的数据需要通过 ioqueue.get 获取。示例ioqueue.cap_done(hwtimer_id, pin)功能对 io 操作队列结束捕获某个 IO 命令。使用场景1.捕获任务完成时 主动结束告诉系统数据读取完成停止 gpio 捕获2.切换捕获目标时比如从捕获 gpio1 切换到捕获 gpio2需要先结束捕获 gpio1。3.错误处理或者提前退出时调用。参数hwtimer_idpin返回值无返回值。示例ioqueue.get(hwtimer_id, input_buff, capture_buff)功能获取 io 操作队列中输入和捕获的数据。注意事项inputset_capcapture 这三个配置接口配置的功能缓存到的输入数据和捕获数据都是通过 get 接口来读取出来input_buff ← 存储 ioqueue.input() 的即时电平采样结果capture_buff ← 存储 ioqueue.capture() 的边沿事件 时间戳input_cnt 成功的 ioqueue.input() 操作数量capture_cnt 成功的 ioqueue.icapture() 操作数量可能因超时而小于计划数参数hwtimer_idinput_buffcapture_buff返回值local input_cnt, capture_cnt ioqueue.get(hwtimer_id, input_buff, capture_buff)input_cntcapture_cnt示例ioqueue.start(hwtimer_id)功能启动 io 操作队列。参数hwtimer_id返回值无返回值。示例ioqueue.stop(hwtimer_id)功能停止 io 操作队列可以通过 start 从头开始。参数hwtimer_id返回值local loop_cnt, cmd_cnt ioqueue.stop(hwtimer_id)loop_cntcmd_cnt示例ioqueue.release(hwtimer_id)功能释放 io 操作队列的资源下次使用必须重新 init。参数hwtimer_id返回值无返回值。示例ioqueue.clear(hwtimer_id)功能清空 io 操作队列。此接口重置了命令队列但保留了硬件定时器资源可以直接添加新的命令。前提是你确信之前队列的状态完全被清空且新的命令序列与之前的结构兼容。参数hwtimer_id返回值无返回值。示例ioqueue.done(hwtimer_id)功能检测 io 操作队列是否已经执行完成。参数hwtimer_id返回值local is_done ioqueue.done(hwtimer_id)is_done示例ioqueue.exti(pin, pull_mode, irq_mode, onoff)功能启动/停止一个带系统 tick 返回的外部中断。ioqueue.exti 是一个独立的外部中断接口与 ioqueue 队列系统完全分离提供简单的 GPIO 边沿事件捕获功能。使用场景简单的按键检测、传感器状态监控、旋转编码器计数参数pinpull_modeirq_modeonoff返回值无返回值。示例五、模组支持说明仅支持 Air700EXX 系列、Air780EXX 系列、Air8000 系列模组Air6101/Air8101 不支持此功能。今天的内容就分享到这里了~