当前位置: 首页 > article >正文

【STM32】IIC

超级常见的外设通信方式,一般叫做I方C。

大部分图片来源:正点原子HAL库课程

 专栏目录:记录自己的嵌入式学习之路-CSDN博客


目录

1    基本概念

1.1    总线结构

1.2    IIC协议

1.3    软件模拟IIC逻辑

2    AT24C02

2.1    设备地址与通信地址

2.2    读写操作模式

2.3    写时序

2.4    读时序

2.5    驱动步骤(例程中使用的是软件IIC)

2.6    SDA的GPIO使用开漏输出的原因

3    硬件IIC

3.1    概述

3.2    配置

3.3    注意事项

4    关于AT24C04、AT24C08、AT24C16


1    基本概念

IIC:Inter Integrated Circuit,集成电路总线,是一种同步、串行、半双工通信总线。

1.1    总线结构

  • 一般来说IIC总线接3个设备就差不多了。
  • IIC的时钟信号是由主机发出的。

1.2    IIC协议


  • 主机通过SDA传输数据时,数据在SCL为高电平时有效。
  • 在主机传输完毕一个字节的数据后,其需要释放SDA,使得从机可以通过拉低SDA来应答确认数据收到。

1.3    软件模拟IIC逻辑

由于初期ST官方说自己的IIC有问题,口碑没做上来,导致大家都使用软件IIC代替其内部的硬件IIC实现。但其实硬件IIC应该没啥大问题,详见:

关于STM32的I2C(IIC)问题的讨论 (stmicroelectronics.cn)




2    AT24C02

EEPROM是一种掉电后数据不丢失的储存器,常用来存储一些配置信息,在系统重新上电时就可以加载。AT24C02是一个2K bit的EEPROM存储器,使用IIC通信方式。

2.1    设备地址与通信地址

  • 通讯地址指定了操作的写和读;
  • 而设备地址不包括读写位;
  • 编程时需要发送出去的是通讯地址,不是设备地址;
  • 对于4K、8K、16K的存储芯片,由于IIC发送一个字节是8位,而4K是9位,因此需要在通讯地址处借1位进行数据发送,8K和16K也是以此类推。但是这样一来通讯地址的可用枚举就变少了,因为A0、A1、A2的位置被拿去做内存扩展了。最终的结果就是,IIC总线上可搭载的该类设备的数量会大打折扣,如16K的就只能搭载一个了。

2.2    读写操作模式

  • 写操作
    • AT24C02支持字节写模式和页写模式,其实也并不是什么字节写,实际上就是在IIC主机发送了数据地址信号后到发送停止信号前,最多可以写到页尾,仅此而已;
    • 其本质就是:收到每个数据字后,数据字地址的低三位(1K/2K)或四位(4K、8K、16K)在内部递增。较高的数据字地址位不递增,保留存储器页面行位置。当内部生成的字地址到达页面边界时,随后的字节被放置在同一页面的开头。如果超过八个(1K/2K)或十六个(4K、8K、16K)数据字传输到EEPROM,数据字地址将“翻转”,先前的数据将被覆盖。
    • 字节写模式就是一个地址一个数据进行写入;
    • 页写模式就是连续写入数据。只需要写一个地址,连续写入数据时地址会自增,但存在页的限制,超出一页时,超出数据覆盖原先写入的数据。但读会自动翻页。因此,若需要使用页写模式,就需要手动在写完一页后进行翻页。
  • 读操作
    • AT24C02支持当前地址读模式,随机地址读模式和顺序读模式;
    • 当前读模式是基于上一次读/写操作的最后位置继续读出数据;
    • 随机地址读模式是指定地址读出数据;
    • 顺序读模式是连续读出数据。

2.3    写时序

2.4    读时序

2.5    驱动步骤(例程中使用的是软件IIC)


2.6    SDA的GPIO使用开漏输出的原因


3    硬件IIC

(正点原子没讲硬件IIC,这个是参考野火的HAL库教程的)

STM32的I2C片上外设专门负责实现I2C通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理I2C协议的方式减轻了CPU的工作,且使软件设计更加简单。

3.1    概述

STM32F103具有2个I2C总线接口,能够工作于多主模式或从模式,支持标准(100kHz)和快速模式(400kHz)。I2C接口支持7位或10位寻址,7位从模式时支持双从地址寻址。内置了硬件CRC发生器/校验器。它们可以使用DMA操作并支持SMBus总线2.0版/PMBus总线。

  • 时钟
    • STM32F103的两个IIC接口外设都挂载在APB1时钟总线上;
    • 为了产生正确的时序,必须在I2C_CR2寄存器中设定该模块的输入时钟。输入时钟的频率必须至少是(但APB1一般都会满足吧):
      • 标准模式下为:2MHz;
      • 快速模式下为:4MHz;

3.2    配置

