学习I2C的概念并学习怎么用代码初始化配置。一、I2C基本概念两个mos管都断开——高阻态引脚悬空、断路电阻无穷大两个mos管都导通——在没有内阻的情况下GPIO控制器芯片会被烧毁同步半双工数据可以双向传输但不可以同时进行上图所示是IIC的总线的使用场景所有挂载在IIC总线上的设备都有两根信号线一根是数据线SDA 另一根是时钟线SCL。这两个信号线都是双向的。作为一种通信方式IIC总线在某一时刻总线只允许有一个设备处于发送状态所发生的数据被总线上所有的设备所接收。IIC通信协议包含有设备地址只有发送方携带的地址与某个接收方的地址相同时接收方才真正执行相关的指令。主从通信模式主机发起通信从机接收主机需要配合不同从机的地址、时钟速度、数据格式和特定命令集等机制进行通信。这里不难看出1、从设备之间是无法直接完成通信的2、总线上的从设备必须拥有一个独一无二的标识这个标识被称为设备地址。1.总线空闲状态空闲时SCL和SCL均由上拉电阻保持高电平。2.起始信号SCL为高时SDA数据线由高到低下降沿表示通信开始主机准备发送数据和地址。3.数据传输规则1数据发送期间SCL为低时SDA可以跳变SCL为高时SDA保持稳定不变2数据发送完成后由接收方发出应答信号ACK或者NACK1bit的低电平或者1bit的高电平3I2C 每次数据传输是以8bit为基本单位且每个字节后必须跟一个ACK/NACK。图中“无限制发送数据”意为“可连续发送多个字节每个字节后需要应答”。4主机第一次发送的数据永远是7位从机地址1位读写标志4.停止信号SCL为高时SDA由低到高上升沿。表示通信结束总线释放。注意:1.通信只能由主机发起2.时钟线永远由主机控制3.数据线传输数据时由发送方控制应答信号由接收方控制——主机写主机控制数据位从机控制应答——主机读从机控制数据位主机控制应答5.ACK 与 NACK 的信号特征ACK (Acknowledge)从设备在第9个时钟脉冲的高电平期间将 SDA 线稳定地拉为低电平逻辑0。特征当主设备在第9个 SCL 高电平时采样 SDA 线如果读到0则表示接收方从设备已成功接收到前8位数据并确认可以继续。NACK (Not Acknowledge)从设备在第9个时钟脉冲的高电平期间不拉低 SDA 线即释放它由上拉电阻将其维持在高电平逻辑1。特征当主设备在第9个 SCL 高电平时采样 SDA 线如果读到1则表示 NACK。这有几种可能从设备未成功接收数据。主设备发送的地址无对应从设备。从设备通知主设备数据传输结束。在读取操作中主设备发送 NACK 来通知从设备停止发送。二、I2C应用第一步依旧是先在开发板原理图找到I2C对应的寄存器引脚如图可以知道是UART4_RXD和UART4_TXD在手册中对应IOMUXC_UART4_RX_DATA_I2C1_SDA和IOMUXC_UART4_TX_DATA_I2C1_SCL根据前面的学习可以找到初始化的思路对这两个引脚先复用功能再配置电气特性。寄存器引脚也要配置。代码之后再写先根据手册了解重要的两个寄存器。1.I2CRIIC控制寄存器IEN位7IIC使能位置1使能IIC模块。也是整个I2C模块的软件复位控制位。0 禁用I2C模块。1使能I2C模块此位必须在其他任何I2C——I2CR位生效前辈设置。IIEN位6中断使能位置1使能IIC中断。MSTA位5主/从模式选择1为主模式主设备占用总线0为从模式。作为主机时启动通信前将此位置置1会产生一个起始位在发送过程中向此位清零会立即产生一个停止位。MTX位4传输方向1为发送主发/从发0为接收主收/从收。TXAK位3应答使能1为发送应答主收时0为不发送应答主发时默认0让从设备应答。RSTA位2重复起始位1生成重复起始条件用于“先写后读”等操作。// I2CR #define I2CR_IEN (1 7) //使能位 #define I2CR_MSTA (1 5) //主从模式选择位 #define I2CR_MTX (1 4) //收发模式 #define I2CR_TXAK (1 3) //回复的应答类型 ACK NACK #define I2CR_RSTA (1 2) //重发起始信号2.I2SRIIC状态寄存器IIF位1中断标志传输完成/仲裁丢失时置1需软件清零否则中断持续触发。IBB位5总线忙标志1表示总线被占用主设备启动后或总线有通信0表示总线空闲。RXAK位0接收应答标志0表示从设备发送ACK应答成功1表示NACK应答失败。表示在总线周期第九个时钟的应答位期间从SDA输入线采样到的值。IAL位4仲裁丢失标志主设备竞争总线失败时置1需软件清零。// I2SR #define I2SR_ICF (1 7) //数据传输位 0:正在 1:完成 #define I2SR_IBB (1 5) //空闲检测 0:空闲 1:忙碌 #define I2SR_IAL (1 4) //仲裁标识 0:正常 1:失去仲裁 #define I2SR_IIF (1 1) //中断 0:没产生 1:产生了 #define I2SR_RXAK (1 0) //接收应答类型 0:ACK 1:NACKI2C初始化首先编写初始化函数初始化包括两个方面一个是配置引脚复用功能和电器特性另外一个就是初始化I2C控制器。void i2c_init(I2C_Type *base) { if (I2C1 base) { IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0); IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0); IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0x98b0); IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x98b0); } else if (I2C2 base) { IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA, 0); IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL, 0); IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA, 0x98b0); IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL, 0x98b0); } base-I2CR ~(1 7); base-IFDR 0x16; base-I2CR | (1 7); }IIC主设备发送数据流程图i2c_stop://对应流程图Generate STOP发送停止信号表示结束