你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeMx入门教程(7) I2C的读写应用

[复制链接]
STMCU小助手 发布时间:2021-1-6 10:19
STM32CubeMx入门教程(7) I2C的读写应用

导语“本次 教程使用CubeMx配置I2C进行I2C总线设备的数据读写操作,使用EEPROM作为实验对象”
01
------------第一节 系统要求----------

•硬件
野火指南者开发板

•软件

CubeMx & MDK & 串口调试助手

•原理图
2.1.png





我们可以从原理图中得到使用的I2C1,AT24C02的设备地址的第三位是000,容量是256个字节。设备地址从下图得到:
2.2.png




不带读写方向的使用左移得到的地址为0b10100000->0xA0, 读地址为:0xA1,写地址为0xA0;

注意:(1) 操作ATC02的时候,多字节写入的时候没写入一个字节,延时最小5ms, 多字节读的时候没有要求,页写入的时候每8个字节为一页,共32页。

02
------------第二节 CubeMx的配置----------


我们依然使用之前的USART的项目,在此基础上进行I2C的配置,串口的使用是进行EEPROM读写数据显示在控制台上,使用CubeMx进行I2C的配置:
2.3.png




I2C的配置很简单,完成上述配置后生成代码。


03
------------第三节MDK的代码编写----------
使用MDK打开CubeMx生成的代码进行应用代码编写。
(1)在main.c 中进行AT24C02的相关宏定义和变量定义:

  1. #define ADDR_AT24C_Write 0xA0
  2. #define ADDR_AT24C_Read  0xA1
  3. #define DEV_ADDR_ATC02   0xA0 //0x50 左移得到的。
  4. #define ATC02_BufferSize 256   // 256
  5. #define I2C_TIMEOUT                0xFF
  6. #define AT_I2C              hi2c1
  7. uint8_t AT24_WriteBuffer[ATC02_BufferSize],AT24_ReadBuffer[ATC02_BufferSize];
复制代码


(2) 应用函数申明:

  1. HAL_StatusTypeDef I2C_Write_Buffer(I2C_HandleTypeDef *hi2c,\
  2. uint16_t DevAddress, uint16_t MemAddress,\
  3. uint16_t MemAddSize, uint8_t *pData, uint16_t Size,\
  4. uint32_t Timeout);
  5. HAL_StatusTypeDef I2C_Read_Buffer(I2C_HandleTypeDef *hi2c,\
  6. uint16_t DevAddress, uint16_t MemAddress,\
  7. uint16_t MemAddSize, uint8_t *pData, uint16_t Size,\
  8. uint32_t Timeout);
复制代码


I2CWriteBuffer()是自定义的任意字节写入I2C-AT24C02的函数,I2CReadBuffer()是任意字节读写函数。这两个函数的实现采用HAL库的这两个函数:
1)HALStatusTypeDefHALI2CMemWrite(I2CHandleTypeDef *hi2c, uint16t DevAddress, uint16t MemAddress,uint16t MemAddSize, uint8t *pData, uint16t Size, uint32_t Timeout);

参数依次是:(I2C句柄,AT24C02的设备地址,设备中数据地址,数据地址的大小,写的数据,数据大小,超时时间)

2)HALStatusTypeDefHALI2CMemRead(I2CHandleTypeDef *hi2c, uint16t DevAddress, uint16t MemAddress,uint16t MemAddSize, uint8t *pData, uint16t Size, uint32_t Timeout);

参数依次是:(I2C句柄,AT24C02的设备地址,设备中数据地址,数据地址的大小,读出数据,数据大小,超时时间)

为什么不直接使用库函数呢?是因为在测试中AT24C02读写不正常,查看AT24C02的手册发现,单个字节写入没问题,多字节的写入需要每个字节延时5ms, 其实多字节的读没有问题,这个从新实现了下。可以连续8个字节的页写入,这个不需要延时。

