资讯动态

HAL库源码解析——I2C的初始化

发布时间:2026/10/27 2:02:27 来源:尧图企业网站定制
MX_I2C2_Init()在STM32CubeMx将I2C做了配置之后在main()函数中我我们就能看到这个初始化函数。转到这个函数的定义hi2c2.Instance I2C2; 是干什么的hi2c2.Instance转到定义看得到是一个结构体指针是什么样的结构体再看下面可以看到是I2C寄存器的结构体I2C的寄存器在编址上是连续的所以只需要起始地址加上偏移量就能够访问但是这样子并不够优雅所以HAL库定义了一个寄存器结构体把寄存器的起始地址强转成结构体指针这样就能够在C语言层面上直接访问寄存器。I2C2经过我上面的解释老铁们应该就明白了I2C2起始就是I2C寄存器的起始地址。I2C句柄中的Init结构体如图框住的这一大片代码都与一个 Init 结构体有关那这个 Init 结构体又是何方神圣呢下面就解开它神秘的面纱。哦看到这里老铁们应该就恍然大悟了吧其实这个Init结构体就是用来临时存放STM32CubeMx中的配置信息的。 为什么说是临时存放因为等一下我们要把这些配置信息给到寄存器结构体中就是我前面所说的哪个结构体。号右边的蓝色字体是什么嗯有经验的老铁应该一眼就知道这种全是大写字母的就是宏就是配置信息。但是HAL库中这些宏往往会有多重嵌套看起来有点眼花但是只要老铁们一层一层算一算就会发现它就是配置信息。HAL_I2C_Init转到定义图片我就不全截图出来了这个函数实在是太长了我们没必要全部都看我挑一些重要的内容讲一讲。对复用GPIO引脚的初始化首先要认清楚一点 复用引脚的初始化是在I2C的初始化中完成的不是在GPIO的初始化中完成的。下面这个就是对复用GPIO进行初始化的函数但是我们直接在vs code中转到定义是看不到关于这个函数的定义的。原因后面中断再说我们要在目录下的这个文件中找找到如下定义这个红色波浪线不要在意其实并没有出错编译也是没有问题的只是vs code找头文件有些小bug 如果想要解决它可以包一下I2C的头文件即可。也就是#includestm32f1xx_hal_i2c.h以后遇到类似的问题都可以用这个方法解决。1 开启对应GPIO的时钟也就是这句代码这是一个宏主要作用是操作对应的寄存器开启时钟具体我就不说了老铁们可以自己去看看2 配置GPIO具体怎么配置的我前面在GPIO的源码解析中提到过此处不在解释3 开启I2C的时钟配置I2C的寄存器如图配置I2C的寄存器不知道大家有没有发现配置寄存器都是用一个叫做MODIFY_REG()的宏实现的。下面我就介绍一下这个MODIFY_REG()MODIFY_REG()先给一种场景 假设有一个 8 位的寄存器 REG。其中第 [5:4] 位从右往左数从 0 开始表示控制一个 LED 灯的模式00关闭01低速闪烁10高速闪烁11常亮假设当前 REG 寄存器状态1011 0100此时第 [5:4] 位 (即红色字体部分) 是 11即 “常亮” 状态。 需求在不改变其他位如第 0−3 位和第 6−7 位的情况下把模式改为 10高速闪烁2 .为了未来具有更好的通用性准备 2 种掩码 (Mask)掩码 1 清除掩码CLEARMASK0011 0000就是为了把第 [5:4] 位清空。掩码 2 设置掩码SETMASK0010 0000就是为了把第 [5:4] 位置位。完成需3.REG取 REG 的内容读取 REG 右值即1011 0100。~CLEARMASK清除掩码按位取反变成: 0011 0000 - 1100 1111REG (~CLEARMASK)清空 REG 中指定位(REG (~CLEARMASK)) | SETMASK设置新值REG ((REG (~CLEARMASK)) | SETMASK); 写回新值配置寄存器前后的细节其实配置寄存器之前我们还要先 disableI2C才能后续对它进行配置。 在配置完了之后才enabledisableenable

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