STM32 I2C硬件配置库函数

news2025/1/12 17:10:13
单片机学习!

目录

前言

一、I2C_DeInit函数

二、I2C_Init函数

三、I2C_StructInit函数

四、I2C_Cmd函数

五、I2C_GenerateSTART函数

六、I2C_GenerateSTOP函数

七、I2C_AcknowledgeConfig函数

八、I2C_SendData函数

九、I2C_ReceiveData函数

十、I2C_Send7bitAddress函数

十一、I2C状态监控功能

十二、标志位函数

12.1 I2C_GetFlagStatus函数

12.2 I2C_ClearFlag函数

12.3 I2C_GetITStatus函数

12.4 I2C_ClearITPendingBit函数


前言

        本文介绍了I2C硬件配置常用的一些库函数。


一、I2C_DeInit函数

        I2C_DeInit函数将外设 I2Cx 寄存器重设为缺省值

二、I2C_Init函数

        I2C_Init函数用于I2C的初始化。函数第二个参数是初始化的结构体。

I2C_Mode 用以设置 I2C 的模式。下表给出了该参数可取的值:

I2C_DutyCycle 用以设置 I2C 的占空比。下表给出了该参数可取的值:

注意:该参数只有在 I2C 工作在快速模式(时钟工作频率高于 100KHz)下才有意义。

I2C_OwnAddress1 该参数用来设置第一个设备自身地址,它可以是一个 7 位地址或者一个 10 位地址。

I2C_Ack 使能或者失能应答(ACK),下表给出了该参数可取的值:

I2C_AcknowledgedAddress 定义了应答 7 位地址还是 10 位地址。下表给出了该参数可取的值:

I2C_ClockSpeed 该参数用来设置时钟频率,这个值不能高于 400KHz

三、I2C_StructInit函数

下表给出了 I2C_InitStruct 各个成员的缺省值:

四、I2C_Cmd函数

        使能或失能I2C外设用I2C_Cmd函数来完成。

五、I2C_GenerateSTART函数

        调用I2C_GenerateSTART函数,就可以生成起始条件。

 程序源码:

/**
  * @brief  Generates I2Cx communication START condition.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: new state of the I2C START condition generation.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    /* Generate a START condition */
    I2Cx->CR1 |= CR1_START_Set;
  }
  else
  {
    /* Disable the START condition generation */
    I2Cx->CR1 &= CR1_START_Reset;
  }
}

如果 NewState 不等于 DISABLE,就把CR1寄存器的 START 位置1;否则,把 START 位清0.

        START 位意义可以从手册里的寄存器描述中来了解:

START 置1

  • 在从模式下是产生起始条件。
  • 在主模式下是产生重复起始条件。

就是 START 这一位置1,产生起始条件。

六、I2C_GenerateSTOP函数

        调用I2C_GenerateSTOP函数,生成终止条件。

程序源码:

/**
  * @brief  Generates I2Cx communication STOP condition.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: new state of the I2C STOP condition generation.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    /* Generate a STOP condition */
    I2Cx->CR1 |= CR1_STOP_Set;
  }
  else
  {
    /* Disable the STOP condition generation */
    I2Cx->CR1 &= CR1_STOP_Reset;
  }
}

        I2C_GenerateSTOP函数其实就是操作 CR1 的 STOP 位,查询手册中I2C寄存器的内容:

        STOP 是产生停止条件的。STOP位置1,产生停止条件。

七、I2C_AcknowledgeConfig函数

        I2C_AcknowledgeConfig函数是用来配置 CR1 的 ACK 这一位。就是配置,在收到一个字节后是否给从机应答。

程序源码:

/**
  * @brief  Enables or disables the specified I2C acknowledge feature.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: new state of the I2C Acknowledgement.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    /* Enable the acknowledgement */
    I2Cx->CR1 |= CR1_ACK_Set;
  }
  else
  {
    /* Disable the acknowledgement */
    I2Cx->CR1 &= CR1_ACK_Reset;
  }
}

手册ACK寄存器描述:

        ACK就是应答使能。STM32作为主机,在接收到一个字节后,是给从机应答还是非应答,就取决于ACK这一位。

在应答的时候:

  • 如果ACK是1,就给从机应答。
  • 如果ACK是0,就不给从机应答。

八、I2C_SendData函数

        I2C_SendData函数用于写数据到数据寄存器DR。

程序源码:

/**
  * @brief  Sends a data byte through the I2Cx peripheral.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval None
  */
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  /* Write in the DR register the data to be sent */
  I2Cx->DR = Data;
}

        分析源码,I2C_SendData函数实际就是把Data这个数据直接写入到DR寄存器。

手册DR寄存器描述:

        DR数据寄存器用于存放接收到的数据或放置用于发送到总线的数据。在发送器模式下,当写一个字节至DR寄存器时,自动启动数据传输。一旦传输开始,也就是TxE=1,发送寄存器空,如果能及时把下一个需传输的数据写入DR寄存器,I2C模块将保持连续的数据流。

        从上面可以看出两个信息:

  • 一个是,写入DR,自动启动数据传输。也就是产生发送一个字节的波形。
  • 另一个是,在上一个数据移位传输过程中,如果及时把下一个数据放在DR里等着,这样就能保持连续的数据流。

九、I2C_ReceiveData函数

        I2C_ReceiveData函数用于读取DR数据,作为返回值。

程序源码:

/**
  * @brief  Returns the most recent received data by the I2Cx peripheral.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @retval The value of the received data.
  */
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  /* Return the data in the DR register */
  return (uint8_t)I2Cx->DR;
}

 手册DR寄存器描述:

        

        在接收器模式下,接收到的字节被拷贝到DR寄存器,这时就是RxNE=1,接收寄存器非空。在接收到下一个字节(RxNE=1)之前读出数据寄存器,即可实现连续的数据传送。

        这里也可以看出两个信息:

  • 一个是,接收移位完成时,收到的一个字节由移位寄存器转到数据寄存器。读取数据寄存器就能接收一个字节了。
  • 另一个是,要在下一个字节收到之前,及时把上一个字节取走,防止数据覆盖。这样才能实现连续的数据流。

十、I2C_Send7bitAddress函数

        I2C_Send7bitAddress函数是发送7位地址的专用函数。

程序源码:

/**
  * @brief  Transmits the address byte to select the slave device.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  Address: specifies the slave address which will be transmitted
  * @param  I2C_Direction: specifies whether the I2C device will be a
  *   Transmitter or a Receiver. This parameter can be one of the following values
  *     @arg I2C_Direction_Transmitter: Transmitter mode
  *     @arg I2C_Direction_Receiver: Receiver mode
  * @retval None.
  */
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_I2C_DIRECTION(I2C_Direction));
  /* Test on the direction to set/reset the read/write bit */
  if (I2C_Direction != I2C_Direction_Transmitter)
  {
    /* Set the address bit0 for read */
    Address |= OAR1_ADD0_Set;
  }
  else
  {
    /* Reset the address bit0 for write */
    Address &= OAR1_ADD0_Reset;
  }
  /* Send the address */
  I2Cx->DR = Address;
}

        从源码可以看出,Address这个参数实际上也是通过DR发送的。只不过是Address参数在发送之前设置了Address最低位的读写位。

        代码意思是:如果I2C_Direction不是发送,就把Address的最低位置1,也就是读;否则就把Address的最低位清0,也就是写。

        在发送地址的时候,可以用一下这个函数。当然也可以手动设置最低位,调用I2C_SendData函数来发送地址。

十一、I2C状态监控功能

源码说明:

