带你了解STM32:I2C通信(第二部分)

目录

0.I2通信两部分学习

1.I2C外设简介(先学习一主多从、7位地址的I2C,才能深入的看手册学习)

2.I2C框图

3.I2C基本结构

4.主机发送

5.主机接收

6.软件/硬件波形对比

7.硬件I2C读写MPU6050代码

第一步:按图接线到面包板

第二步:复制软件I2C读写MPU6050代码

第三步:将MyI2C模块移除工程

第四步:在MPU6050.c中配置I2C外设

I2C相关库函数

第五步:在MPU6050.c中封装一个事件等待函数

第六步:在MPU6050.c中配置指定地址写一个字节的时序

第七步:在MPU6050.c中配置指定地址读一个字节的时序

第八步:头文件声明

硬件I2C读写MPU6050完整代码

[8. I2C相关库函数](#8. I2C相关库函数)


0.I2通信两部分学习

第一部分:介绍协议规则,然后用软件模拟的形式来实现协议

第二部分:介绍STM32的I2C外设,然后用硬件来实现协议


1.I2C外设简介(先学习一主多从、7位地址的I2C,才能深入的看手册学习)

STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担
支持多主机模型

有两种:1.固定多主机。有两个及以上的主机,连接I2C总线控制从机,当主机之间有信号冲突时,会总线仲裁让那个主机先使用;2.可变多主机(STM32的I2C就这种)。I2C总线上没有固定的主机,任何设备都可以在总线空闲状态下充当主机,没有充当主机的就是从机,当这个主机完成了信号的通信,就会变回从机,如果从机之间有信号冲突同时要当主机,总线仲裁会判断谁来当主机
支持7位/10位地址模式

7位地址:起始位后的第一个字节是7位地址+读写位,第一个字节为寻址位。只有128种情况,设备非常多,不够用

10位地址:起始位的第一个字节前五位11110,第一个字节剩下的三位:前面两个和第二个字节的8位组成10位地址,最后一位读写位,也就是把前面两字节当成寻址位。有1024种情况
支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)
支持DMA

多字节通讯可以增加通信效率
兼容SMBus协议

SMBus系统管理总线,基于I2C总线改进产生
STM32F103C8T6 硬件I2C资源:I2C1、I2C2


2.I2C框图

外设通信引脚:SDA、SCL

SMBALERT:SMBus使用
数据控制部分

核心部分:DATA REGISTER和数据移位寄存器

需要发送数据时,可以把一个字节数据写到数据寄存器DR,当移位寄存器没有移位时,这个数据寄存器的值就会进一步转到数据寄存器里面,在移位的过程中,就可以把下一个数据放在数据寄存器里等待移位,一旦前面的一个数据完成移位,这个数据就可以无缝衔接进行移位,当数据由数据寄存器转到移位寄存器时,就会置转态寄存器的TXE位为1,表示发生寄存器为空。

接收和发送的过程相反,然后,置标志位RXNE,表示接收寄存器非空

比较器和地址寄存器(自身地址寄存器、双地址寄存器):从机模式使用,可变多主机模式,自身地址寄存器可以自定义的写入地址,如果STM32作为从机,在被寻址时,收到的寻址通过比较器判断,和自身地址相同,那STM32作为从机,响应外部主机的召唤,并且STM32支持同时响应两个从机地址,所以又有双地址寄存器

PEC计算和寄存器:数据校验模块,当发送一个多字节数据帧时,在PEC计算里硬件可以自动执行CRC校验计算(根据前面的数据,进行各种数据运算,得到一个字节的校验位,附加在数据帧的后面),接收到这个数据帧后,STM32硬件自动执行校验判断,如果数据在传输过程中出错了,CRC校验算法就通不过,硬件就会置校验错误标志位
时钟控制部分


3.I2C基本结构

因为是高位先行,所以向左移


4.主机发送


5.主机接收


6.软件/硬件波形对比


7.硬件I2C读写MPU6050代码

第一步:按图接线到面包板

第二步:复制软件I2C读写MPU6050代码

第三步:将MyI2C模块移除工程

