STM32学习笔记 -- I2C(江科大)

STM32学习笔记 – I2C

原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!
代码总结部分还未更新

一、II2简介

IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构。

  • 两根通信线:SCL(Serial Clock)、SDA(Serial Data)
    - 同步,半双工
    - 带数据应答
    - 支持总线挂在多设备(一主多从、多主多从)

1.时序(以stm32作为主机思考)

起始条件:SCL高电平期间,SDA从高电平切换到低电平
终止条件:SCL高电平期间,SDA从低电平切换到高电平
在这里插入图片描述
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次即可发送一个字节
接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机再接收之前,需要释放SDA,释放SDA就相当于切换为输入模式)。

理解:谁要放数据谁就掌握SCL(拉低SCL),然后改变SDA ,处于接收的设备需释放SDA
发数据SCL低电平,读数据SCL高电平

在这里插入图片描述
发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
可以理解为发送1位和接收1位,这一位用来作为应答,在发送完一个数据之后,就要立即进行接收应答,来判断从机是否接收到主机发送的数据

理解:谁接收信息谁就要发应答位

二、IIC的读写

为什么没当前地址写,可能是因为写完后不知道写在哪里了

指定地址写

  • 对于指定设备(Slave Address),在指定地址(Reg Address)下写入数据(Data)

    1.空闲状态下两个总线都是高电平
    2.主机需要给从机写入数据的时候,在SCL高电平期间,拉低SDA,产生起始条件,在起始条件之后紧跟的时序,必须是发送一个字节的时序,字节的内容必须是从机地址+读写位
    3.紧跟着的单元是接收从机的应答位(Receive Ack,RA),这个时刻主机需要释放SDA,如果从机应答,从机会立即拉低SDA,应答位产生后,从机释放SDA,从机交出SDA的控制权,同样的时序再来一遍,第二个字节数据就会送入指定数据的内部,一般第二个字节是寄存器地址或者是指令控制字
    4.第三个字节是想要往寄存器地址中写入的值如果主机不想发送数据了,要产生停止条件,在产生停止条件之前,先拉低SDA,会后续的上升沿做准备然后释放SCL,再释放SDA,产生SCL高电平期间SDA的上升沿。
    5.写多个字节:重复三遍,发送一个字节和接收应答,第一个数据就写入0x19的位置(写入一个地址后地址指针会自动+1,编程吧0x1A)第二个数据就会写到0x1A的位置,第三个数据写入的是0x1B的位置
    在这里插入图片描述

当前地址读

  • 对于不指定设别(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)

    1.在SCL高电平期间,拉低SDA,产生起始条件,主机首先发送一个字节,来进行从机的寻址和读写标志位,图示波形代表,本次寻址的目标是1101000的设备,读写标志为1,表示主机接下来想要读取设备,
    2.发送一个字节后,接收从机应答位,代表从机收到了第一个字节,把SDA的控制权交给从机,主机调用接收一个字节的时序,进行接收操作,从机接收到了主机的允许,可以在SCL低电平期间写入SDA,主机在哪SCL高电平期间读取SDA,主机再SCL高电平期间依次读取8位,就接收到了从机发送的一个字节数据0000 1111也就是(0x0F),
    3.没有指定地址这个环节
    4.在从机中所有寄存器被分配到了一个线性区域中,会有个单独的指针变量,指示着其中一个寄存器,这个指针上电一般默认0地址,每写入一个字节或者读出一个字节后,这个指针就是自动自增一次,移动到下一个位置),从机返回的是当前指针指向的寄存器的值
    在这里插入图片描述

当前地址读

理解为”指定地址写“的前半部分的指定地址和“当前地址读”的后半部分结合

  • 对于指定设备(Slave Address),在指定地址(Reg Address)下读取从机数据(Data)
    1.指定从机地址是1101000 读写标志位是0,代表要进行写的操作,经过从机应答后,在发送一个字节第二个字节0001 1001,用来指定地址,这个数据就写入到从机的地址指针里了
    2.从机接收到这个地址后,它的寄存器指针就指向了0x19这个位置,
    3.不给从机发要写入的数据,而是再来个起始条件,起始条件后,重新寻址并且指定读写标志位,此时读写标志位为1代表开始读,继续主机接收一个字节,这个字节数据就是0x19地址下的数据。
    在这里插入图片描述

三、stm32的IIC外设

STM32内部集成了硬件收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,软件只需要写入控制寄存器CR和数据寄存器DR就可以实现协议,为了实时监控时序的状态,软件还需要读取状态寄存器SR,来了解外设电路当前处于什么状态,类似于开车,写入控制寄存器CR,就像是踩油门、打方向盘来控制汽车的运行,读取状态寄存器SR,就像是观看仪表盘,来观测汽车的运行状态,有了这些寄存器,就可以完全掌握外设电路的运行了,同时也可以减轻CPU的负担

支持多主机模型
支持7位/10位地址模式
支持不同的通讯速度,标准速度(高达100kHz),快速(高达400kHz)
支持DMA
兼容SMBus协议
STM32F103C8T6 硬件I2C资源:I2C1、I2C2

