细说STM32F407单片机IIC总线基础知识

news2025/1/2 21:00:40

目录

一、 I2C总线结构

1、I2C总线的特点

2、I2C总线通信协议

3、 STM32F407的I2C接口

二、 I2C的HAL驱动程序

1、 I2C接口的初始化

2、阻塞式数据传输

(1)函数HAL_I2C_IsDeviceReady()

(2)主设备发送和接收数据

(3)从设备发送和接收数据

(4)I2C存储器数据传输

3、中断方式数据传输

4、 DMA方式数据传输

5、其它


        I2C(Inter-Integrated Circuit)接口,有时也写作IIC或I²C接口,是一种串行数字总线接口。I2C接口只有2根信号线,总线上可以连接多个设备,硬件实现简单,可扩展性强。I2C接口主要用于通信速率要求不高,以及多个器件之通信的应用场景。

        本文使用的开发板:旺宝红龙STM32F407ZGT6 KIT V1.0。

一、 I2C总线结构

        一个器件的I2C接口只有2根信号线,即双向串行数据线SDA和时钟信号线SCL。I2C是种多设备总线,一根I2C总线上可以挂载多个设备。

 

1、I2C总线的特点

  • I2C总线只有两根信号线,SDA是双向串行数据线,SCL是时钟信号线,用于数据收发的同步。
  • I2C总线上可以挂载多个设备,一般有一个主设备、多个从设备。MCU一般作为主设备,外围器件作为从设备。在I2C通信协议中,主动发起通信的器件就是主设备,被动进行响应的器件就是从设备。
  • I2C总线上每个器件有一个7位或10位的地址,主设备发起通信时,会首先发送目标设备地址,只有地址对应的从设备才会做出响应。
  • I2C总线的两根信号线有上拉电阻。当I2C器件空闲时,其输出接口是高阻态。当所有设备都空闲时,I2C总线上是高电平
  • I2C通信有标准模式和快速模式,标准模式传输速率为100kbit/s,快速模式传输速率为400kbit/s。

2、I2C总线通信协议

        I2C通信总是由主机启动,每个通信过程由起始信号开始,由停止信号结束。一个数据包有8位,每个数据包后有一个应答位(ACK)或非应答位(NACK)。例如,主设备向从设备发送1字节数据的时序图:

 

  • 起始位:当SCL是高电平时,SDA的下跳沿就是起始位,是启动一次I2C通信的起始信号。
  • 停止位:当SCL为高电平时,SDA的上跳沿就是停止位,是停止一次I2C通信的结束信号。
  • 数据位:在SCL的一个时钟周期内传输一个数据位,当SCL为低电平时,发送设备更新SDA的电平,当SCL为高电平时,接收设备读取SDA的电平就是有效的一位数据
  • 数据包:I2C数据通信一个数据包总是8位,也就是1字节的数据。
  • 应答信号:在发送完8位数据包后,发送设备在第9个SCL时钟周期采集接收设备的应答信号。若在SCL的第9个周期采集的SDA为低电平,就是应答信号ACK,如果采集的SDA是高电平,就是非应答信号NACK。

        在一次I2C通信过程中,可以传输多字节的数据。主机启动I2C通信后,发送的第一个字节是目标设备地址,后面再发送或接收的数据由具体器件的指令定义决定。I2C通信协议只是定义了基本的数据传输时序,并且通信时序由MCU的硬件I2C接口实现。

3、 STM32F407的I2C接口

        STM32F407芯片上有3个硬件I2C接口,记作I2C1、I2C2和I2C3,均支持I2C标准模式和I2C快速模式,还与系统管理总线(System Management Bus,SMBus)2.0兼容。STM32F407上的I2C接口具有如下特性。

  • 同一个I2C接口既可以工作于主模式,又可以工作于从模式。
  • 工作于从模式时,可以设置两个从设备地址,从而对两个从地址应答。
  • 使用7位或10位设备地址,还可以进行广播呼叫。
  • 支持不同的通信速度:标准模式传输速率为100kbit/s,快速模式传输速率为400kbit/s。
  • 带DMA功能的1字节缓存。

