学习STM32第十二天

本文详细介绍了I2C通信的基础知识,包括易失性和非易失性存储器类型,如RAM、SDRAM和ROM,以及NOR/NANDFlash。重点讲解了I2C协议的工作原理,涉及MPU6050姿态传感器的应用,并提供了基于STM32F4xx的软件I2C实现示例。
摘要由CSDN通过智能技术生成

I2C通信

一、存储器

按存储介质特性主要分为“易失性存储器”和“非易失性存储器”,主要代表是内存和硬盘。

  • 易失性存储器
    又称RAM,数据被读取或写入所需的时间与这段信息所在的位置无关
    • DRAM
      需要定时刷新保证数据的正确
      • SDRAM(同步DRAM)
      • DDR SDRAM(双倍数据率SDRAM)
      • DDRII SDRAM
      • DDRIII SDRAM
    • SRAM
      以锁存器电路存储数据,不需要定时刷新,存取所读较DRAM快。SRAM一般只用于CPU内部的高速缓存(Cache),外部扩展内存一般使用DRAM。
  • 非易失性存储器
    • ROM
      • MASK ROM(数据在其出厂时就固化,不可修改)
      • PROM
        • OTPROM(一次性可编程)
        • EPROM(可重复擦写的存储器)
        • EEPROM(电可重复擦写的存储器,主要的ROM芯片都是EEPROM)
    • FLASH
      一般以多个字节为单位,以4096个字节为扇区。擦除次数有限
      • NOR FLASH
        地址线与数据线独立分开
      • NAND FLASH
        地址线与数据线共用
    • 硬盘

二、I2C协议

2.1 I2C总线基本概念

I2C是一种多主从机、两线制、低速串行通信总线,广泛用于微控制器和各种外围设备之间的通信。使用两条线路:串行数据线(SDA)和串行时钟线(SCL)进行双向传输

  • 特点:时钟速率可变连接简单地址分配阻塞传输冲突检测低功耗

  • 通信方式:同步串行,每个字节由8位数据构成,加上开始、停止条件以及可选的应答位,支持多种速率

  • 工作原理
    通信由主设备在SDA线上生成特定的信号模式来开始和结束,每次通信开始时主设备发送一个地址帧来指定与之通信的从设备。主设备控制时钟信号,向从设备发送或接收数据,通过应答位告知数据是否被成功接收。每个设备的地址是唯一的,在多主模式下通过仲裁机制决定哪个设备获得控制权。由于所有I2C设备的SCL连在一起,SDA连在一起,为避免总线没协调好导致电源短路设备的SCL和SDA均要配置为开漏输出模式,I2C禁止所有设备输出强上拉高电平,为避免高电平造成引脚浮空需要在SDA和SCL总线上各外置一个上拉电阻,使用若上拉电阻。同时会有一个“线与”现象,只要有任意一个或多个设备输出低电平则总线处于低电平,仅当所有设备输出高电平时总线处于高电平,这样可执行多主机模式下的时钟同步和总线仲裁。
    I2C硬件

  • I2C数据传输流程
    数据信号以8位的序列传输,在特殊的开始条件发生后,就会出现第一个8位序列,它指示了数据被发送到哪个从设备的地址,每个8位序列之后都会跟随一个称为确认的位。
    I2C单字节
    在大多数情况下,第一个确认位之后会跟着另一个寻址序列,但这次是针对从设备的内部寄存器。在寻址序列之后是数据序列,直到数据完全传输完毕,并以一个特殊的停止条件结束。
    I2C帧结构

  • 时序基本单元
    SDA和SCL都处于高电平时,总线处于空闲状态。起始和终止都是由主机产生。

    • 起始条件:SCL高电平期间,SDA从高电平切换到低电平
    • 终止条件:SCL高电平期间,SDA从低电平切换到高电平
      I2C时序基本单元
    • 发送一个字节
      SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机在SCL高电平期间读取数据位,因此SCL高电平期间SDA不允许有数据变化,循环八次即发送一个字节。
      I2C发送一个字节
    • 接收一个字节
      SCL低电平期间,从机将数据位放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,循环8次即接收一个字节(为了防止主机干扰从机写入数据,在接收之前需要释放SDA即转换为接收模式)
      I2C接受一个字节
    • 应答
      在完成发送或接收一个字节后,下一个时钟是一位应答位,0表示应答,1表示非应答。
      I2C应答
  • I2C时序
    I2C完整时序,主要有指定地址写指定地址读当前地址读。先把从设备都确定一个唯一的设备地址(该地址由芯片手册查询,一般器件地址的最后几位可以在电路中改变以允许使用同种芯片模块),主机在起始条件之后先发送一个从机地址(7位地址和10位地址),0表示写入,1表示读取。

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

    • 当前地址读
      I2C当前地址读
      对于指定设备(Slave Address),在当前地址指针(此时主机交换SDA控制权,接收从机SDA发送的数据,从机所有的寄存器都被分配到了一个线性区域中,指针默认指向0地址,在每写入或读出一个字节后指针自增一次)指示的地址下,读取从机数据(Data)。

    • 指定地址读 I2C指定地址读
      对于指定设备(Slave Address)中指定地址(Reg Address)下,读取从机数据(Data)。在发送完从设备地址之后的写操作是为了将指定地址写入到指针中,然后重新寻址并且指定读写标志位进行当前地址读操作。

三、MPU6050

MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景。3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度。3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度。16位ADC采集传感器的模拟信号,量化范围:-32768~32767,加速度计满量程选择:±2、±4、±8、±16(g),陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec),可配置滤波器、时钟源以及采用分频。
MPU6050硬件电路

四、软件I2C

#include "stm32f4xx.h"                  // Device header
#include "Delay.h"

//软件I2C,SDA和SCL引脚根据需要配置
//GPIO全在AHB1总线,这里选择PD2作SCL和PD3作SDA

/*封装I2C引脚电平函数*/
void MyI2C_W_SCL(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOD, GPIO_Pin_2, (BitAction)BitValue);
	Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOD, GPIO_Pin_3, (BitAction)BitValue);
	Delay_us(10);
}
uint8_t MyI2C_R_SDA()
{
	uint8_t BitValue = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3);//主机读取SDA引脚电平
	Delay_us(10);
	return BitValue;
}

/*I2C初始化函数,SDA和SCL同时为高电平*/
void MyI2C_Init()
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOD, GPIO_Pin_2 | GPIO_Pin_3);//I2C处于空闲状态
}
/*I2C起始条件*/
void MyI2C_Start()
{
	//在SCL高电平期间,SDA从高电平切换到低电平,先拉低SDA再拉低SCL
	MyI2C_W_SDA(1);//先释放SDA
	MyI2C_W_SCL(1);
	MyI2C_W_SDA(0);
	MyI2C_W_SCL(0);
}
/*I2C终止条件*/
void MyI2C_End()
{
	//在SCL高电平期间,SDA从低电平切换到高电平,先拉高SCL再拉高SDA
	MyI2C_W_SDA(0);
	MyI2C_W_SCL(1);
	MyI2C_W_SDA(1);
}
/*发送一个字节*/
void MyI2C_SendByte(uint8_t Byte)
{
	//在SCL低电平期间,主机将数据依次放到SDA线上(高位先行)然后释放SCL
	for(uint8_t i = 0; i < 8; i ++)
	{
		MyI2C_W_SDA(Byte & (0x80 >> i));//通过按位与将数据以高位先行的顺序写传输
		MyI2C_W_SCL(1);//从机在SCL高电平期间读取数据位
		MyI2C_W_SCL(0);//保证SCL以低电平结束确保下次数据传输
	}
}
/*接收一个字节*/
uint8_t MyI2C_ReceiveByte()
{
	//SCL低电平期间,从机将数据依次放到SDA线上(高位先行)然后释放SCL
	
	uint8_t Byte = 0x00;
	MyI2C_W_SDA(1);//为了防止主机干扰从机写入数据,需要主机释放SDA即转换为接收模式
	for(uint8_t i = 0; i < 8; i ++)
	{
		MyI2C_W_SCL(1);//主机在SCL高电平期间读取数据位
		if(MyI2C_R_SDA() == 1) Byte |= (0x80 >> i);
		MyI2C_W_SCL(0);
	}
	return Byte;
}
/*发送应答*/
//主机在接收完一个字节之后,在下一个时钟发送一位数据,0表示应答,1表示非应答
void MyI2C_SendAck(uint8_t AckBit)
{
	MyI2C_W_SDA(AckBit);
	MyI2C_W_SCL(1);//从机在SCL高电平期间读取应答位
	MyI2C_W_SCL(0);
}


/*接收应答*/
//主机在发送完一个字节之后,在下一个时钟接收一位数据以判断从机是否应答,0表示应答,1表示非应答
uint8_t MyI2C_ReceiveAck()
{ 
	uint8_t AckBit;
	MyI2C_W_SDA(1);//主机在接受之前要释放SDA,切换到接收状态
	MyI2C_W_SCL(1);//主机在SCL高电平期间读取应答位
	AckBit = MyI2C_R_SDA();
	MyI2C_W_SCL(0);
	return AckBit;
}







  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第十二届蓝桥杯大赛嵌入式组的STM32G431资源包是一个提供给参赛选手使用的开发工具包。STM32G431是STMicroelectronics公司推出的一款高性能、低功耗的嵌入式微控制器。该资源包包含了STM32G431主控板、配套的软件工具、教程文档等。 首先,STM32G431主控板是该资源包的核心部分。它内置了STM32G431微控制器芯片,具有丰富的外设接口,包括多个GPIO口、SPI、I2C、USART等通信接口,以及ADC、DAC等模拟输入输出接口。此外,主控板还提供了可扩展的外设接口,方便参赛选手根据需求进行外设的扩展和连接。 其次,STM32G431资源包还包含了丰富的软件工具,用于开发和调试嵌入式应用程序。其中包括STM32CubeMX配置软件,可帮助选手快速生成初始化代码,并进行外设的配置和引脚分配。另外还提供了Keil MDK开发集成环境和J-Link调试器,用于编写、编译和调试嵌入式应用程序。这些工具的使用简单方便,能够帮助选手高效地进行开发工作。 此外,STM32G431资源包还附带了详细的教程文档,包括使用说明、示例代码以及相关应用的案例。这些文档提供了参赛选手学习和参考的资料,可以帮助他们了解STM32G431的基本原理和功能,掌握开发工具的使用方法,以及进行相关应用的开发和调试。 总之,第十二届蓝桥杯大赛嵌入式组的STM32G431资源包提供了一套完整的开发工具包,包括STM32G431主控板、软件工具和教程文档。选手可以通过这些资源,快速上手开发嵌入式应用,充分发挥STM32G431的强大性能和低功耗特点,展示自己的技术实力和创新能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值