由于正点原子和野火都没讲硬件IIC的配置,因此此处的配置步骤是我通过网络上的CubeMX教程总结来的(没错,就连正点原子的CubeMX教程都是用模拟IIC的)。

  • CubeMX方式
    • 根据需要控制的IIC外部原件连接的GPIO其对应的IIC外设进行使能,例如正点原子F103板子上的AT24C02接在PB6、PB7上,因此是I2C1:
    • 配置IIC的设置,对于AT24C02,除了速率外基本不需要变:
    • 在高速模式下,有一个Fast Mode Duty,是用来调节高速模式下的占空比的,据野火教程说两个选项没太大差别,一般使用可以随便选;
  • HAL库函数手动编写方式
    • 初始化IIC:HAL_I2C_Init
    • 初始化时钟和GPIO:HAL_I2C_MspInit
  • 在需要的位置使用HAL_I2C_Mem_Read或者HAL_I2C_Mem_Write进行读写。这两个函数直接可以一次性指定目标从机地址、寄存器地址、要写入寄存器的数据等,超级方便:
      • hi2c:IIC句柄;
      • DevAddress:从机通讯读地址(注意是通讯地址,不是设备地址,分读写地址不同那个);
      • MemAddress:操作的从机寄存器地址;
      • MemAddSize:从机寄存器数据宽度;
      • pData:准备写入的数据的地址或指针;
      • Size:准备写入的数据的字节数;
      • Timeout:超时时间;
      • pData:返回的数据将要写入的缓存地址或指针(一般为变量地址或数组地址);
      • 其余与上一个类似;
  • 除了上述两个函数外,还有两个函数可以实现IIC通信:HAL_I2C_Master_Receive和HAL_I2C_Master_Transmit。这两个只能同时发送从机地址和数据,适合写入和读取那种从机内无需寄存器地址就能读到数据的从机,如传感器之类的。
    • 有博主提出使用HAL_I2C_Mem_Write等于先使用HAL_I2C_Master_Transmit传输第一个寄存器地址,再用HAL_I2C_Master_Transmit传输写入第一个寄存器的数据。我没有试验过,不知道对不对。

3.3    注意事项

  • 在使用HAL_I2C_Mem_Write的过程中,需要注意AT24C02一页只有8个字节的数据,所以一次Write的长度最多是8,要在循环写32次才能写完整片。循环过程记住要改变MemAddress(每次+8);
  • 在Write的循环中,请务必务必在每次Write后delay一段时间,具体的时间可根据EEPROM手册上说的时间设置,最好设置大一点;
  • 在读写过程中设置的超时时间也应设置大一点;
  • 不过在HAL_I2C_Mem_Read过程中就不需要分页,直接能读256个字节;

4    关于AT24C04、AT24C08、AT24C16

前面提到,这几个性高的通讯地址中有一定的位数是寄存器地址的借位:

由于其数据地址的借位,在发送通讯地址的时候,要结合数据地址对通讯地址进行处理。这篇文章讲得很好:

AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序-CSDN博客

这里截取一下其对写入的处理:

其中,第一个IIC_WriteByte,实际上是将设备地址DEV_ADDR和写地址WRITE_CMD(即0)或操作组成通讯的写地址;其次,对数据地址进行右移8位,并与0x07进行与运算,实际上就是取出数据地址中高8位的低3位,即通讯地址中的P2、P1、P0(若有的话对应位就是1,所以用或运算很安全)。然后还对取出的低三位进行了左移1位运算,再与通讯地址做与运算,这是因为通讯地址的最低位是读/写设置位。

第二个IIC_WriteByte就是将剩下的8位数据地址也发过去,发完就可以开始发数据了。


http://www.kler.cn/a/288939.html

相关文章:

  • 39.在 Vue3 中使用 OpenLayers 导出 GeoJSON 文件及详解 GEOJSON 格式
  • 基于SSM(Spring + Spring MVC + MyBatis)框架搭建一个病人跟踪信息管理系统
  • 【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)
  • 从AI换脸到篡改图像,合合信息如何提升视觉内容安全?
  • QT用Enigmavb 打包成单独exe
  • C/C++圣诞树
  • mongodb 在 Windows 环境下迁移数据库的问题
  • Linux:手搓shell
  • 解析淘宝商品详情API返回值中的特殊属性
  • python系列教程231——__init__.py
  • Docker php文件本地包含--pearcmd.php利用
  • Prometheus+Grafana监控数据可视化
  • 反序列化漏洞(一)
  • flume系列之:批量并行启动、停止、重启flume agent组
  • 设计模式之中介者模式
  • Pixelmator Pro for Mac 专业图像处理软件【媲美PS的修图软件】
  • 微信小程序 - 自定义头部导航栏开发
  • 【区块链 + 物联网】车载终端可信分账应用 | FISCO BCOS应用案例
  • 使用docker部署tensorrtllm推理大模型baichuan2-7b
  • 安装包丨WebGIS开发环境搭建及所需工具
  • 2024-MongoDB中国用户大会
  • Pandas 17-行操作和列操作
  • JavaWeb - Vue项目
  • 软考高级网络规划设计师含金量高吗?
  • 数据传输安全——混合加解密(国密)
  • 使用安信可Ai-WB2-12F开启wifi与手机通信TCP-IP(AT指令)