第四步:在MPU6050.c中配置I2C外设

初始化步骤:1.开启I2C外设和对应的DPIO口的时钟;2.把I2C外设对应的GPIO口初始化为复用开漏模式(开漏:I2C协议要求,复用:GPIO控制权要交给硬件外设,软件配置就是通用开漏模式);3.使用结构体,对整个I2C进行配置;4.I2C_Cmd,使能

I2C相关库函数

恢复缺省配置、初始化、结构体初始化、使能


生成起始条件


生成终止条件


这个函数是配置CR1的ACK的,也就是配置收到一个字节之后,是否给从机应答


发送数据,实际就是把Data这个数据,直接写到DR寄存器


接收数据,读取DR的数据作为返回值


发送7位地址的专用函数


多种监控标志位的函数;1.基本状态监控(推荐使用);2.高级状态监控(一般不用);3.基于标志位的状态监控(之前经常只有)


获取标志位、清除标志位、获取中断状态、清除中断挂起位

第五步:在MPU6050.c中封装一个事件等待函数

第六步:在MPU6050.c中配置指定地址写一个字节的时序

第七步:在MPU6050.c中配置指定地址读一个字节的时序

如果想要读取多个字节,直接等待EV7事件,读取DR,就能收到数据,这样依次接收,在接收最后一个字节之前,也就是这里的EV7_1事件,需要提前把ACK置0,STOP置1;如果只读一个字节,在EV6直接之后,就要立刻ACK置0,STOP置1,要是设置晚了,时序就会多一个字节

这里是读一个字节,代码思路:我们是在EV6之后,也就是收到最后一个字节之前,临时把ACK置0,非应答,STOP置1,所以接收函数的最后要恢复默认的ACK=1

第八步:头文件声明

剩下的其他不变,代码任务完成

硬件I2C读写MPU6050完整代码

8. I2C相关库函数

恢复缺省配置、初始化、结构体初始化、使能


生成起始条件


生成终止条件


这个函数是配置CR1的ACK的,也就是配置收到一个字节之后,是否给从机应答


发送数据,实际就是把Data这个数据,直接写到DR寄存器


接收数据,读取DR的数据作为返回值


发送7位地址的专用函数


多种监控标志位的函数;1.基本状态监控(推荐使用);2.高级状态监控(一般不用);3.基于标志位的状态监控(之前经常只有)


获取标志位、清除标志位、获取中断状态、清除中断挂起位

相关推荐
笨笨饿36 分钟前
#110_SCH3000 平台图传系统配置指南:从 DVP 摄像头到 UVC/WiFi 双通道传输
c语言·stm32·单片机·嵌入式硬件·物联网·vim
捷瑞电子工坊1 小时前
FreeRTOS事件组:多任务同步的利器
stm32·嵌入式·freertos·实时操作系统·标准外设库·事件组·任务同步
千秋岁rr3 小时前
5.0 TIM
单片机·嵌入式硬件
小僧景贤3 小时前
STM32 startup.s 启动文件与 .map 映射文件深度技术解析(md/hd 版本差异化对比)
stm32·内存映射·startup.s·map 文件·单片机启动流程
zcmodeltech5 小时前
水利水电沙盘模型控制系统设计与实现:多场景多工况联动方案
网络·stm32·嵌入式硬件·制造·多分类
2601_966799045 小时前
CH398 技术解析:USB 3.0转千兆以太网单芯片方案与内置电源设计要点
单片机·嵌入式硬件
zlinear数据采集卡6 小时前
数据采集卡从入门到精通(38):上位机开发实战——Python/QT/LabVIEW的技术选型与分层架构
python·单片机·嵌入式硬件·qt·fpga开发·开源·labview
嵌入式阿蔡6 小时前
项目实战 02:智能家居环境网关——ESP32 做 BLE 中心 + 本地联动
网络·单片机·嵌入式硬件·esp32·智能家居·嵌入式实时数据库
自小吃多7 小时前
Capture软件原理图添加差分属性笔记
笔记·嵌入式硬件
简单电磁炮7 小时前
ADXL345调试
单片机·嵌入式硬件