实验平台

硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器
软件:最新版本STM32CubeH7固件库STM32CubeMX v6.10.0,开发板环境MDK v5.35,串口工具putty
网盘资料包:链接: https://pan.baidu.com/s/1Y3nwaY4SMxfoUsdqPm2R3w?pwd=inba 提取码: inba

I2C

I2C介绍

  IIC 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,IIC是一种串行、半双工总线,主要用于近距离、低速的芯片之间的通信。有两根信号线,一根为SCL(时钟线),一根为SDA(数据线) 。 IIC是一种多主机总线,连接在IIC总线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被呼叫;当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误产生;每个连接到IIC总线上的器件都有唯一的地址(7bit),并且每个器件都可以作为主机和从机;IIC总线在通信时总线上发送数据的为发送器,接受数据的为接受器。
IIC特点:
①总线由数据线SDA和时钟线SCL构成的串行总线,数据线用来传输数据,时钟线用来同步数据收发。
②总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时序就可以实现微控制器与器件之间的通信。
③数据线SDA和时钟线SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电压,所以当总线空闲的时候,这两条线路都是高电平。
④总线上数据的传输速率在标准模式下可达100kbit/s 在快速模式下可达400kbit/s在高速模式下可达3.4Mbit/s。
⑤总线支持设备连接。在使用IIC通信总线时,可以有多个具备IIC通信能力的设备挂载在上面,同时支持多个主机和多个从机,连接到总线的接口数量只由总线电容400pF的限制决定。IIC总线挂载多个器件的示意图,如下图所示:
在这里插入图片描述

IIC时序

在这里插入图片描述
1.起始位
当主设备决定开始通讯时,需要发送开始信号,并且执行以下过程:

  • 将SDA线由高电平切换成低电平;
  • 将SCL线由高电平切换成低电平;

在主设备发送开始条件信号之后,所有从机即使处于睡眠模式也将变为活动状态,并等待接收地址位。
2.停止位
当主设备决定结束通讯时,需要发送结束信号,需要执行以下动作:

  • 先将SDA线从低电压电平切换到高电压电平;
  • 再将SCL线从高电平拉到低电平;

该信号由主设备发出,在停止信号发出后,总线就会处于空闲状态。
3.应答信号
  IIC最大的一个特点就是有完善的应答机制,从机接收到主机的数据时,会回复一个应答信号来通知主机表示“我收到了”。
  应答信号: 出现在1个字节传输完成之后,即第9个SCL时钟周期内,此时主机需要释放SDA总线,把总线控制权交给从机,由于上拉电阻的作用,此时总线为高电平,如果从机正确的收到了主机发来的数据,会把SDA拉低,表示应答响应。如果接收器是主机,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主机接收器发送一个停止信号。

在这里插入图片描述
4.数据位
  IIC数据总线传输要保证在SCL为高电平时,SDA数据稳定,所以SDA上数据变化只能在SCL为低电平时。
  一次传输的数据总共有8位,由发送方设置,它需要将数据位传输到接收方。发送之后会紧跟一个ACK / NACK位,如果接收器成功接收到数据,则从机发送ACK。否则,从机发送NACK。
  数据可以重复发送多个,直到接收到停止位为止。
5.停止位
当主设备决定结束通讯时,需要发送结束信号,需要执行以下动作:

  • 先将SDA线从低电压电平切换到高电压电平;
  • 再将SCL线从高电平拉到低电平;
    在这里插入图片描述

6.空闲状态
  IIC总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

7.读写操作流程
在这里插入图片描述
写操作
在这里插入图片描述

  1. Master发起START
  2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
  3. Slave发送ACK
  4. Master发送reg addr(8bit),等待ACK
  5. Slave发送ACK
  6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
  7. Slave发送ACK
  8. 第6步和第7步可以重复多次,即顺序写多个寄存器
  9. Master发起STOP

读操作
在这里插入图片描述

  1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
  2. Slave发送ACK
  3. Master发送reg addr(8bit),等待ACK
  4. Slave发送ACK
  5. Master发起START
  6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
  7. Slave发送ACK
  8. Slave发送data(8bit),即寄存器里的值
  9. Master发送ACK
  10. 第8步和第9步可以重复多次,即顺序读多个寄存器

