STM32_HAL_I2C_串行接口

电气特性

I2C(Inter-Integrated Circuit)是一种由飞利浦公司(现恩智浦半导体)开发的串行通信协议,用于连接低速外围设备。I2C总线只需要两根线(SDA:串行数据线,SCL:串行时钟线)就可以实现多个设备之间的数据交换。以下是I2C的主要电气特性:

  1. 两线接口

    • SDA(Serial Data Line):用于传输数据。(数据线)
    • SCL(Serial Clock Line):用于同步数据传输。(时钟线)
  2. 多主从结构

    • I2C总线支持多个主设备和一个或多个从设备。在任何时刻,只有一个主设备控制总线。(不能同时存在多个主设备)
  3. 地址编码

    • 每个从设备都有唯一的7位或10位地址,主设备通过地址来选择要通信的从设备。
  4. 时钟同步

    • I2C总线上的所有设备都同步于SCL线上的时钟信号。时钟线由主设备控制
  5. 数据传输速率

    • 标准模式下,时钟频率可达100 kHz。
    • 快速模式下,时钟频率可达400 kHz。
    • 高速模式下,时钟频率可达3.4 MHz。
  6. 起始和停止条件

    • 数据传输开始于起始条件,结束于停止条件。起始条件是SCL为高电平时,SDA由高电平向低电平跳变;停止条件是SCL为高电平时,SDA由低电平向高电平跳变。
  7. 数据有效性

    • 数据在SCL为高电平时保持稳定,在SCL为低电平时改变。
  8. 位的表示

    • I2C使用8位数据传输,每次传输可以是一个字节(8位),也可以是多个字节。
  9. 确认(ACK/NACK)

    • 每个字节传输后,接收方会通过驱动SDA线至低电平来发送一个确认位(ACK),或者通过不驱动SDA线(保持高电平)来发送一个非确认位(NACK)。

协议

I²C写操作的详细步骤:

  1. 起始条件:主设备通过将SDA线从高电平拉到低电平,同时保持SCL为高电平,然后释放SCL,使其变为低电平,从而产生起始条件。总线在起始条件后处于忙碌状态。

  2. 发送从设备地址:主设备发送从设备的7位或10位地址,后面跟着一个写操作位(即最低位为0)。所有从设备都会接收这个地址,但只有地址匹配的从设备会响应。

  3. 从设备响应:地址匹配的从设备会发送一个确认(ACK)信号,即在第9个时钟周期时,从设备将SDA线拉低。

  4. 发送数据:主设备开始发送数据字节,每个字节后面都跟着一个时钟周期,用于从设备发送ACK信号。主设备可以发送多个字节,直到发送完所有需要的数据。

  5. 停止条件:当主设备发送完所有数据后,它会发出停止条件,即将SDA线从低电平拉到高电平,同时保持SCL为高电平,然后释放SDA线。

  6. 从设备处理数据:从设备在接收到停止条件后,会处理这些数据,例如存储到内部寄存器或EEPROM中。

以下是I²C写过程的时序图表示:

起始条件 -> [设备地址 + W] -> ACK -> [数据1] -> ACK -> [数据2] -> ACK -> ... -> [数据N] -> ACK -> 停止条件

-> 表示时间流动,[] 表示数据字节,R 表示读操作位,ACK 表示主设备发送的确认信号,NACK 表示主设备发送的否定确认信号。

I²C读操作的详细步骤:

  1. 起始条件:主设备通过将SDA线从高电平拉到低电平,同时保持SCL为高电平,然后释放SCL,使其变为低电平,从而产生起始条件。总线在起始条件后处于忙碌状态。

  2. 发送从设备地址:主设备发送从设备的7位或10位地址,后面跟着一个读操作位(即最低位为1)。所有从设备都会接收这个地址,但只有地址匹配的从设备会响应。

  3. 从设备响应:地址匹配的从设备会发送一个确认(ACK)信号,即在第9个时钟周期时,从设备将SDA线拉低。

  4. 读取数据:从设备开始发送数据字节,主设备在每个字节后面通过发送ACK信号来请求更多的数据,或者通过发送NACK信号来结束读取过程。

  5. 停止条件:当主设备完成数据读取后,它会发出停止条件,即将SDA线从低电平拉到高电平,同时保持SCL为高电平,然后释放SDA线。

  6. 主设备处理数据:主设备接收到数据后,可以根据需要进行处理或存储。

以下是I²C读过程的时序图表示:

起始条件 -> [设备地址 + R] -> ACK -> [数据1] -> ACK -> [数据2] -> ACK -> ... -> [数据N] -> NACK -> 停止条件

-> 表示时间流动,[] 表示数据字节,R 表示读操作位,ACK 表示主设备发送的确认信号,NACK 表示主设备发送的否定确认信号。

I 2 C的功能框图

