【STM32】IIC

news2024/11/13 9:25:37

超级常见的外设通信方式,一般叫做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.coloradmin.cn/o/2080898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为手机数据丢失如何恢复?

在智能手机普及的今天,华为手机凭借其卓越的性能和用户体验赢得了众多用户的青睐。然而,在使用过程中,我们难免会遇到数据丢失或误删除的情况。面对这一困境,许多用户可能会感到束手无策。别担心,本文将为你提供一份全…

什么是响应式?

表达式: 用于表达式进行插值,渲染到页面之中 语法: {{ 表达式 }} 案例 <template><h1>{{ arr[2] }}</h1><h1>{{ 9 5 }}</h1><h1>{{ "神奇" }}</h1> </template><script setup> import { ref } from vue; …

react中配置Sentry

sentry 打开sentrySentry Docs | Application Performance Monitoring &amp; Error Tracking Software官网&#xff0c; 注册。根据提示创建应用后 在 React 应用中配置 Sentry 可以按照以下步骤进行&#xff1a; 安装 Sentry SDK: 在项目根目录下运行&#xff1a; npm in…

DDR5 Channel SI设计的挑战

DDR5延续了前几代数据速率不断提高的趋势。数据传输速度在3200至6400MT/s之间。同时将继续像前几代一样使用单端数据线的方式。为了帮助减少由高数据速率引起的信号完整性问题&#xff0c;DRAM端也会考虑加入判决反馈均衡&#xff08;DFE&#xff09;来减轻反射、ISI对信号传输…

十、Java异常

文章目录 一、异常简介二、异常体系图三、常见的异常3.1 常见的运行时异常3.2 常见的编译异常 四、异常处理4.1 异常处理的方式4.2 try-catch异常处理4.2.1 try-catch异常处理基本语法4.2.2 try-catch异常处理的注意细节 4.3 throws异常处理4.3.1 throws异常处理基本介绍4.3.2 …

Android - Windows平台下Android Studio使用系统的代理

这应该是第一篇Android的博文吧。以后应该会陆续更新的。记录学习Android的点点滴滴。 之前也看过&#xff0c;不过看完书就忘了&#xff0c;现在重拾Android&#xff0c;记录学习历程。 为何要用代理 因为更新gradle太慢了。 如何使用系统的代理 先找到系统代理的ip和端口。…

YOLO与PyQt5结合-增加论文工作量-实现一个目标检测的UI界面

这是个简单的界面&#xff0c;Qtdesigner支持各种界面&#xff0c;支持替换背景添加图标等。 接下来实现一个简单YOLO目标检测界面&#xff1a; 功能&#xff1a; 1、在窗口打开视频或图片进行目标检测&#xff0c;具有中断检测功能&#xff1a;比如检测视频的时候突然打开图…

速盾:cdn可以解决带宽问题么

一、速盾 CDN 的基本概念 CDN&#xff08;Content Delivery Network&#xff09;即内容分发网络&#xff0c;速盾 CDN 是这一技术的具体应用。它的工作原理是通过在全球多地部署服务器节点&#xff0c;将网站的内容缓存到这些节点上。 速盾 CDN 具有诸多优势。首先&#xff0…

分布式百万商户架构之缓存技术 本地化及未来之窗行业应用跨平台架构

如果数据读取速度比文件读取慢&#xff0c;将数据缓存到文件有以下优点&#xff1a; 一、提高读取效率 当需要反复访问某些数据时&#xff0c;从缓存文件中读取可以大大减少读取时间。因为文件系统通常会对文件进行一定程度的优化&#xff0c;使得文件的读取更加高效。而相比之…

优雅回收多个成员变量内存——使用函数模板实现内存安全释放

目录 从析构类中的多个成员说起什么是函数模板使用函数模板 从析构类中的多个成员说起 你有没有遇到过这种情况&#xff0c;一个类的构造函数中new了很多个成员变量&#xff0c;在析构函数中回收内存时&#xff0c;写了一遍又一遍 下面的代码&#xff1a; if (ptr ! nullptr)…