EEPROM简介

  EEPROM (Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。
  由于EPROM操作的不便,后来出的主板上BIOSROM芯片大部分都采用EEPROM。EEPROM的擦除不需要借助于其它设备,它是以电子信号来修改其内容的,而且是以Byte为最小修改单位,不必将资料全部洗掉才能写入,彻底摆脱了EPROMEraser和编程器的束缚。
  EEPROM在写入数据时,仍要利用一定的编程电压,此时,只需用厂商提供的专用刷新程序就可以轻而易举地改写内容,所以,它属于双电压芯片。借助于EEPROM芯片的双电压特性,可以使BIOS具有良好的防毒功能,在升级时,把跳线开关打至“on”的位置,即给芯片加上相应的编程电压,就可以方便地升级;平时使用时,则把跳线开关打至“off”的位置,防止CIH类的病毒对BIOS芯片的非法修改。所以,至今仍有不少主板采用EEPROM作为BIOS芯片并作为自己主板的一大特色。
  传统的单片机存贮结构,一般要由ROM、RAM组成。随着存贮器技术的发展.市场上推出电可擦除可编程只读存贮器,即EEPROM器件。该类器件基于FLOTOX(floatin~gatetunneling~Oxide)结构.根据Fowler—Nordheim效应来完成数据的擦除或写入。因而具备联机可读、可写的特性,以及掉电之后的非易失性。EEPROM存贮器件的出现,为单片机存贮体的选择提供了新的设计方案。
原理图:
在这里插入图片描述

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置I2C部分如下图所示:
在这里插入图片描述

实验代码

1. 主函数

int main(void)
{
    MPU_Config();
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_USART6_UART_Init();
    uint8_t writeData[] = {0x11, 0x22, 0x33};
    uint8_t readData[3];
    uart6.printf("\033[1;32;40m");
    // 写入测试
    if(EEPROM_WritePage(0x0000, writeData, sizeof(writeData)) == HAL_OK) 
    {
        uart6.printf("Write Success!\r\n");
        uart6.printf("write data:0x%02x 0x%02x 0x%02x\r\n\r\n",writeData[0],writeData[1],writeData[2]);
        HAL_Delay(10); 
        // 读取验证
        if(EEPROM_ReadByte(0x0000, &readData[0]) == HAL_OK) 
        {
            uart6.printf("Read Success!\r\n");
            uart6.printf("Read Data readData[0]: 0x%02X\r\n", readData[0]); 
        }
    } 
    else 
    {
        uart6.printf("Write Failed!\r\n");
    }

  while (1)
  {

  }
}

2. EEPROM读写函数

// 写入单字节(需处理页边界)
HAL_StatusTypeDef EEPROM_WriteByte(uint16_t memAddr, uint8_t data) 
{
    HAL_StatusTypeDef status;
    status = HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDR_WRITE, memAddr, I2C_MEMADD_SIZE_16BIT, &data, 1, 1000);
    HAL_Delay(5);  // 必须延时等待EEPROM内部写入完成
    return status;
}

// 读取单字节
HAL_StatusTypeDef EEPROM_ReadByte(uint16_t memAddr, uint8_t *data) 
{
    return HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDR_READ, memAddr, I2C_MEMADD_SIZE_16BIT, data, 1, 1000);
}

// 写入多字节(自动分页)
HAL_StatusTypeDef EEPROM_WritePage(uint16_t memAddr, uint8_t *data, uint16_t size) 
{
    while (size > 0) 
	{
        uint16_t bytesToWrite = (memAddr % PAGE_SIZE == 0) ? PAGE_SIZE : PAGE_SIZE - (memAddr % PAGE_SIZE);
        bytesToWrite = (bytesToWrite > size) ? size : bytesToWrite;
        
        HAL_StatusTypeDef status = HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDR_WRITE, memAddr, I2C_MEMADD_SIZE_16BIT, data,bytesToWrite, 1000);
        if (status != HAL_OK) return status;
        HAL_Delay(5);
        memAddr += bytesToWrite;
        data += bytesToWrite;
        size -= bytesToWrite;
    }
    return HAL_OK;
}

实验现象

EEPROM读写测试成功,则在终端显示出相应的写入数据和读出数据。
在这里插入图片描述

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