STM32CudeMX 

  • Master  features  主模式特性

  • Slave  features  从模式特性

  1. Byte

    • 一个字节(Byte)通常包含8位(bit),这是计算机中最小的可寻址的存储单元。
    • 字节是大多数计算机体系结构中的基本数据单位,用于表示字符、数字和其他数据类型。
    • 在不同的上下文中,字节可以表示不同的含义,例如在数据通信中,它通常指的是传输的一个数据单元。
  2. Half Word

    • 半字(Half Word)通常包含16位(bit),即2个字节。
    • 在16位或更宽的处理器中,半字可能是处理器可以同时处理的数据单位之一。
    • 在一些编程语言和操作系统中,半字用于指定数据类型的大小,例如短整型(short)在某些体系结构上可能是16位的。
  3. Word

    • 一个字(Word)的大小取决于具体的处理器架构,但通常是16位、32位或64位。
    • 在32位处理器中,一个字通常是32位,即4个字节。
    • 在64位处理器中,一个字可能是64位,即8个字节。
    • 字是许多处理器的主要数据单位,用于表示整数、指针和内存地址。

有哪些函数

  1. 初始化和去初始化

    • HAL_I2C_Init():初始化I2C外设。
    • HAL_I2C_DeInit():去初始化I2C外设。
  2. 配置

    • HAL_I2C_Config():配置I2C的一些参数,如时钟速度、地址等。
  3. 数据传输

    • HAL_I2C_Master_Transmit():作为主设备发送数据到从设备。
    • HAL_I2C_Master_Receive():作为主设备从从设备接收数据。
    • HAL_I2C_Slave_Transmit():作为从设备发送数据到主设备。
    • HAL_I2C_Slave_Receive():作为从设备从主设备接收数据。
  4. 状态和错误处理

    • HAL_I2C_GetState():获取I2C外设的当前状态。
    • HAL_I2C_GetError():获取I2C的错误代码。
  5. 中断处理

    • HAL_I2C_IRQHandler():I2C中断处理函数。
    • HAL_I2C_MasterTxCpltCallback():主设备发送完成回调函数。
    • HAL_I2C_MasterRxCpltCallback():主设备接收完成回调函数。
    • HAL_I2C_SlaveTxCpltCallback():从设备发送完成回调函数。
    • HAL_I2C_SlaveRxCpltCallback():从设备接收完成回调函数。
  6. 其他功能

    • HAL_I2C_IsDeviceReady():检查指定地址的从设备是否就绪。
    • HAL_I2C_Mem_Write():向从设备的内存写入数据。
    • HAL_I2C_Mem_Read():从从设备的内存读取数据。

代码编写