EXCEL文件如何批量加密,有什么方法

EXCEL文件的加密&#xff0c;通常在EXCEL软件上进行设置&#xff0c;它有打开密码与写保护密码&#xff0c;如果有多个文件的话&#xff0c;想通过一键设置的方法进行密码设置&#xff0c;那么它通常需要用到第三方软件进行批处理&#xff0c;因为EXCEL软件只能对当前打开的文件…

Wan-本科阶段部分作品

1、简易无接触温度测量与身份识别装置&#xff08;电赛 省一&#xff09; 2、基于交叉带式分拣结构的智能垃圾分类系统&#xff08;工训赛 省二&#xff09; 3、基于STM32的智能语音风扇&#xff08;大创优秀结题&#xff09;

鸿蒙界面开发(八):Grid网格布局Badge角标组件

Badge角标组件 在目标组件的外层包裹一层Badge角标组件 支持位置&#xff1a;右上&#xff0c;左&#xff0c;右 也可以使用绝对定位实现更灵活的角标位置。 Badge({count:1,//角标数值&#xff0c;角标数值为0时不展示position:BadgePosition.RightTop,//角标位置&#xff0…

【工作实践】MVEL 2.x语法指南

目录标题 MVEL 2.x语法指南一、基本语法1. 简单属性表达式2. 复合语句3. 返回值 二、值判断1. 判断空值2. 判断Null值3. 强制转换 三、内联Lists、Maps和数组Arrays1. Lists2. Maps3. 数组Arrays4. 数组强制转换 四、属性导航1. Bean属性2. Bean的安全属性导航3. 集合(1). List…

BOSS AI

BOSS AI 人工智能一点也不智能啊&#xff0c;机器人都不考虑用户的需求和体验吗&#xff1f; 这么多&#xff0c;我怎么看&#xff0c;我也不知道对面是人呢&#xff1f;还是机器人&#xff1f; 然后推送的东西也不知道我想要的&#xff0c;难道年龄到了&#xff0c;就活该天…

在 Windows 11上安装 .NET Framework 3.5

在 Windows 11上安装 .NET Framework 3.5 在控制面板中启用 .NET Framework 3.5 在安装某些软件时&#xff0c;会弹出以下界面&#xff0c;显示需要安装【 .NET Framework 3.5】。 安装微软官方建议进行安装&#xff1a; Microsoft-https://learn.microsoft.com/zh-cn/dotnet…

性能测试的方法有哪些?

性能测试是软件开发过程中非常重要的一环&#xff0c;它能够评估系统的性能以及稳定性。在进行性能测试之前&#xff0c;需要制定一系列的测试方法和策略&#xff0c;以确保测试的准确性和有效性。下面是一篇详细且规范的文章&#xff0c;介绍了性能测试的方法。 第一部分&…

Python中排序算法之冒泡排序

排序算法是将给定的数列中的数进行升序&#xff08;从小到大&#xff09;或者降序&#xff08;从大到小&#xff09;排列。冒泡排序是排序算法的一种。 1 冒泡排序的原理 1.1 基本思想 冒泡排序是将数据中较大或者较小的数据依次向右推移的一种排序技术。它的基本思想是比较…

js实现3d拖拽环绕旋转

js实现拖动节点围绕圆心转动 1.使用transform属性&#xff0c;将圆环放倒展示为椭圆 圆环上有不同的色彩&#xff0c;在转动的同时&#xff0c;需要让圆环也转动&#xff0c;所以圆环不能是椭圆&#xff0c;而是圆形&#xff0c;这样在转动的时候&#xff0c;改变rotate&…

Cypress第二次安装遇到的问题

问题一&#xff1a;吐血&#xff0c;谁会想到node.js的官网访问不了呢&#xff01; 中文网站&#xff1a;http://url.nodejs.cn/download/ 官网&#xff1a;https://nodejs.org/zh-cn nodejs安装的两种方法(官网、NVM安装-node版本切换)不知道这种方式是否可行&#xff0c;还…