二、 I2C的HAL驱动程序

        I2C的HAL驱动程序头文件是stm32f4xx_hal_i2c.h和stm32f4xx_hal_i2c_ex.h。I2C的HAL驱动程序包括宏定义、结构体定义、宏函数和功能函数。I2C的数据传输有阻塞式、中断方式和DMA方式 

1、 I2C接口的初始化

        对I2C接口进行初始化配置的函数是HAL_I2C_Init(),其函数原型定义如下:

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)

     其中,hi2c是I2C接口的对象指针,是I2C_HandleTypeDef结构体类型指针。在STM32CubeIDE自动生成的文件i2c.c中,会为启用的I2C接口定义外设对象变量,例如,为I2C1接口定义的变量如下:

I2C_HandleTypeDef hi2c1; //I2C1接口的外设对象变量

        结构体I2C_HandleTypeDef的成员变量主要是HAL程序内部用到的一些定义,只有成员变量Init是需要用户配置的I2C通信参数,是I2C_InitTypeDef结构体类型。

2、阻塞式数据传输

        阻塞式数据传输使用方便,且I2C接口的传输速率不高,一般传输数据量也不大,阻塞式传输是常用的数据传输方式。

函数名

功能描述

HAL_I2C_IsDeviceReady()

检查某个从设备是否准备好了I2C通信

HAL_I2C_Master_Transmit()

作为主设备向某个地址的从设备发送一定长度的数据

HAL_I2C_Master_Receive()

作为主设备从某个地址的从设备接收一定长度的数据

HAL_I2C_Slave_Transmit()

作为从设备发送一定长度的数据

HAL_I2C_Slave_Receive()

作为从设备接收一定长度的数据

HAL_I2C_Mem_Write()

向某个从设备的指定存储地址开始写入一定长度的数据

HAL_I2C_Mem_Read()

从某个从设备的指定存储地址开始读取一定长度的数据

(1)函数HAL_I2C_IsDeviceReady()

        函数HAL_I2C_IsDeviceReady()用于检查I2C网络上一个从设备是否做好了I2C通信准备,其函数原型定义如下:

HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout);

        其中,hi2c是I2C接口对象指针,DevAddress是从设备地址,Trials是尝试的次数,Timeout是超时等待时间(单位是嘀嗒信号节拍数),当SysTick定时器频率为默认的1000Hz时,Timeout的单位就是ms。

(2)主设备发送和接收数据

        一个I2C总线上有一个主设备,可能有多个从设备。主设备与从设备通信时,必须指定设备地址。I2C主设备发送和接收数据的两个函数的原型定义如下:

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint8_t *pData,uint16_t Size,uint32_t Timeout);

HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint8_t *pData,uint16_t Size,uint32_t Timeout);

        其中,pData是发送或接收数据的缓冲区,Size是缓冲区大小。DevAddress是从设备地址无论是发送还是接收,这个地址都要设置为I2C设备的写操作地址。Timeout为超时等待时间单位是嘀嗒信号节拍数。

        阻塞式操作函数在数据发送或接收完成后才返回,返回值为HAL_OK时表示传输成功,否则可能是出现错误或超时。

(3)从设备发送和接收数据

        I2C从设备发送和接收数据的两个函数的原型定义如下:

HAL_StatusTypeDef HAL_I2C_slave_Transmit(I2C_HandleTypeDef *hi2c,uint8_t *pData,uint16_t Size,uint32_t Timeout);

HAL_StatusTypeDef HAL_I2C_slave_Receive(I2C_HandleTypeDef *hi2c,uint8_t *pData,uint16_t size,uint32_t Timeout)

        I2C从设备是应答式地响应主设备的传输要求,发送和接收数据的对象总是主设备,所以函数中无须设置目标设备地址。

(4)I2C存储器数据传输

        对于I2C接口的存储器,例如EEPROM芯片24C02,有两个专门的函数用于存储器数据读写。向存储器写入数据的函数是HAL_I2C_Mem_Write(),其原型定义如下:

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t*pData,uint16_t Size,uint32_t Timeout);

        其中,DevAddress是I2C从设备地址,MemAddress是存储器内部写入数据的起始地址,MemAddSize是存储器内部地址大小,即8位地址或16位地址,有两个宏定义表示存储器内部地址大小。

#define I2C_MEMADD_SIZE_8BIT 0x00000001U  //8位存储器地址
#define I2C_MEMADD_SIZE_16BIT 0x000000100 //16位存储器地址

        参数pData是待写入数据的缓冲区指针,Size是待写入数据的字节数,Timeout是超时等待时间。使用这个函数可以很方便地向I2C接口存储器一次性写入多字节的数据。从存储器读取数据的函数是HAL_I2C_Mem_Read),其原型定义如下:

HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t *pData,uint16_t Size,uint32_t Timeout);

        使用I2C存储器数据传输函数的好处是,可以一次性传递地址和数据,函数会根据存储器的I2C通信协议依次传输地址和数据,而不需要用户自己分解通信过程。

3、中断方式数据传输

        一个I2C接口有两个中断号,一个用于事件中断,另一个用于错误中断。HAL_I2C_EV_IRQHandler()是事件中断ISR中调用的通用处理函数,HAL_I2C_ER_IRQHandler()是错误中断ISR中调用的通用处理函数。

        I2C接口的中断方式数据传输函数,以及各个传输函数关联的回调函数如表:

函数名

函数功能描述

关联的回调函数

HAL_I2C_Master_Transmit_IT()

主设备向某个地址的从设备发送
一定长度的数据

HAL_I2C_MasterTxCpltCallback()

HAL_I2C_Master_Receive_IT()

主设备从某个地址的从设备接收
一定长度的数据

HAL_I2C_MasterRxCpltCallback()

HAL_I2C_Master_Abort_IT()

主设备主动中止中断传输过程

HAL_I2C_AbortCpltCallback()

HAL_I2C_Slave_Transmit_IT()

作为从设备发送一定长度的数据

HAL_I2C_SlaveTxCpltCallback()

HAL_I2C_Slave_Receive_IT()

作为从设备接收一定长度的数据

HAL_I2C_SlaveRxCpltCallback()

HAL_I2C_Mem_Write_IT()

向某个从设备的指定存储地址开
始写入一定长度的数据

HAL_I2C_MemTxCpltCallback()

HAL_I2C_Mem_Read_IT()

从某个从设备的指定存储地址开
始读取一定长度的数据

HAL_I2C_MemRxCpltCallback()

所有中断方式传输函数

中断方式传输过程出现错误

HAL_I2C_ErrorCallback()

        中断方式数据传输函数的参数定义与对应的阻塞式传输函数类似,只是没有超时等待参数Timeout。例如,以中断方式读写I2C接口存储器的两个函数的原型定义如下:

HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t *pData,uint16_t Size);

HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,int16_t MemAddress,uint16_t MemAddSize,uint8_t *pData,uint16_t Size);

        中断方式数据传输是非阻塞式的,函数返回HAL_OK只是表示函数操作成功,并不表示数据传输完成,只有相关联的回调函数被调用时,才表示数据传输完成

4、 DMA方式数据传输

        一个I2C接口有I2C_TX和I2C_RX两个DMA请求,可以为DMA请求配置DMA流,从而进行DMA方式数据传输。I2C接口的DMA方式数据传输函数,以及DMA流发生传输完成事件(DMA_IT_TC)中断时的回调函数如表:

函数名

函数功能描述

关联的回调函数

HAL_I2C_Master_Transmit_DMA()

向某个地址的从设备发送一
定长度的数据

HAL_I2C_MasterTxCpltCallback()

HAL_I2C_Master_Receive_DMA()

从某个地址的从设备接收一
定长度的数据

HAL_I2C_MasterRxCpltCallback()

HAL_I2C_Slave_Transmit_DMA()

作为从设备发送一定长度的
数据

HAL_I2C_SlaveTxCpltCallback()

HAL_I2C_Slave_Receive_DMA()

作为从设备接收一定长度的
数据

HAL_I2C_SlaveRxCpltCallback()

HAL_I2C_Mem_Write_DMA()

向某个从设备的指定存储地
址开始写入一定长度的数据

HAL_I2C_MemTxCpltCallback()

HAL_I2C_Mem_Read_DMA()

从某个从设备的指定存储地
址开始读取一定长度的数据

HAL_I2C_MemRxCpltCallback()

        DMA传输函数的参数形式与中断方式传输函数的参数形式相同,例如,以DMA方式读写I2C接口存储器的两个函数的原型定义如下:

HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t *pData,uint16_t Size);

HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t *pData,uint16_t Size);

        DMA传输是非阻塞式传输,函数返回HAL_OK时只表示函数操作完成,并不表示数据传输完成。DMA传输过程由DMA流产生中断事件,DMA流的中断函数指针指向I2C驱动程序中定义的一些回调函数。I2C的HAL驱动程序中并没有为DMA传输半完成中断事件设计和关联回调函数。

5、其它

        一个I2C从设备有两个地址,一个是写操作地址,另一个是读操作地址。例如开发板上的EEPROM芯片24C02的写操作地址是0xA0,读操作地址是0xA1,也就是在写操作地址上加1。在I2C的HAL驱动程序中,传递从设备地址参数时,只需设置写操作地址,函数内部会根据读写操作类型,自动使用写操作地址或读操作地址。但是在软件模拟I2C接口通信时,必须明确使用相应的地址。

        IIC总线判断高低电平;SPI总线判断边沿。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268209.html

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

相关文章

Android笔试面试题AI答之Android基础(7)

Android入门请看《Android应用开发项目式教程》,视频、源码、答疑,手把手教 文章目录 1.Android开发如何提高App的兼容性?**1. 支持多版本 Android 系统****2. 适配不同屏幕尺寸和分辨率****3. 处理不同硬件配置****4. 适配不同语言和地区**…

《机器学习》线性回归模型实现

目录 一、一元线性回归模型 1、数据 2、代码 3、结果 二、多元线性回归模型 1、数据 2、代码 3、结果 一、一元线性回归模型 1、数据 2、代码 # 导入所需的库 import pandas as pd # 用于数据处理和分析 from matplotlib import pyplot as plt # 用于数据可视化 fr…

基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD Video 之全功能显示器连接端口方案

随着USB-C连接器和PD功能的出现,新一代USB-C PD PC显示器可以用作个人和专业PC工作环境的电源和数据集线器。 虽然USB-C PD显示器是唯一插入墙壁插座的交流电源输入设备,但它可以作为数据UFP(上游接口)连接到连接到TCD&#xff0…

QWidget应用封装为qt插件,供其他qt应用调用

在之前的文章中,有介绍通过QProcess的方式启动QWidget应用,然后将其窗口嵌入到其他的qt应用中,作为子窗口使用.这篇文章主要介绍qt插件的方式将QWidget应用的窗口封装为插件,然后作为其他Qt应用中的子窗口使用. 插件优点: 与主程序为同一个进程,免去了进程间繁琐的通信方式,…

关于 覆铜与导线之间间距较小需要增加间距 的解决方法

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

ArcGIS教程(009):ArcGIS制作校园3D展示图

文章目录 数据下载校园3D展示图制作创建要素类矢量化【楼】要素矢量化【绿地】矢量化【范围】矢量化处理打开ArcScene添加动画数据下载 https://download.csdn.net/download/WwLK123/90189025校园3D展示图制作 创建要素类 添加底图: 新建【文件地理数据库】,并修改名称为【…

权限注解+AOP切面+额外工具(UUID生成id,JWT,Servlet客户端,字符串String工具类,Redis序列化,ip工具类)

权限功能和注解的关系 ①、定义三个注解 //角色认证,必须具有指定角色标识才能进入该方法 Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD,ElementType.TYPE}) public interface RequiresRoles{//需要校验的角色标识String[] value() default {}…

RGB、HSV颜色模型及MATLAB互换应用实例