检查指定地址的从设备是否就绪。

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_I2C1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */
char I2c_Data[9]={"AA"};/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if(HAL_I2C_IsDeviceReady(&hi2c1,0x78,2,500)==HAL_OK){HAL_UART_Transmit(&huart1,(uint8_t*)I2c_Data,9,1000);}else{char a[]={"null"};HAL_UART_Transmit(&huart1,(uint8_t*)a,5,1000);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

注意 

在I2C(Inter-Integrated Circuit)总线协议中,通常有一个主机(master)和多个从机(slave)。按照I2C协议的设计,所有的数据传输都是在主机控制下进行的。也就是说,在标准的I2C通信中,从机与从机之间不能直接进行通信,所有的数据传输都需要通过主机来控制。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费生物蛋白质的类chatgpt工具助手copilot:小分子、蛋白的折叠、对接等

参考: https://310.ai/copilot 可以通过自然语言对话形式实现小分子、蛋白质的相关处理:生成序列、折叠等 应该是agent技术调用不同工具实现 从UniProt数据库中搜索和加载蛋白质。使用ESM Fold方法折叠蛋白质。使用310.ai基础模型设计新蛋白质。使用TM-Align方法比较蛋白质…

【Spring Cloud】微服务链路跟踪Sleuth

目录 为什么要使用微服务链路跟踪微服务的现状多服务协同工作复杂的调用链条容易出错 微服务链路跟踪需要实现的需求实现监控决策避免技术债务快速定位故障 微服务链路跟踪的技术要求低消耗应用透明延展性可控采样率可视化 Spring Cloud Sleuth简介Spring Cloud Sleuth的4个特点…

Shell脚本快速入门

为什么要学shell?能做什么? 答:CI/CD 持续集成,自动化部署作业方式,需要将一系列linux命令程序化,shell 就能做到,提高运维人员的工作效率。 指定解析器: (1) shell解析器 #…

Linux网络-自定义协议、序列化和反序列化、网络计算服务器的实现和Windows端客户端

文章目录 前言一、自定义协议传结构体对象 序列化和反序列化什么是序列化?反序列化 二、计算器服务端(线程池版本)1.main.cc2.Socket.hpp3.protocol.hpp4.Calculator.hpp5.serverCal.hpp6.threadPool.hpp7.Task.hpp8. log.hpp 客户端Windows客…

小白级教程—安装Ubuntu 20.04 LTS服务器

下载 本教程将使用20.04版进行教学 由于官方速度可能有点慢,可以下方的使用清华镜像下载 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/ 点击20.24版本 选择 ubuntu-20.04.6-live-server-amd64.iso 新建虚拟机 下载好后 我们使用 VMware 打开它 这里选…

一篇文章讲透排序算法之归并排序

0.前言 本篇文章将详细解释归并排序的原理,以及递归和非递归的代码原理。 一.概念 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使…

苹果或面临退一赔三,新iPad悄悄砍了核心规格

618 快过去了一半,各家都卖的如火如荼,这其中当属苹果搞得最热火朝天。 某东手机竞速榜中,iPhone15 Pro Max 销量稳坐头把交椅,平板方面虽然没有统计表,但是相信销量也是不差。 加上今年刚刚发布的新系列的 iPad&…

求助!什么软件可以人声分离?手机上可以进行人声分离操作吗?

在数字时代,音频处理变得越来越重要,而人声分离技术则是其中的一项关键技术。很多人可能都有过这样的疑问:什么软件可以实现人声分离?手机上能否进行人声分离操作?今天,我们就来为大家解答这些问题&#xf…

提取伴奏与人声分离软件:5款手机必备音频软件

在数字音乐的浪潮中,音频处理软件已经成为手机用户不可或缺的工具。特别是在音乐制作、卡拉OK伴奏制作以及日常音频编辑中,人声与伴奏的分离显得尤为重要。本文将为您介绍五款免费且实用的手机音频软件,它们都具有人声与伴奏分离的功能&#…

spring boot 3.x版本 引入 swagger2启动时报错

一,问题 Spring Boot 3.x版本的项目里,准备引入Swagger2作为接口文档,但是项目启动报错: java.lang.TypeNotPresentException: Type javax.servlet.http.HttpServletRequest not present at java.base/sun.reflect.generics.…

安装windows x64的开源录屏软件GifCapture

下载压缩包 GIF软件 安装报错 下载.NET桌面版运行 .NET 即可在最近安装部分找到GifCapture打开使用

容器项目之前后端分离

容器化部署ruoyi项目 #需要的镜像nginx、java、mysql、redis、 #导入maven镜像、Java镜像和node镜像 docker load -i java-8u111-jdk.tar docker load -i maven-3.8.8-sapmachine-11.tar docker load -i node-18.20.3-alpine3.20.tar #拉取MySQL和nginx镜像 docker pull mysql…

【JavaScript】ECMAS6(ES6)新特性概览(二):解构赋值、扩展与收集、class类全面解析

🔥 个人主页:空白诗 🔥 热门专栏:【JavaScript】 文章目录 🌿 引言五、 Destructuring Assignment - 解构赋值,数据提取的艺术 🎨📌 数组解构📌 对象解构&

文件夹突变解析:类型变文件的数据恢复与预防

在数字化时代,文件夹作为我们存储和组织数据的基本单元,其重要性不言而喻。然而,有时我们可能会遇到一种令人困惑的情况——文件夹的类型突然变为文件,导致无法正常访问其中的内容。这种现象不仅会影响我们的工作效率,…

Solon2分布式事件总线的应用价值探讨

随着现代软件系统的复杂性日益增加,微服务架构逐渐成为开发大型应用的主流选择。在这种架构下,服务之间的通信和协同变得至关重要。Solon2作为一个高性能的Java微服务框架,其分布式事件总线(Distributed Event Bus)为微…

FastAPI给docs/配置自有域名的静态资源swagger-ui

如果只是要解决docs页面空白的问题,可先看我的这篇博客:FastAPI访问/docs接口文档显示空白、js/css无法加载_fastapi docs打不开-CSDN博客 以下内容适用于需要以自用域名访问swagger-ui的情况: 1. 准备好swagger-ui的链接,如&am…

读后感:《SQL数据分析实战》运营SQL实用手册

学习SQL,先有用起来,有了使用价值,之后才是去了解它的原理,让使用更加顺畅。 在大部分业务场景中,通过SQL可以快速的实现数据处理与统计。《SQL数据分析实战》区别于其他工具书,它并没有介绍SQL是什么&…

为何限定项目的 Node.js 版本

首先区分三个概念nvm,npm,nodejs。 Node.js: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境。它允许开发者使用 JavaScript 在服务器端编写应用程序,而不仅限于在浏览器中运行 JavaScript。Node.js 提供了一系列内置的模块和 API,使得开发…

Redis之常用实战场景

1.Redis数据丢失场景 1.1 持久化丢失 采用RDB或者不持久化,就会有数据丢失,因为是手动或者配置以快照的形式来进行备份。 解决: 启用AOF,以命令追加的形式进行备份,但是默认也会有1s丢失,这是在性能与数据安全性中寻…

2021 hnust 湖科大 数据结构课设报告+代码

2021 hnust 湖科大 数据结构 课设报告代码 描述 hnust大一下学期数据结构课设的报告和源代码(放在了附录里面) 目录 项目名称完成日期页码复杂度分析(Ⅰ)2021-06-211—2复杂度分析(Ⅱ)2021-06-213—4Josephus问题(Ⅰ)2021-06-215—6Josephus问题(Ⅱ…