
stm32 i2c通信 [操作寄存器+库函数] I2C总线是由NXP(原PHILIPS)公司设计,有十分简洁的物理层定义,其特性如下:
![]() I2C的协议很简单: 数据的有效性 在传输数据的时候,SDA线必须在时钟的高电平周期保持稳定,SDA的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变 。 起始和停止条件 SCL 线是高电平时,SDA 线从高电平向低电平切换,这个情况表示起始条件; SCL 线是高电平时,SDA 线由低电平向高电平切换,这个情况表示停止条件。 字节格式 发送到SDA 线上的每个字节必须为8 位,每次传输可以发送的字节数量不受限制。每个字节后必须处理一个响应位。 应答响应 数据传输必须带响应,相关的响应时钟脉冲由主机产生。在响应的时钟脉冲期间发送器释放SDA 线(高)。 在响应的时钟脉冲期间,接收器必须将SDA 线拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平。 也就是说主器件发送完一字节数据后要接收一个应答位(低电平),从器件接收完一个字节后要发送一个低电平。 寻址方式(7位地址方式) 第一个字节的头7 位组成了从机地址,最低位(LSB)是第8 位,它决定了传输的 普通的和带重复开始条件的7位地址格式方向。第一个字节的最低位是 “0”,表示主机会写信息到被选中的从机; “1”表示主机会向从机读信息。 当发送了一个地址后,系统中的每个器件都在起始条件后将头7 位与它自己的地址比较,如果一样,器件会判定它被主机寻址,至于是从机接收器还是从机发送器,都由R/W 位决定。 仲裁 I2C是所主机总线,每个设备都可以成为主机,但任一时刻只能有一个主机。 stm32至少有一个I2C接口,提供多主机功能,可以实现所有I2C总线的时序、协议、仲裁和定时功能,支持标准和快速传输两种模式,同时与SMBus 2.0兼容。 本实验直接操作寄存器实现对I2C总线结构的EEPROM AT24c02的写入和读取。AT24c02相关操作详见 单片机读取EEPROM(AT24C02)。 库函数实现使用stm32的两个I2C模拟I2C设备间的数据收发,并通过串口查看数据交换情况。 直接操作寄存器 首先需要配置I2C接口的时钟,相关寄存器如下: I2C_CR2寄存器低五位: FREQ[5:0]:I2C模块时钟频率 ,必须设置正确的输入时钟频率以产生正确的时序,允许的范围在2~36MHz之间: 000000:禁用 000001:禁用 000010:2MHz ... 100100:36MHz 大于100100:禁用。 用于设置I2C设备的输入时钟,本例使用的是PLCK1总线上的时钟所以为36Mhz; 时钟控制寄存器(I2C_CCR)低12位: CCR[11:0]:快速/标准模式下的时钟控制分频系数(主模式),该分频系数用于设置主模式下的SCL时钟。 在I2C标准模式或SMBus模式下: Thigh = CCR ×TPCLK1 Tlow = CCR ×TPCLK1 时钟周期为 T = Thigh + Tlow; 例如:在标准模式下,FREQR = 36 即36Mhz,产生200kHz的SCL的频率 时钟控制分频系数 = Freqr /2/f f 为想得到的频率 配置好时钟,还需要配置本机地址,I2C支持7位地址和10位地址,这里用的是7位地址: 自身地址寄存器1(I2C_OAR1)[7:1]:接口地址,地址的7~1位。 其他相关操作参见代码,有详细注释:(system.h 和 stm32f10x_it.h 等相关代码参照 stm32 直接操作寄存器开发环境配置) User/main.c
|
挺详细的,谢谢分享
![]() ![]() ![]() ![]() |
谢谢分享 |
学习了 |
谢谢 |
楼主好好排下版。 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
用起i2c 我最头大 |
谢谢分享!![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |