STM32CubeMX系列 | I2C总线

发布时间:2023-03-21  

1. 简介

1.1 I2C总线介绍

I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速I2C总线一般可达400kbps以上。下面从物理层和协议层两方面来了解I2C

  • I2C物理层:可连接多个I2C通讯设备,支持多个通讯主机和从机;每个连接到总线的设备都有一个独立的地址,主机利用这个地址进行不同设备之间的访问;总线通过上拉电阻接到电源,当I2C设备空闲时会输出高阻态;多主机同时使用总线时,利用仲裁方式觉得由哪个设备占用总线;有三种传输模式,标准模式(100kbit/s)、快速模式(400kbit/s)、高速模式(3.4Mbit/s 多数I2C设备不支持);连接到相同总线的I2C数量受最大电容400pF限制

  • I2C协议层:I2C总线在传送数据的过程中共有三种类型信号,在这些信号中,起始信号是必需的,结束和应答信号可以不要;I2C总线寻址按照从机地址可分为7位和10位(寻址字节)寻址两种,D7~D1位组成从机的地址,D0位是数据传送方向(0表示主机向从机写数据/1表示主机由从机读数据)

a. 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据
b. 结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
c. 应答信号:接收数据的IC在接收到8位数据后,向发送数据的IC发出特定的低电平脉冲,表 示已经收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际 情况作出是否继续传递信号的判断。若为收到应答性,判断为受控单元故障

1.2 AT24C02芯片介绍

AT24C02是一个2K位串行CMOS,内部含有256个字节,此芯片具有I2C通讯接口,芯片内保存的数据在掉电的情况下不丢失(EEPROM),常用于存放比较重要的数据。本实验使用的是SOP-8封装的AT24C02芯片,其引脚说明见下图

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

下图为AT24C02的总线时序图和时间参数

2. 硬件设计

D1指示灯用来提示系统运行状态,K_UP按键用来控制24C02的数据写入,K_DOWN按键用来控制24C02的数据读取,数据的写入与读取信息通过串口1打印出来

  • D1指示灯

  • K_UP和K_DOWN按键

  • USART1

  • AT24C02

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • PA0设置为GPIO输入模式、下拉模式;PE3设置为GPIO输入模式、上拉模式

  • 激活I2C2,选择标准传输模式,选择7位寻址地址,其余默认设置

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM编程

  • 在i2c.c文件下可以看到I2C初始化函数

void MX_I2C2_Init(void){

  hi2c2.Instance = I2C2;

  hi2c2.Init.ClockSpeed = 100000;

  hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;

  hi2c2.Init.OwnAddress1 = 0;

  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

  hi2c2.Init.OwnAddress2 = 0;

  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

  if (HAL_I2C_Init(&hi2c2) != HAL_OK){

    Error_Handler();

  }

}


void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle){

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  if(i2cHandle->Instance==I2C2){

    __HAL_RCC_GPIOB_CLK_ENABLE();

    /**I2C2 GPIO Configuration    

    PB10     ------> I2C2_SCL

    PB11     ------> I2C2_SDA*/

    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C2 clock enable */

    __HAL_RCC_I2C2_CLK_ENABLE();    //网上看到很多资料说此处的I2C时钟初始化函数应该放在GPIO初始化之前,但是这里没有调整也能够正常读写EEPROM

  }

}

创建按键驱动文件key.c 和相关头文件key.h(驱动代码参考按键输入案例)

添加AT24C02驱动文件24cxx.c和24cxx.h

#define ADDR_24CXX_WRITE 0XA0

#define ADDR_24CXX_READ  0XA1

void AT24CXX_Init(void){

    MX_I2C2_Init(); 

    while(AT24CXX_Check()){

        printf("AT24C02 Checked Failed!rn");

        HAL_Delay(500);

    }

    printf("AT24C02 Checked Sucessed!rn");

}


uint8_t AT24CXX_Check(void){

    uint8_t temp;

    HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,255,I2C_MEMADD_SIZE_8BIT,&temp,1,0xff);                

    if(temp==0x36)  

        return 0;          

    else{

        uint8_t data = 0x36;

        HAL_I2C_Mem_Write(&hi2c2,ADDR_24CXX_WRITE,255,I2C_MEMADD_SIZE_8BIT,&data,1,0xff);

        HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,255,I2C_MEMADD_SIZE_8BIT,&temp,1,0xff);   

        if(temp==0x36)  

            return 0;

    }

    return 1;                                             

}

在main.c文件下编写IIC测试代码

AT24C02的2Kbit分为32页,每页8个字节。而EEPROM也可以按页写入,本例使用了按页写入的方式,分32次写入。注意每次写入完毕需要延时5ms,是AT24C02芯片的要求;读取数据没有页的限制,可以一次全部读取256个字节

/* USER CODE BEGIN PV */

#define ADDR_24CXX_WRITE 0XA0

#define ADDR_24CXX_READ  0XA1

uint8_t WriteBuf[256];

uint8_t ReadBuf[256];

uint16_t i,j;

/* USER CODE END PV */

void SystemClock_Config(void);

int main(void){

  uint8_t key;

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_I2C2_Init();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  AT24CXX_Init(void);

  printf("rn*********STM32CubeMX I2C AT24C02 Example*********rn");

  for(i = 0;i < 256; i++){   //初始化写数据缓冲区

    WriteBuf[i] = i;

  }

  /* USER CODE END 2 */

  while (1){

    key = KEY_Scan(0);

    if(key == KEY_UP_PRES){

        for(j = 0;j < 32;j++){  //按页写入EEPROM,分32次写入

            if(HAL_I2C_Mem_Write(&hi2c2,ADDR_24CXX_WRITE,8*j,I2C_MEMADD_SIZE_8BIT,WriteBuf+8*j,8,0xFF) == HAL_OK){

                printf("rnEEPROM 24C02 Write Test OK!rn");

                HAL_Delay(5);

            }

            else{

                printf("rnEEPROM 24C02 Write Test False!rn");

                HAL_Delay(5);                   

            }

        }

    }


    if(key == KEY_DOWN_PRES){   //EEPROM读取没有页限制,可以一次读取256个字节

        HAL_I2C_Mem_Read(&hi2c2,ADDR_24CXX_READ,0,I2C_MEMADD_SIZE_8BIT,ReadBuf,256,0xFF);

        for(i=0;i<256;i++){

            printf("0x%02X ",ReadBuf[i]);

        }


        if(memcmp(WriteBuf,ReadBuf,256) == 0){  //通过内存比较,判断读取和写入的数据是否相同

            printf("rnEEPROM 24C02 Read Test OK!rn");

        }

        else{

            printf("rnEEPROM 24C02 Read Test False!rn");

        }

    }


    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);

    HAL_Delay(500);

  }

}

. 下载验证

编译无误下载到开发板后,可以看到D1指示灯不断闪烁,当按下K_UP按键后数据写入到24C02芯片内,当按下K_DOWN按键后读取24C02芯片的值,同时串口打印出相应信息


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>