/**
 * @brief
 ****************************************************************************************
 *
 *                         I2C State Monitoring Functions
 *                       
 ****************************************************************************************   
 * This I2C driver provides three different ways for I2C state monitoring
 *  depending on the application requirements and constraints:
 *        
 *  
 * 1) Basic state monitoring:
 *    Using I2C_CheckEvent() function:
 *    It compares the status registers (SR1 and SR2) content to a given event
 *    (can be the combination of one or more flags).
 *    It returns SUCCESS if the current status includes the given flags 
 *    and returns ERROR if one or more flags are missing in the current status.
 *    - When to use:
 *      - This function is suitable for most applications as well as for startup 
 *      activity since the events are fully described in the product reference manual 
 *      (RM0008).
 *      - It is also suitable for users who need to define their own events.
 *    - Limitations:
 *      - If an error occurs (ie. error flags are set besides to the monitored flags),
 *        the I2C_CheckEvent() function may return SUCCESS despite the communication
 *        hold or corrupted real state. 
 *        In this case, it is advised to use error interrupts to monitor the error
 *        events and handle them in the interrupt IRQ handler.
 *        
 *        @note 
 *        For error management, it is advised to use the following functions:
 *          - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
 *          - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
 *            Where x is the peripheral instance (I2C1, I2C2 ...)
 *          - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler()
 *            in order to determine which error occurred.
 *          - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
 *            and/or I2C_GenerateStop() in order to clear the error flag and source,
 *            and return to correct communication status.
 *            
 *
 *  2) Advanced state monitoring:
 *     Using the function I2C_GetLastEvent() which returns the image of both status 
 *     registers in a single word (uint32_t) (Status Register 2 value is shifted left 
 *     by 16 bits and concatenated to Status Register 1).
 *     - When to use:
 *       - This function is suitable for the same applications above but it allows to
 *         overcome the limitations of I2C_GetFlagStatus() function (see below).
 *         The returned value could be compared to events already defined in the 
 *         library (stm32f10x_i2c.h) or to custom values defined by user.
 *       - This function is suitable when multiple flags are monitored at the same time.
 *       - At the opposite of I2C_CheckEvent() function, this function allows user to
 *         choose when an event is accepted (when all events flags are set and no 
 *         other flags are set or just when the needed flags are set like 
 *         I2C_CheckEvent() function).
 *     - Limitations:
 *       - User may need to define his own events.
 *       - Same remark concerning the error management is applicable for this 
 *         function if user decides to check only regular communication flags (and 
 *         ignores error flags).
 *     
 *
 *  3) Flag-based state monitoring:
 *     Using the function I2C_GetFlagStatus() which simply returns the status of 
 *     one single flag (ie. I2C_FLAG_RXNE ...). 
 *     - When to use:
 *        - This function could be used for specific applications or in debug phase.
 *        - It is suitable when only one flag checking is needed (most I2C events 
 *          are monitored through multiple flags).
 *     - Limitations: 
 *        - When calling this function, the Status register is accessed. Some flags are
 *          cleared when the status register is accessed. So checking the status
 *          of one Flag, may clear other ones.
 *        - Function may need to be called twice or more in order to monitor one 
 *          single event.
 *            
 */

以上描述的是I2C的状态监控函数。

STM32有的状态可能会同时置多个标志位,

  • 如果只检查某一个标志位就认为这个状态已经发生了,就不太严谨。
  • 如果用I2C_GetFlagStatus函数读多次,再进行判断,又可能比较麻烦。

所以这里库函数就给了多种监控标志位的方案:

第一种,基本状态监控,使用I2C_CheckEvent函数。这种方式就是同时判断一个或多个标志位,来确定几个EVx,从而判断某个状态是否发生。和下图的流程是对应的。

第二种,高级状态监控,使用I2C_GetLastEvent函数,是直接把SR1和SR2这两个状态寄存器拼接成16位的数据。

第三种,基于标志位的状态监控,使用I2C_GetFlagStatus函数判断某一个标志位是否置1了。

十二、标志位函数

12.1 I2C_GetFlagStatus函数

        I2C_GetFlagStatus函数用于读取标志位。

 下表给出了所有可以被函数 I2C_ GetFlagStatus 检查的标志位列表:

12.2 I2C_ClearFlag函数

        I2C_ClearFlag函数用于清除标志位。

下表给出了所有可以被函数 I2C_ ClearFlag 清除的标志位列表:

12.3 I2C_GetITStatus函数

        I2C_GetITStatus函数用于读取中断标志位。

下表给出了所有可以被函数 I2C_ GetITStatus 检查的中断标志位列表:

12.4 I2C_ClearITPendingBit函数

        I2C_ClearITPendingBit函数用于清除中断标志位。

下表给出了所有可以被函数 I2C_ ClearITPendingBit 清除的中断待处理位列表:

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

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

相关文章

sys.dm_exec_connections:查询与 SQL Server 实例建立的连接有关的信息以及每个连接的详细信息(客户端ip)

文章目录 引言I 基于dm_exec_connections查询客户端ip权限物理联接时间范围dm_exec_connections表see also: 监视SQL Server 内存使用量资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)引言 查询历史数据库客户端ip应用场景: 安全分析缺乏…

plane开源的自托管项目

Plane 是一个开源的自托管项目规划解决方案,专注于问题管理、里程碑跟踪以及产品路线图的设计。作为一款开源软件,Plane 的代码托管在 GitHub 平台上,允许任何人查看和贡献代码。它为用户提供了便捷的项目创建与管理手段,并配备了…

高光谱相机的特点

光谱特性 高光谱分辨率:能将光谱范围分割成极窄的波段,光谱分辨率通常达到纳米级甚至亚纳米级,可精确捕捉到不同物质在细微光谱差异上的特征,比如可以区分不同种类的植被因叶绿素含量等差异而在光谱上的细微变化。 多波段探测&a…

1.两数之和--力扣

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…

yolov5+colab跑起来

教程1.先上传网盘再run 教程2.直接上传解压run 本人过程

el-tree拖拽光标错位问题