1.I2C通信,分为主机和从机,主机拥有主动控制总线的权利,从机只能在主机允许的情况下,才能控制总线,主机一个人掌控所有,不存在权利冲突
2. 多主机-多主机模型分为固定多主机和可变多主机
固定多主机就是总线上有两个或多个固定的主机,上面几个始终固定为主机,下面的几个时钟固定为从机,就像是教室里讲台上站了多个老师,下面坐的学生可以被任意一个老师点名,老师可以主动发起对学生的控制,学生不能控制老师,当两个老师同时想说话就是总线冲突状态,这时要进行总线仲裁,仲裁失败的一方让出总线控制权,这种讲台上站多个老师的情况就是固定多主机。
可变多主机就是,总线上可以挂载多个设备,总线上没有固定的主机和从机,任何一个设备都可以在总线空闲时跳出来作为主机,然后指定其他任何一个设备进行通信,当这个通信完成后,跳出来的主机要退回从机的位置,就像是在教室里,只有一堆学生,没有老师,默认情况下,所有学生都是从机,都不能说话,当有某个学生想说话 时,站出来变成主机,然后指定其他任何一个学生进行通信,通信完成后坐下变成从机。当有多个学生同时跳出来时,就是总线冲突状态,这时要进行总线仲裁,仲裁失败的一方让出总线控制权,这种所有设备一视同仁,谁做主机谁跳出来的模型,就是可变多主机,对stm32的I2C使用的是可变多主机的模型
3.10位寻址 I2C起始之后的第一个字节,必须是寻址+读写位,一个字节只能有7位地址,只需要在规定,起始位之后的前两个字节,都作为寻址,就可以完成10位地址寻址,这就是10位地址的基本思路,第一个字节有7个空位,第二个字节,有8ge空位,加一起是15位地址,但是I2C只有10位地址模式,还剩下5位当标志位,因为发送第一个字节后,不知道后面这个字节是不是寻址,所以需要再第一个字节写个特定的数据,作为10位寻址位的标志位,标志位就是11110,也就是第二个字节如果也是寻址,那第一个字节的前5位就必须是11110,如果前5位是11010,就说明它是7位寻址,如果前五位是11110,那第一个字节剩下的两位,和第二个字节的8位,都作为寻址,这就组成了10位地址,11110作为10位地址模式的标志位,不会在7位地址模式下出现的,这就是7位地址和10位地址的1区别。
4.支持DMA可以在多字节传输的时候提高传输效率,比如指定地址读多字节或写多字节的时序,如果想要连续读或者写非常多的字节那用一下DMA自动帮忙转运数据,这个过程的效率就会大大提升,如果只有几个字节就没必要用DMA了。

在这里插入图片描述
上面的那部分是SDA,数据控制部分,数据收发的核心部分是数据寄存器和数据移位寄存器,当我们需要发送数据时,可以把一个字节数据写到数据寄存器DR,当移位寄存器没没有数据移位时这个数据寄存器的值就会进一步转到移位寄存器里,在移位的过程中把下一个数据放到数据寄存器里等着了,一旦前一个数据移位完成,下一个数据就可以无缝衔接,继续发送,当数据从数据寄存器转运到移位寄存器时,就会置状态寄存器的TXE位为1,表示发送寄存器为空,这是发送的流程在接收时,输入的数据,一位一位地,从引脚移入到移位寄存器里,当一个字节的数据收齐之后,数据就整体从移位寄存器转到数据寄存器,同时置标志位RXNE,表示接受寄存器非空,这时候就可以把数据从数据寄存器读出来了。I2C是半双工,所以数据收发是同一组数据寄存器和移位寄存器比较器和地址寄存器这是从机模式使用的,

四、软件IIC(MPU6050)

在这里插入代码片

五、硬件IIC(MPU6050)

在这里插入代码片
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32是一款非常流行的嵌入式微控制器系列,它具有强大的性能和丰富的外设资源。在学习STM32时,掌握如何进行Flash读写是非常重要的。 Flash是一种非易失性存储器,可以用来存储程序代码和数据。在STM32中,Flash存储器通常用来存储应用程序代码。下面是一个简单的Flash读写程序的示例: 1.首先,我们需要包含适用于所使用的STM32型号的头文件。例如,对于STM32F4系列,我们需要包含"stm32f4xx.h"。 2.然后,我们需要定义一个指向Flash存储器的指针变量。例如,可以使用如下代码:`uint32_t* flash_address = (uint32_t*)0x08000000;`其中0x08000000是Flash存储器的起始地址。 3.要读取Flash存储器中的数据,我们可以通过以下代码实现:`data = *flash_address;`其中data是一个变量,用于存储读取到的数据。 4.要写入数据到Flash存储器中,我们可以通过以下代码实现:`*flash_address = data;`其中data是要写入的数据。 需要注意的是,STM32的Flash存储器是有写保护机制的,因此在写入数据之前,我们需要禁用写保护。可以使用以下代码禁用写保护:`FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB;`然后才能进行数据写入。 另外,为了确保数据的完整性,我们可以使用CRC校验来验证Flash存储器中的程序代码的正确性。可以使用库函数来计算校验和,然后将其与预期的校验和进行比较以进行验证。 综上所述,掌握STM32的Flash读写操作对于嵌入式系统的开发非常重要。上述示例代码可以帮助我们快速进行Flash读写操作,同时注意写保护和数据校验可以提高数据的安全性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值