前言: I2C主要在服务应用在管理系统的配置或掌握组件的功能状态,如电源和系统风扇。可随时监控内存、硬盘、网络、系统温度等多个参数,增加了系统的安全性,方便了管理。
目录
1、实验要求:实现主机与EEPROM(24C02)双向通信。
I2C(Inter-Integrated Circuit)总线(也称IIC或I2C)是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备,是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,期间封装形式少,通信速率高等优点。

I2C 总线在物理连接上分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。
总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。




软件模拟I2C时序
由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,所以称之为“软件模拟协议”方式。
硬件控制产生I2C时序
STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理 I2C协议的方式减轻了 CPU 的工作,且使软件设计更加简单。

I2C的主要特点
● I2C总线规范 rev03 兼容性:
- 从机模式和主机模式
- 多主机功能- 标准模式(高达 100kHz )
- 快速模式(高达 400kHz )
- 超快速模式(高达 1 MHz )
- 7 位和 10 位地址模式
- 软件复位
● 1 字节缓冲带 DMA 功能
STM32F4-I2C通讯引脚:STM32芯片有多个I2C外设,它们的I2C通讯信号引出到不同的GPIO引脚上,使用时必须配置到这些指定的引脚。

EEPROM (Electrically Erasable Programmable read only memory),带电可擦可编程只读存储器--一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。
EEPROM常用来存储一些配置信息,以便系统重新上电的时候加载之。EEPOM 芯片最常用的通讯方式就是 I 2 C 协议
AT24XX芯片容量 XX表示:01、02、04、16、32、64、….. 单位: Kbit
AT24C02是一个2K位串行CMOS,内部含有256个字节,此芯片具有I2C通讯接口,芯片内保存的数据在掉电的情况下不丢失(EEPROM),常用于存放比较重要的数据。本实验使用的是SOP-8封装的AT24C02芯片,其引脚说明见下图



24CXX的设备地址:
24CXX的设备地址为7位:
高4位恒定为 1010
低3位取决于A0-A2的电平状态
注:一般主机在读写24CXX都是把设备地址连同读写位组合成一个字节一起发送

一个写操作需要8位数据字的地址,跟随着设备地址和响应位。一旦收到地址,EEPROM会再次响应0,然后输入第一个8位数据字。在接收到8位数据字后,EEPROM将输出一个“0”,寻址设备(如微控制器)必须以停止条件终止写序列。

随机读需要一个“空”字节写序列来加载数据字地址。一旦设备地址字和数据字地址被输入并被EEPROM确认,微控制器必须生成另一个启动条件。微控制器通过发送一个设备地址和读写标志位选择1,来启动当前地址的读取。EEPROM确认设备地址并串行输出数据字。 微控制器不响应“0”,但会产生停止条件

AT24C02芯片的器件地址为7位,高4位固定为1010,低3位有上表中的A0/A1/A2引脚的电平决定,还有一位(最低位R/W)用来选择读写方向。本实验中A0/A1/A2引脚接在GND上了,因此器件地址为1010000;加上最低位的读写方向位后,写器件地址为10100000(0xA0),读器件地址为10100001(0xA1)
SCL:串行时钟,SDA:串行数据I/O




IIC的时钟线和数据线对应PB8、PB9
开始168mhz时钟,串口通信,IIC外部管脚配置





主从地址必须在0到127之间,我们这边只有一个设备所以是0。生产工程打开keil。
实现一个写函数、一个读函数,在主程序中写入EEPROM并从EEPROMN读出来打印
我们使用到两个HAL库函数

代码中注意我们的EEPROM是8字节使用I2C_MEMADD_SIZE_8BIT
- int fputc(int ch,FILE *p)
- {
- while(!(USART1->SR & (1<<7)));
- USART1->DR = (uint8_t) ch;
- return ch;
- }
-
- #define WriteAddr 0xA0
- #define ReadAddr 0xA1
-
- uint8_t Wbuf[20] = "EEPROM TEST OK!";
- uint8_t Rbuf[20] = {0};
-
- /********* 24c02 写数据函数 *****************
- * @brief
- * @param MemAddr 起始位置
- * @param 数据存储区
- * @param 数据长度
- ********* 24c02 写数据函数 ******************/
- void EEPROM_Write(uint16_t MemAddr,uint8_t *Wbuf, uint16_t len)
- {
- while(len--)
- {
- while(HAL_I2C_Mem_Write(&hi2c1, WriteAddr, MemAddr, I2C_MEMADD_SIZE_8BIT, Wbuf,1,100) != HAL_OK){};
- MemAddr++;
- Wbuf++;
- }
- }
-
- /********* 24c02 读数据函数 *****************
- * @brief
- * @param MemAddr 起始位置
- * @param 数据存储区
- * @param 数据长度
- ********* 24c02 读数据函数 ******************/
- void EEPROM_Read(uint16_t MemAddr,uint8_t *Rbuf, uint16_t len)
- {
- while(HAL_I2C_Mem_Read(&hi2c1, ReadAddr, MemAddr, I2C_MEMADD_SIZE_8BIT, Rbuf,len,100) != HAL_OK){};
- }
-
-
- /* USER CODE END 0 */
-
- /**
- * @brief The application entry point.
- *
- * @retval None
- */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
-
- /* USER CODE END 1 */
-
- /* MCU Configuration----------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
-
- /* USER CODE BEGIN Init */
-
- /* USER CODE END Init */
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* USER CODE BEGIN SysInit */
-
- /* USER CODE END SysInit */
-
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_USART1_UART_Init();
- MX_I2C1_Init();
- /* USER CODE BEGIN 2 */
- printf("II2C test\r\n");
- EEPROM_Write(0,Wbuf,sizeof(Wbuf));
- HAL_Delay(500);
- EEPROM_Read(0,Rbuf,sizeof(Rbuf));
- printf("%s",Rbuf);
-
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
-
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
- }
- /* USER CODE END 3 */
-
- }