背景:el-tree实现的分类树增加拖拽功能后,当分类树由于数量较多产生滚动条,如果分类树已滚动,进行拖拽时会造成光标错位的问题: 原因:el-tree拖拽光标定位的高度并未加上滚动的高度解决:将滚动的样式属性放…

Copula算法原理和R语言股市收益率相依性可视化分析

阅读全文:http://tecdat.cn/?p6193 copula是将多变量分布函数与其边缘分布函数耦合的函数,通常称为边缘。在本视频中,我们通过可视化的方式直观地介绍了Copula函数,并通过R软件应用于金融时间序列数据来理解它(点击文…

OpenCV计算机视觉 07 图像的模块匹配

在做目标检测、图像识别时,我们经常用到模板匹配,以确定模板在输入图像中的可能位置 API函数 cv2.matchTemplate(image, templ, method, resultNone, maskNone) 参数含义: image:待搜索图像 templ:模板图像 method&…

相加交互效应函数发布—适用于逻辑回归、cox回归、glmm模型、gee模型

在统计分析中交互作用是指某因素的作用随其他因素水平变化而变化,两因素共同作用不等于两因素单独作用之和(相加交互作用)或之积(相乘交互作用)。相互作用的评估是尺度相关的:乘法或加法。乘法尺度上的相互作用意味着两次暴露的综合效应大于(…

深入解析 Flink 与 Spark 的性能差异

💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长…

工厂人员定位管理系统方案(二)人员精确定位系统架构设计,适用于工厂智能管理

哈喽~这里是维小帮,提供多个场所的定位管理方案,如需获取工厂人员定位管理系统解决方案可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~撒花 在上一篇文章中,我们初步探讨了工厂人员定位管理系统的需求背景以及定位方…

Wi-Fi Direct (P2P)原理及功能介绍

目录 Wi-Fi Direct (P2P)介绍Wi-Fi Direct P2P 概述P2P-GO(P2P Group Owner)工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct &#xff…

Linux第二课:LinuxC高级 学习记录day01

0、大纲 0.1、Linux 软件安装,用户管理,进程管理,shell 命令,硬链接和软连接,解压和压缩,功能性语句,结构性语句,分文件,make工具,shell脚本 0.2、C高级 …

L4-Prompt-Delta

Paper List PromptPapers:https://github.com/thunlp/PromptPapersDeltaPapers: https://github.com/thunlp/DeltaPapers Programming Toolkit OpemPrompt: https://github.com/thunlp/OpenPromptOpenDelta: https://github.com/thunlp/OpenDelta 一、传统微调方法&#xff1…

关于husky8.0 与 4.0的配置

husky的场景使用很多,一般大多场景是在配置git commit 命令拦截hook, 校验 commit-msg 格式规范。以下环境默认:git > 2.27.0, node >14 1、安装huskey8.0.1 npm install --save-dev husky8.0.1 2、初始化配置文件 在package.json scripts 属性…

ML汇总

Introduction and Overview 机器学习算法模型压缩Feature scaling 特征缩放损失函数正则化优化方式激活函数机器学习算法 逻辑回归: 用于二分类问题。它基于一个或多个预测变量建模二元结果的概率。 线性回归: 用于预测基于一个或多个预测变量的连续结果。它通过拟合线性方程来…

Day04-后端Web基础(Maven基础)

目录 Maven课程内容1. Maven初识1.1 什么是Maven?1.2 Maven的作用1.2.1 依赖管理1.2.2 项目构建1.2.3 统一项目结构 2. Maven概述2.1 Maven介绍2.2 Maven模型2.3 Maven仓库2.4 Maven安装2.4.1 下载2.4.2 安装步骤 3. IDEA集成Maven3.1 配置Maven环境3.1.2 全局设置 3.2 Maven项…

spring boot解决swagger中的v2/api-docs泄露漏洞

在配置文件中添加以下配置 #解决/v2/api-docs泄露漏洞 springfox:documentation:swagger-ui:enabled: falseauto-startup: false 处理前: 处理后:

【Linux】深入理解文件系统(超详细)

目录 一.磁盘 1-1 磁盘、服务器、机柜、机房 📌补充: 📌通常网络中用高低电平,磁盘中用磁化方向来表示。以下是具体说明: 📌如果有一块磁盘要进行销毁该怎么办? 1-2 磁盘存储结构 ​编辑…

CSS如何让一个盒子或内容在指定区域中上下左右居中

要使用CSS让盒子或内容在其父元素中上下左右居中,可以使用多种方法。例如:flexbox布局、使用grid布局、box布局、使用position定位和transform结合、以及表格属性等等,相关属性来实现内容的上下左右的居中。 接下来我们使用以上的方法&#x…