一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式,RGB和HSV都是描述颜色的数学模型,可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型,由红(Red)、绿(Green&#x…

MySQL基础-常见的增删改查操作语句总结

1.数据库操作 查看所有数据库 show databases;创建数据库 create database db_stu; --如果数据库已经存在就不创建 create database if not exists db_stu; --添加默认字符集 create database db_stu default charset utf8mb4;删除数据库 drop database db_stu; --如果存在…

【运维】部署MKDocs

部署MKDocs obsidian 记录笔记,通过 mkdocs 私有化部署。 1 使用MKDocs创建笔记 创建仓库,安装 Material for MkDocs 和 mkdocs-minify-plugin mkdir tmp cd tmp git initpip install mkdocs-material pip install mkdocs-minify-pluginmkdocs new .2 …

黑马Java面试教程_P2_MySQL

系列博客目录 文章目录 系列博客目录前言1. 优化1.1 MySQL中,如何定位慢查询?面试文稿 1.2 面试官接着问:那这个SQL语句执行很慢,如何分析 ( 如何优化)呢?面试文稿 1.3 了解过索引吗?(什么是索引)1.4 继续问 索引的底层数据结构…

【优选算法】盛最多水的容器(双指针算法)

11. 盛最多水的容器 - 力扣(LeetCode) 【1.题目】 【2.算法原理】 【3.代码编写】 优化之后就遍历了一遍数组,时间复杂度变为O(N),就使用了几个变量,空间复杂度为O(1)。 class Solution { public:int maxArea(vecto…

安装torch-geometric库

目录 1.查看 torch 和 CUDA 版本 2.依次下载和 torch 和 CUDA 对应版本的四个依赖库pyg-lib、torch-scatter、torch-sparse、torch-cluster以及torch-spline-conv 3.下载并安装torch-geometric库 1.查看 torch 和 CUDA 版本 查看CUDA版本 nvcc -V 查看pytorch版本 pip s…

王佩丰24节Excel学习笔记——第十八讲:Lookup和数组

【以 Excel2010 系列学习,用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 地址栏公式可以使用 F9 查看,取消请按Esc键,或者公式前的红色叉;使用数组时一定要注意使用绝对引用,方便下拉;使用数组时一…

【hackmyvm】hacked靶机wp

tags: HMVrootkitDiamorphine Type: wp 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. 获取参数 3. 提权 靶机链接 https://hackmyvm.eu/machines/machine.php?vmHacked 作者 sml 难度 ⭐️⭐️⭐️⭐️️ 2. 信息收集 2.1. 端口扫描…

【超级详细】七牛云配置阿里云域名详细过程记录

0. 准备一个阿里云域名,记得要备案!!!! 1. 创建七牛云存储空间 首先,登录七牛云控制台,创建一个新的存储空间(Bucket)。这个存储空间将用于存放你的文件,并…

【JDBC】转账案例

回顾 使用工具类查询表 需求: 查询student表的所有数据,把数据封装到一个集合中 数据准备 #创建表 CREATE TABLE student( sid INT, name VARCHAR(100), age INT, sex VARCHAR(100) ) #插入数据 INSERT INTO student VALUES(1,张三,18,女),(2…

HTML——14. 超链接四种状态

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>超链接</title></head><body><a href"https://ai.m.taobao.com" target"_blank">淘宝</a><br /><a href"…

微信V3支付报错 平台证书及平台证书序列号

1.平台证书及平台证书序列号设置错误报错&#xff1a; 错误1&#xff1a; Verify the response’s data with: timestamp1735184656, noncea5806b8cabc923299f8db1a174f3a4d0, signatureFZ5FgD/jtt4J99GKssKWKA/0buBSOAbWcu6H52l2UqqaJKvrsNxvodB569ZFz5G3fbassOQcSh5BFq6hvE…

MusicFree - 免费播放全网歌曲!无广告开源网络音乐聚合播放器 (安卓电脑版)

大家平常听歌可能都会在 QQ 音乐、网易云音乐、酷狗、喜马拉雅等不同平台来回切换&#xff0c;体验其实很烦。曾经推荐过不少“聚合”音乐应用&#xff0c;比如 洛雪音乐助手、Listen1 等等。 最近又有一个新选择了&#xff01;MusicFree 是一款免费开源清爽无广告的音乐播放器…