2024-9-30 14:42
114 次阅读|
0 个评论
01 物联网系统中为什么要使用IIC I/O扩展芯片 在物联网系统中使用IIC(也称为I2C)I/O扩展芯片的原因主要可以归结为以下几点: 1、扩大I/O端口数量 硬件资源限制:许多微控制器(MCU)自带的I/O端口数量有限,但物联网项目往往需要连接大量的传感器、执行器和其他外设。I2C I/O扩展芯片能够通过I2C接口提供额外的I/O端口,从而满足项目需求。 灵活性:通过扩展芯片,设计者可以根据项目需求灵活增加或减少外设连接,而无需更换主控制器。 2、简化布线和连接 减少引脚需求:I2C总线仅需要两根线(SCL时钟线和SDA数据线)即可实现多个设备之间的通信,这大大减少了系统布线的复杂性和成本。 便于管理:通过I2C总线连接的设备可以使用统一的通信协议进行通信,简化了系统的维护和管理工作。 3、提高系统性能 高效通信:I2C协议具有高效的通信机制,能够支持高速数据传输,提高系统的整体性能。 时钟控制:I2C I/O扩展芯片可以控制外部设备的时钟,有助于优化系统的时序控制,提高系统的稳定性和可靠性。 4、降低成本和功耗 减少元件数量:使用I2C I/O扩展芯片可以减少系统中其他类型扩展元件的使用,从而降低整体成本。 低功耗:I2C总线支持低功耗模式,有助于降低系统的整体功耗,延长电池寿命(在便携式或无线物联网设备中尤为重要)。 5、广泛应用场景 传感器网络 :在物联网系统中,传感器是不可或缺的组成部分。I2C I/O扩展芯片可以方便地连接各种类型的传感器(如温度、湿度、加速度计等),实现数据的采集和传输。 工业自动化 :在工业自动化领域,PLC等控制系统需要与大量外设进行通信。I2C I/O扩展芯片能够满足这一需求,提高工业自动化系统的集成度和可靠性。 智能家居 :智能家居系统需要连接和控制各种智能家电和设备。I2C I/O扩展芯片可以扩展智能家居系统的控制能力,实现更多样化的功能。 工业自动化和控制 :在工业自动化系统中,经常需要连接和控制大量的传感器、执行器和其他设备。IIC IO扩展芯片可以提供更多的IO端口,以便与这些设备进行通信和控制。例如,它们可以用于读取传感器的数据、控制执行器的动作或与其他工业设备进行交互。 消费电子产品 :在消费电子产品中,如智能家居设备、智能音箱、智能手环等,IIC IO扩展芯片也发挥着重要作用。它们可以用于扩展设备的IO接口,以便连接更多的外部设备或传感器。例如,智能音箱可以通过IIC IO扩展芯片连接更多的麦克风或扬声器,提高音频处理的性能和质量。 嵌入式系统 :在嵌入式系统中,由于资源限制和成本考虑,微控制器的IO端口数量往往有限。IIC IO扩展芯片可以有效地解决这个问题,为嵌入式系统提供额外的IO端口。这些端口可以用于连接外部设备、扩展系统功能或实现与其他系统的通信。 测试与测量设备 :在测试和测量领域,IIC IO扩展芯片可以用于连接各种测试设备和传感器。通过扩展IO端口,测试设备可以获取更多的数据输入,提高测试的准确性和效率。同时,IIC IO扩展芯片还可以用于控制测试过程中的各种设备和参数。 医疗设备 :在医疗设备中,IIC IO扩展芯片可以用于连接各种医疗传感器和执行器。例如,在监护仪中,IIC IO扩展芯片可以连接多个生命体征传感器,实时监测患者的血压、心率等生理参数。在医疗机器人中,IIC IO扩展芯片可以控制机器人的运动和操作。 综上所述, IIC(I2C)I/O扩展芯片在物联网系统中扮演着重要角色,它们通过提供额外的I/O端口、简化布线和连接、提高系统性能、降低成本和功耗以及支持广泛应用场景等方式,为物联网系统的设计和实现带来了诸多便利和优势。 02 IIC I/O扩展芯片的行业知识介绍 IIC I/O扩展芯片定义 IIc接口IO扩展芯片是一种可以为电子设备添加输入输出功能的集成电路,它可以有效提高设备的性能。 IIC 原理 I²C通信协议 :I²C是一种串行通信协议,用于连接微控制器及其外围设备。它只需要两根线(SDA数据线和SCL时钟线)即可实现全双工通信,同时还可以连接多个设备到同一总线上。 设备寻址 :每个I²C设备都有一个唯一的地址,主控制器通过发送设备的地址来选中并与之通信。I²C扩展IO芯片也具备一个或多个可设置的地址,以便主控制器能够识别并与之通信。 数据传输 :在选中特定的I²C设备后,主控制器可以通过I²C总线发送数据到该设备,或者从该设备读取数据。对于I²C扩展IO芯片,主控制器可以发送命令来设置或读取IO端口的电平状态,从而实现对外围设备的控制或监测。 中断机制 :许多I²C扩展IO芯片还具备中断功能。当IO端口的电平状态发生变化时,芯片可以产生一个中断信号,通知主控制器进行相应的处理。这样,主控制器可以更加高效地响应外部事件,而无需持续轮询IO端口的状态。 内部寄存器 :I²C扩展IO芯片内部通常包含多个寄存器,用于存储IO端口的配置信息、数据等。主控制器可以通过I²C总线访问这些寄存器,以实现对IO端口的控制和管理。 IIC I/O扩展芯片的参数选型 电源电压 :确保你的系统电源电压与IO扩展芯片的电源电压兼容。常见的电源电压范围包括1.8V、3.3V、5V等。 IO口数量 :根据你的应用需求确定所需的IO口数量。有些IO扩展芯片提供8个、16个或更多的IO口。 IO口类型 :考虑你需要的IO口类型,如准双向口、开漏输出等。准双向口既可以作为输入也可以作为输出,而开漏输出则可以用于驱动LED等外部设备。 通信接口 :确保IO扩展芯片支持你的主控制器所使用的通信接口,如I²C、SPI等。I²C接口通常使用两根线(SDA和SCL)进行通信,具有简单易用、支持多设备连接等优点。 中断功能 :如果你的应用需要实时监测外部设备状态的变化,那么选择具有中断功能的IO扩展芯片将非常有用。当中断引脚被触发时,主控制器可以立即响应并处理相应的事件。 封装和尺寸 :根据你的应用需求和电路板空间限制选择合适的封装和尺寸。常见的封装类型包括TSSOP、QFN、SSOP等,尺寸范围也有所不同。 工作温度和功耗 :考虑你的应用所在的环境温度和功耗要求。选择具有适当工作温度和低功耗的IO扩展芯片将有助于提高系统的稳定性和可靠性。 其他特性 :根据你的应用需求,还可以考虑其他特性,如驱动能力(最大输出电流)、输入/输出电平范围、可编程性(是否支持通过编程来配置IO口)等。 IIC I/O扩展芯片的厂商 NXP Semiconductors(恩智浦半导体) :NXP是全球领先的半导体公司之一,提供广泛的IIC IO扩展芯片产品。其产品线包括PCF8574、PCA9555等,这些芯片具有高性能、低功耗和易用性等特点,广泛应用于各种领域。 Microchip Technology(微芯科技) :Microchip是一家专注于嵌入式控制和混合信号半导体解决方案的供应商。其IIC IO扩展芯片产品包括MCP23017、MCP23S17等,这些芯片具有高集成度、高可靠性和低功耗等特点,适用于工业自动化、消费电子和汽车电子等领域。 Texas Instruments(德州仪器) :德州仪器是一家全球性的半导体设计和制造公司,其IIC IO扩展芯片产品包括TPS2113、TPS2296等。这些芯片具有高性能、高精度和低功耗等特点,广泛应用于电源管理、电机控制和工业自动化等领域。 STMicroelectronics(意法半导体) :意法半导体是一家全球领先的半导体公司,提供广泛的IIC IO扩展芯片产品。其产品线包括VLSI Solution的82C55A等,这些芯片具有高速、高可靠性和低功耗等特点,适用于各种嵌入式系统和工业自动化应用。 此外,还有其他一些厂商也提供IIC IO扩展芯片产品,如Maxim Integrated、Renesas Electronics等。在选择IIC IO扩展芯片时,需要根据具体的应用需求和性能要求来选择合适的厂商和产品。国内也有一些知名的IIC(实际上是I²C,即Inter-Integrated Circuit)IO扩展芯片厂商,以下是一些例子: 中微爱芯 :作为中国领先的半导体公司之一,中微爱芯专注于消费电子芯片和小家电芯片的研发。他们的产品可能包括IIC IO扩展芯片,但具体型号和规格可能需要查询其官方渠道。 紫光展锐 :紫光展锐是中国集成电路设计和解决方案供应商,他们在移动通信、数字多媒体等领域积累了丰富的经验。虽然他们主要以手机芯片闻名,但他们的产品线可能也涵盖IIC IO扩展芯片。 华大半导体 :华大半导体是中国电子信息产业集团有限公司(CEC)旗下的核心企业,是中国“909”工程集成电路项目的重点承担单位。他们提供多种类型的半导体产品,包括可能包含IIC IO扩展芯片的产品。 03 IIC I/O扩展芯片的硬件设计方案 本文主要采用了信路达的XL9535做为驱动芯片。 1、XL9535概述 XL9535是一款24引脚CMOS器件,通过I²C总线/SMBus接口 串行时钟线(SCL)、串行数据(SDA)为大多数微控制器系列提供16位通用并行输入/输出(GPIO)扩展。这些设备设计用于2.3-V至5.5-V Vcc操作。这些改进包括更高的驱动能力、5V I/O容差、更低的电源电流、单独的I/O配置和更小的封装。 通电时,I/O被配置为输入。系统主机可以通过写入I/O配置位来启用I/O作为输入或输出。每个输入或输出的数据都保存在相应的输入或输出寄存器中。输入端口寄存器的极性可以用极性反转寄存器反转。所有寄存器均可由系统主控器读取。 当任何输入状态与其对应的输入端口寄存器状态不同时,这些设备开漏中断(/INT)输出被激活,并用于向系统主机指示输入状态已改变。在超时或其他不当操作的情况下,系统主设备可以利用上电重置功能重置这些设备。通电重置将寄存器设置为默认值,并初始化I²C/SMBus状态机。三个硬件引脚(A0、A1和A2)改变固定的I²C总线地址, 并允许多达八个设备共享同一I²C总线/SMBus。 2、 XL9535特性 I²C总线至16位GPIO扩展器 工作电源电压范围为2.3 V至5.5 V 低待机电流消耗 5 V容错I/O端口 400 kHz快速模式I²C总线时钟频率 SCL/SDA输入上的噪声滤波器 内部通电复位 通电时无故障 极性反转寄存器 开漏有源低中断输出 16个I/O引脚,默认为16个输入 3、XL9535引脚配置和功能 4、XL9535功能框图和参考设计 04 IIC I/O扩展芯片的软件设计方案 本文采用了奇迹物联的红豆版开源技术平台为主控单元,一步步手把手教会读者如何使用红豆版开源平台编写XL9535驱动。这里对代码就不多详解,如果需要详细了解,请到奇迹物联的红豆版开源平台了解详细代码讲解。 1 Gitee链接地址 Demo位于amaziot_bloom_os_sdk\sample\3rd\1.0_XL9535 Gitee源码地址:https://gitee.com/ning./hongdou Github源码地址:https://github.com/ayumid/hongdou 编译指令:.\build.bat -l .\amaziot_bloom_os_sdk\sample\3rd\1.0_XL9535 2 组件功能介绍 驱动XL9535芯片,实现输入IO检测。 3 代码讲解 1 drv_xl9535_i2c_init 功能:该函数用于,将发送数据长度写入xl9535寄存器。 参数:五 返回值:无 示例: C //初始化i2c总线 ret = drv_xl9535_i2c_init(); 2 drv_xl9535_i2c_read 功能:该函数用于,读取I2C从机。 参数:五 返回值:无 示例: C RegAddr = 0x00; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 00 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); 3 drv_xl9535_i2c_write 功能:该函数用于,发送数据到I2C从机。 参数:五 返回值:无 示例: C RegAddr = 0x06; RegWriteValue = 0xFF; ret = drv_xl9535_i2c_write(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("write i2c value=0x%x, ret=%d\n", RegWriteValue, ret); 4 Demo实战 4.1 概述 上电后,按下按键,串口会打印出按下了哪一个按键 4.2 测试 测试步骤: 参考编译教程,和文档开头的编译指令,进行编译 按照编译教程选择对应的选项 烧录 4.3 宏定义介绍 sample_xl9535_uart_printf 输出日志到DEBUG 串口,日志比较少,可以输出到这个串口,如果日志比较多,需要输出到usb口,以免不必要的问题出现 sample_xl9535_catstudio_printf 输出日志到USB 串口,使用catstudio查看,catstudio查看日志需要更新对应版本mdb.txt文件,软件打开filtter过滤日志,只查看用户输出的日志 SAMPLE_XL9535_STACK_SIZE 栈空间宏定义 4.4 全局变量介绍 sample_xl9535_int_detect_stack_ptr 任务栈空间,本例使用数组实现,用户在做项目时,可以预先估算下当先任务需要的大致栈空间,OS没有提供可以查看栈空间使用情况的API sample_xl9535_int_detect_task_ref 任务指针 4.5 函数介绍 Phase1Inits_enter 底层初始化,本例空 Phase1Inits_exit 底层初始化,本例空 Phase2Inits_enter 底层初始化,本例空 Phase2Inits_exit 创建主任务,初始化INT 引脚 代码片段: C int ret = 0; GPIOConfiguration config = {0}; //创建定时器 OSATimerCreate(&sample_xl9535_int_detect_timer_ref); //创建中断事件 OSAFlagCreate( &sample_xl9535_int_detect_flg_ref); Os_Create_HISR(&sample_xl9535_int_detect_hisr, "sample_xl9535_int_detect_hisr", sample_xl9535_detect_handler, 2); //创建中断处理任务 OSATaskCreate(&sample_xl9535_int_detect_task_ref, sample_xl9535_int_detect_stack_ptr, SAMPLE_XL9535_STACK_SIZE, 100, "detect_task", sample_xl9535_detect_task, NULL); //初始化int引脚,这里使用70脚 gpio126 config.pinDir = GPIO_IN_PIN; config.pinEd = GPIO_RISE_EDGE; config.pinPull = GPIO_PULLUP_ENABLE; config.isr = sample_xl9535_irq_handler; GpioInitConfiguration(SAMPLE_GPIO_ISR_PIN_NUM, config); sample_xl9535_detect_task 主任务,代码发分为两部分,一部分是发送不定长数据;另一部分是上电后等待其它模块发送的数据,收到后打印到串口。 代码片段: C void sample_xl9535_detect_task(void *param) { GPIO_ReturnCode ret = 0; UINT32 value = 0; OSA_STATUS status = OS_SUCCESS; UINT32 flag_value = 0; unsigned char RegAddr = 0; unsigned char RegWriteValue = 0; unsigned char RegReadValue0 = 0; unsigned char RegReadValue1 = 0; UINT8 down_en = 0; UINT8 up_en = 0; UINT8 sig_en = 0; UINT8 mul_en = 0; UINT8 read_en = 0; UINT8 de_en = 0; UINT8 ck_en = 0; UINT8 sim_en = 0; UINT8 gnss_en = 0; UINT8 nb_en = 0; UINT8 fourg_en = 0; //初始化i2c总线 ret = drv_xl9535_i2c_init(); sample_xl9535_catstudio_printf("ql_i2c_init ret %d", ret); //上电后,读xl9535 io扩展芯片的8个寄存器,测试用 RegAddr = 0x00; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 00 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x01; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 01 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x02; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 02 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x03; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 03 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x04; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 04 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x05; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 05 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x06; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 06 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x07; ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("read reg 07 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); //等1s OSATaskSleep(1 * 200); //初始化xl0535 io扩展芯片的06 07寄存器,设置所有的io都是输入 RegAddr = 0x06; RegWriteValue = 0xFF; ret = drv_xl9535_i2c_write(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("write i2c value=0x%x, ret=%d\n", RegWriteValue, ret); RegAddr = 0x07; RegWriteValue = 0xFF; ret = drv_xl9535_i2c_write(&RegAddr, &RegReadValue0); sample_xl9535_catstudio_printf("write i2c value=0x%x, ret=%d\n", RegWriteValue, ret); while(1) { // sample_xl9535_catstudio_printf("sample_xl9535_detect_task\r\n"); status = OSAFlagWait(sample_xl9535_int_detect_flg_ref, 0x01, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND); //红豆版,设置了边沿,但是还是会上升沿,下降沿都触发,所以会执行两次 if(flag_value & 0x01) { RegAddr = 0x00; //ret = ql_i2c_read(i2c_no, SAMPLE_I2C_SLAVE_ADDR, RegAddr, &RegReadValue0, 1); ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue0); // sample_xl9535_catstudio_printf("read reg 00 i2c value=0x%x, ret=%d\n", RegReadValue0, ret); RegAddr = 0x01; //ret = ql_i2c_read(i2c_no, SAMPLE_I2C_SLAVE_ADDR, RegAddr, &RegReadValue0, 1); ret = drv_xl9535_i2c_read(&RegAddr, &RegReadValue1); // sample_xl9535_catstudio_printf("read reg 01 i2c value=0x%x, ret=%d\n", RegReadValue1, ret); //寄存器值非默认值,表示有io输入,否则表示是上升沿中断 if(RegReadValue0 != 0xff || RegReadValue1 != 0x07) { event_ticks = OSAGetTicks(); int_status = 0; //判断是那个IO这里使用寄存器值判断,后续可以改为根据位判断 if(RegReadValue1 == DRV_XL9535_BUTTON_DOWN_EN) { // sample_xl9535_catstudio_printf("down int"); down_en = 1; } else if(RegReadValue1 == DRV_XL9535_BUTTON_UP_EN) { // sample_xl9535_catstudio_printf("up int"); up_en = 1; } else if(RegReadValue1 == DRV_XL9535_BUTTON_SIG_EN) { // sample_xl9535_catstudio_printf("sig int"); sig_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_MUL_EN) { // sample_xl9535_catstudio_printf("mul int"); mul_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_READ_EN) { // sample_xl9535_catstudio_printf("read int"); read_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_DE_EN) { // sample_xl9535_catstudio_printf("de int"); de_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_CK_EN) { // sample_xl9535_catstudio_printf("ck int"); ck_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_SIM_EN) { // sample_xl9535_catstudio_printf("sim int"); sim_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_GNSS_EN) { // sample_xl9535_catstudio_printf("gnss int"); gnss_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_NB_EN) { // sample_xl9535_catstudio_printf("nb int"); nb_en = 1; } else if(RegReadValue0 == DRV_XL9535_BUTTON_4G_EN) { // sample_xl9535_catstudio_printf("4g int"); fourg_en = 1; } } else { if(int_status == 0) { UINT32 keep_ticks = OSAGetTicks() - event_ticks; 20) { //检测到某个IO被按下后,可以在这里,或者发送信号,消息等去其它任务执行相应操作 // sample_xl9535_catstudio_printf("keep_ticks:%d, event_ticks:%d", keep_ticks, event_ticks); if(down_en == 1) { sample_xl9535_catstudio_printf("down en"); } else if(up_en == 1) { sample_xl9535_catstudio_printf("up en"); } else if(sig_en == 1) { sample_xl9535_catstudio_printf("sig en"); } else if(mul_en == 1) { sample_xl9535_catstudio_printf("mul en"); } else if(read_en == 1) { sample_xl9535_catstudio_printf("read en"); } else if(de_en == 1) { sample_xl9535_catstudio_printf("de en"); } else if(ck_en == 1) { sample_xl9535_catstudio_printf("ck en"); } else if(sim_en == 1) { sample_xl9535_catstudio_printf("sim en"); } else if(gnss_en == 1) { sample_xl9535_catstudio_printf("gnss en"); } else if(nb_en == 1) { sample_xl9535_catstudio_printf("nb en"); } else if(fourg_en == 1) { sample_xl9535_catstudio_printf("4g en"); } } down_en = 0; up_en = 0; sig_en = 0; mul_en = 0; read_en = 0; de_en = 0; ck_en = 0; sim_en = 0; gnss_en = 0; nb_en = 0; fourg_en = 0; } int_status = 1; } } } } 4.6 固件 上电后,按下按键,串口会打印出按下了哪一个按键 注:本文部分内容来源于网络,如有侵权,请及时联系我们。 本文章源自奇迹物联开源的物联网应用知识库Cellular IoT Wiki,更多技术干货欢迎关注收藏Wiki: Cellular IoT Wiki 知识库(https://rckrv97mzx.feishu.cn/wiki/wikcnBvAC9WOkEYG5CLqGwm6PHf)