STM32:I²C通信原理概要

一、IIC通信原理

        IIC通信和串口通信有一定的相似之处,都有一根共地线和两根数据线。但是传递外部信息,串口有两根数据线可以进行双向通信,也就是全双工通信。而在IIC通信下,其中一条数据线是用于提供同步时钟脉冲的时钟线(SCL),只有一根数据线(SDA)能够用于传递外部信息。因此,虽然IIC可以进行双向通信,但是不能够同时进行,也就是半双工通信。

        IIC采用主从模式,支持多设备通信。即一台被当作主机,剩下的当作从机。由主机率先发起通信,从机才能根据主机的指令回复相应的信息。

        像这种支持多个设备进行通信的通信协议我们称之为总线协议。在IIC总线上,每个从机都有其唯一的设备地址。例如AHT20的设备地址是0x70,OLED设备地址是0x7A。当主机需要与AHT20进行通信时,在通信开始时主机就会发送AHT20设备地址。当从机收到主机发来是自己的设备地址后就会向主机发送响应数据(ACK)。如果不是自己的设备地址就把信息抛弃。

        在串口中,通信的双方首先约定通信的速度,即比特率。然后双方按照这一速度在合适的时机去设置/读取数据线上的高低电平,这种模式称之为异步模式。这种的优点就是通信便捷,但是缺点就是要保证双方各自的时钟系统是精确的。

        但是有很多小型传感器并没有精确的晶振提供时钟基准,因此IIC选择了同步通信方式。由主机通过SCL发送固定频率的时钟脉冲信号来作为IIC总线上的统一时钟源。

二、IIC通信步骤

       

        主机负责提供同步的脉冲信号与从机进行时间同步。具体就是当时钟线处于低电平时,数据发送方有权设置数据线的电平;当时钟线为高电平时,无数据线控制权的设备读取数据线电平。

        首先,IIC数据线与时钟线上往往有一个上拉电阻进行上拉。所以在未开始通信时,数据线和时钟线都处于高电平。在通信开始时,数据线的控制权在主机上,从机负责在时钟线在高电平时读取数据。在时钟线依旧是高电平时,将数据线提前下拉。所有从机就读取到一个低电平,意味着开始接收主机指令。而后时钟线提供一个恒定频率的时钟脉冲信号,主从机根据这个时钟信号开始通信操作。例如主机要发送0x71(0111001)数据。

        在时钟线低电平时,数据线为高电平,说明主机发送的数据是1,数据线为低电平时,数据发送的就是0;在时钟线高电平时,数据线为高电平,说明从机读取到的数据是1,数据线为低电平时,从机读取到的就是0..

        将0x71发送完后,从机AHT20收到主机与自身建立通信的信息,返回一个ACK信号,并获得数据线控制权。在物理上的表现就是,时钟线处于低电平时,从机将数据线电平拉低。而后,就与之前的方式相反了。主机负责在时钟线在高电平时读取数据,从机在时钟线低电平时写数据。如此反复直到AHT20返回所有数据。而后在时钟线为高电平时,主机将数据线拉高,表示IIC通信结束。 

也就是说当时钟线为高电平时,主机拉低数据线就代表通信开始,时钟线为高电平的期间, 拉高数据线, 就表示本次通讯结束。

### 使用ICM-20948传感器与STM32 #### 配置和初始化过程 为了在STM32平台上成功配置并使用ICM-20948传感器,需先了解该设备支持两种主要的通信协议——SPI或I²C。当选择I²C作为通信方式时,ICM-20948会一直扮演从属角色,并通过引脚1 (AD0) 来设定其7位地址中的最低有效位(LSB)[^1]。 对于硬件连接部分,在设计电路板布局时应确保正确无误地将ICM-20948的数据线(SDA)与时钟线(SCL)分别接到对应的STM32 GPIO引脚上;同时注意电源供电以及接地处理。此外还需考虑拉电阻的存在与否及其阻值大小对总线上信号质量的影响。 软件层面则涉及驱动程序编写: ```c #include "stm32f4xx_hal.h" #include <string.h> #define ICM20948_I2C_ADDRESS 0x68 // 默认地址, 若 AD0=HIGH 则为 0x69 // 初始化函数定义... void MX_I2C1_Init(void); uint8_t icm20948_read(uint8_t reg_addr,uint8_t *data,uint16_t length); uint8_t icm20948_write(uint8_t reg_addr,uint8_t data); int main(){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); uint8_t who_am_i; /* 检查器件ID */ if(icm20948_read(0x00,&who_am_i,1)){ printf("Error reading WHO_AM_I register\n"); while(1){}; } if(who_am_i != 0xEA){ printf("Device ID mismatch!\n"); while(1){}; } // 更多初始化代码... } /* 实现读写操作的具体细节... */ ``` 上述代码片段展示了基本框架结构,其中包含了必要的头文件引入、全局变量声明、`main()` 函数主体逻辑以及辅助性的读/写子功能实现概要。值得注意的是这里仅提供了一个简单的例子来验证目标模块的身份(`WHO_AM_I`),实际应用中还需要进一步完成其他参数设置工作如采样率、量程范围等调整。 #### 温度传感特性利用 除了惯性测量单元(IMU),即加速度计、陀螺仪外,ICM-20948还集成了一个温度感应通道。此特征允许开发者获取环境温差变化情况下的补偿数据,从而提高整体系统的精度表现。具体来说,可以通过访问特定寄存器获得原始ADC数值进而计算得出摄氏度单位表示的实际温度值][^[^24]: \[ TEMP\_degC = \left(\frac{TEMP\_OUT - RoomTemp\_Offset}{Temp\_Sensitivity}\right)+21^\circ C\] 此处 `RoomTemp_Offset` 和 `Temp_Sensitivity` 是两个预设常数项,通常可以在产品手册里找到确切数值。 #### 综合优势体现 得益于内置数字运动处理器(DMP)的支持,加上出厂前已完成校准流程的优势条件,使得基于ICM-20948构建的应用方案不仅简化了开发难度而且增强了用户体验感。制造商无需再单独挑选、测试多个离散元件就能达到预期效果,同时也降低了成本开销[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值