stm32fxx_hal_i2c.c解读之HAL_I2C_Mem_Write
HAL_I2C_Mem_Write()函数位于stm32fxx_hal_i2c.c文件的2432行,源代码对该函数的解释如下图
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 );

该函数是通过阻塞模式将一定数量的数据写入目标地址器件中目标寄存器地址中去。
该函数的参数一共有7个,将他们的特性列入下表格:
| 参数名 | 参数数据类型 | 参数解释 |
|---|---|---|
| hi2c | I2C_HandleTypeDef * | hi2c是一个结构体指针,它包含了特定I2C设备的配置信息 |
| DevAddress | uint16_t | 目标器件的地址,七位地址必须左对齐 |
| MemAddress | uint16_t | 目标器件的目标寄存器地址 |
| MemAddSize | uint16_t | 目标器件内部寄存器地址数据长度 |
| pData | uint8_t* | 一个8位的指针,指向待写的数据 |
| Size | uint16_t | 待传数据的数量 |
| Timeout | uint32_t | 等待时间 |
- 结构体I2C_HandleTypeDef的定义如下图所示

接下来我们看该函数是如何实现功能的:

首先定义了一个32位的变量tickstart,将目前时钟计数的值赋给它,HAL_GetTick()函数实现了取当前时钟计数的功能,我们看它的源代码

HAL_GetTick()函数位于stm32f1xx_hal.c文件中,可以看到HAL_GetTick()函数就完成了一个功能返回uwTick,而uwTick即为时钟计数值,当完成初始化HAL库后,uwTick每1ms增加1,溢出后归零。我们可以在代码的不同位置分别取当前的uwTick的值,将两个值相减即为中间代码运行时间。
再回到源代码:

assert_param()是一个参数校验函数,它的作用是检验输入参数是否符合要求。
接下来判断I2C是否准备好,如果i2c准备就绪,就进入下一环节,如果没有,则返回HAL_BUSY。
如果I2C准备就绪,则等待总线空闲,通过函数I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart)实现,我们来看看此函数的源码:

本函数位于stm32f1xx_hai_i2c.c文件的6876行,它实现了一个这样的功能:判断在一个时间间隔内,某标志位是否等于某值,如果是则返回HAL_OK;如否,则配置hi2c结构体参数并返回HAL_ERROR。

_HAL_LOCK(hi2c)实现了对资源的锁定,我们来看它的源代码

它位于stm32f1xx_hal_def.h文件内,它实现了这样一个功能:判断—_HANDLE_结构体中的成员Lock的值是否等于HAL_LOCKED,如果是,则返回HAL_BUSY,表示资源已被占用;如果否,则给Lock赋值HAL_LOCKED,表示本资源已被占用。
再回到源码:

标蓝的代码实现了这样一个功能:检测I2C是否被使能,如果没被使能,则使能。
下一段代码:

可以看到,注释对这段代码的解释是失能Pos,这个Pos是什么意思呢?让我们看STM32手册里面的解释
stm32fxx_hal_i2c.c解读之HAL_I2C_Mem_Write的更多相关文章
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- SDWebImage源码解读 之 NSData+ImageContentType
第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...
- SDWebImage源码解读 之 UIImage+GIF
第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...
- SDWebImage源码解读 之 SDWebImageCompat
第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
- SDWebImage源码解读之SDWebImageCache(下)
第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- AFNetworking 3.0 源码解读 总结(干货)(上)
养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...
随机推荐
- 多校联训 DP 专题
[UR #20]跳蚤电话 将加边变为加点,方案数为 \((n-1)!\) 除以一个数,\(dp\) 每种方案要除的数之和即可. 点击查看代码 #include<bits/stdc++.h> ...
- Tomcat深入浅出——Servlet(二)
一.Servlet简介 Servlet类最终开发步骤: 第一步:编写一个Servlet类,直接继承HttpServlet 第二步:重写doGet方法或者doPost方法,重写哪个我说的算! 第三步:将 ...
- Tapdata 等40余家行业知名企业,应邀参与共建 NextArch Foundation
日前,Linux 基金会执行董事 Jim Zemlin 于 Linux 基金会会员峰会(The Linux Foundation Member Summit)上宣布,Linux 基金会正式成立 N ...
- 创建多线程程序的第一种方式_创建Thread类的子类
创建多线程程序的第一种方式:创建Thread类的子类java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类 实现步骤: 1.创建一个Thread类的子类 ...
- android studio取消设置代理
看标题感觉就是一个简单的设置,其实只是个大坑啊 https://www.jianshu.com/p/bb6d2bcdd5b5 android studio内虽然设置了 no proxy,但是没起作用, ...
- 用KVM安装MacOS/OSX
基本步骤按照大牛的步骤https://github.com/kholia/OSX-KVM 黑果镜像建议用黑果小兵的:macOS Big Sur(我试过,大牛的更卡),里面的双EFI就很够用. 将镜像名 ...
- 01-vscode自定义配色方案 插件基础上
01-下载相关主题插件 02- 点击设置按钮 复制id 03-进入插件文件 C:\Users\Administrator\.vscode\extensions 04-复制刚才的id 05-themes ...
- 【一本通提高博弈论】[ZJOI2009]取石子游戏
[ZJOI2009]取石子游戏 题目描述 在研究过 Nim 游戏及各种变种之后,Orez 又发现了一种全新的取石子游戏,这个游戏是这样的: 有 n n n 堆石子,将这 n n n 堆石子摆成一排.游 ...
- treap(大根堆)模板
大根堆与小根堆性质相比简单很多,不用加特判 直接上代码: //treap(大根堆性质) #include<bits/stdc++.h> #define rint register int ...
- JS常用的3种弹出框
1.提示框 alert // 没有返回值 alert('你好'); 2.确认框 confirm // 返回 false/true let res = confirm('确定删除?'); if(res ...