(3)多字节的读写函数:

  1. /*这里自己实现多字节的ATC02的写操作*/
  2. HAL_StatusTypeDef I2C_Write_Buffer(I2C_HandleTypeDef *hi2c,\
  3. uint16_t DevAddress, uint16_t MemAddress,\
  4. uint16_t MemAddSize, uint8_t *pData, uint16_t Size,\
  5. uint32_t Timeout)
  6. {
  7.        uint16_t count=0;
  8.        for(count=0;count
  9.        {
  10.               if(HAL_I2C_Mem_Write(hi2c,DevAddress,MemAddress, MemAddSize,pData,1,Timeout)==HAL_OK)
  11.               {
  12.                      MemAddress ++;
  13.                      pData ++;
  14.                      HAL_Delay(5);
  15.               }
  16.               else
  17.               {
  18.                      printf("i2c write is error \t\n");
  19.                      return HAL_ERROR;
  20.               }
  21.        }
  22.        return HAL_OK;
  23. }
  24. /*这里自己实现多字节的ATC02的读操作*/
  25. HAL_StatusTypeDef I2C_Read_Buffer(I2C_HandleTypeDef *hi2c,\
  26. uint16_t DevAddress, uint16_t MemAddress,\
  27. uint16_t MemAddSize, uint8_t *pData, uint16_t Size,\
  28. uint32_t Timeout)
  29. {
  30.        uint16_t count=0;
  31.        for(count=0;count<Size;count ++)
  32.        {
  33.               if(HAL_I2C_Mem_Read(hi2c,DevAddress,MemAddress, MemAddSize,pData,1,Timeout)==HAL_OK)
  34.               {
  35.                      MemAddress ++;
  36.                      pData ++;
  37.                      //HAL_Delay(5);
  38.               }
  39.               else
  40.               {
  41.                      printf("i2c read is error \n");
  42.                      return HAL_ERROR;
  43.               }
  44.        }
  45.        return HAL_OK;
  46. }
复制代码

(4)在main函数中添加测试代码:

  1. uint16_t num_atc=0;
  2.        printf("this is test for I2C device read and write in ATC02\r\n");
  3.        printf("/**--------------------开始I2C-------------------------**/\r\n");
  4.        for( num_atc=0;num_atc
  5.        {
  6.               AT24_WriteBuffer[num_atc]=num_atc;
  7.               printf("0x%x\t",AT24_WriteBuffer[num_atc]);      
  8.        }
  9.        if(I2C_Write_Buffer(&AT_I2C,DEV_ADDR_ATC02, 0, I2C_MEMADD_SIZE_8BIT,AT24_WriteBuffer,ATC02_BufferSize, I2C_TIMEOUT) == HAL_OK)
  10.        {
  11.               printf("write i2c lots bytes is ok\t\n");
  12.        }
  13.        if(HAL_I2C_Mem_Read(&AT_I2C,DEV_ADDR_ATC02, 0, I2C_MEMADD_SIZE_8BIT,AT24_ReadBuffer,ATC02_BufferSize,I2C_TIMEOUT)== HAL_OK)
  14.        {
  15.               printf("\r\n EEPROM 24C02 read data Test OK \r\n");
  16.        }
  17.        else
  18.        {
  19.               printf("\r\n EEPROM 24C02 read data Test False \r\n");
  20.        }
  21. /*这里使用自定义多字节读函数也是正常的*/
  22. /*
  23.        if(I2C_Read_Buffer(&AT_I2C,DEV_ADDR_ATC02, 0,               I2C_MEMADD_SIZE_8BIT,AT24_ReadBuffer,ATC02_BufferSize,I2C_TIMEOUT)== HAL_OK)
  24.        {
  25.               printf("i2c read lots is ok\t\n");
  26.        }
  27. */
  28.        for(num_atc=0; num_atc<ATC02_BufferSize; num_atc++)
  29.        {
  30.               printf("0x%x\t",AT24_ReadBuffer[num_atc]);
  31.        }
  32.        if(memcmp(AT24_WriteBuffer,AT24_ReadBuffer,ATC02_BufferSize) == 0 ) /* check date */
  33.        {
  34.               printf("\r\n EEPROM 24C02 Read and write Test OK\r\n");
  35.        }
  36.        else
  37.        {
  38.     printf("\r\n EEPROM 24C02 Read and write Test False\r\n");
  39.        }      
  40.        printf("/**--------------------结束I2C-----------------**/\r\n");
复制代码


编译上述程序后下载。
04
------------第四节效果演示----------

使用串口观察写入的数据和读出的数据是否一致?
2.4.png


可以看到I2C操作EEPROM进行读写都是正常的。
文章出处: 小鸟的早晨


收藏 1 评论0 发布时间:2021-1-6 10:19

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版