STM32 软件IIC配置(MPU6050演示)

这篇具有很好参考价值的文章主要介绍了STM32 软件IIC配置(MPU6050演示)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

IIC说明:
IIC是一种通信协议,IIC 总线是一种用于IC器件之间连接的二线制总线,有主机和从机,二者可以互相通信,可以一主多从也可以多主多从,有时钟线(SCL)和数据线(SDA),SDA线既可以被主机控制也可以被从机控制,但SCL线只能由主机控制。
软件IIC配置:
总体操作:
1.初始化GPIO,包括打开时钟,配置结构体,初始化选用的引脚
2.配置IIC开始函数
3.配置IIC结束函数
4.配置IIC发送一个字节函数
5.配置IIC接收一个字节函数
6.配置IIC发送应答函数
7.配置IIC接收应答函数
具体操作:
1.初始化GPIO,例如,选用Pin10为SCL线,Pin11为SDA线,配置IIC的GPIO为开漏输出

void MyI2C_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11);
}

1.1IIC不论是SDA还是SCL都只有高低两种状态,所有使用时就是把GPIO电平配置为高或者低
例如:

	GPIO_WriteBit(GPIOB,GPIO_Pin_10,1);
	Delay_us(10);
	GPIO_WriteBit(GPIOB,GPIO_Pin_11,1);
	Delay_us(10);

延时10微秒为操作时间,实测不延时也可以
但这样,每次都配置GPIO不仅麻烦还不明了
所以就把GPIO封装起来

void MyI2C_W_SCL(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);
	Delay_us(10);
}//对SCL线封装,便于操作,控制时钟线
void MyI2C_W_SDA(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);
	Delay_us(10);
}//对SDA线封装,便于操作,发送主机值
uint8_t MyI2C_R_SDA(void)
{
	uint8_t BitValue;
	BitValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);
	Delay_us(10);
	return BitValue; 
}//对SDA线封装,便于操作,读取从机发送的值

封装完以后便可以很简单的配置后面的函数
2.配置开始函数
IIC开启需要在SCL为高的时候拉低SDA,这样为开启IIC信号,从机便知道,IIC开启,主机要发送或者接收数据了

void MyI2C_Start(void)
{
	MyI2C_W_SDA(1);
	/*最好先拉高SDA确定,简要原因在最后面的读MPU6050的注释里面有简要说明,
	这样只是一个以防外一,个人感觉不是特别重要*/
	MyI2C_W_SCL(1);
	MyI2C_W_SDA(0);
	MyI2C_W_SCL(0);//拉低SDA后再把SCL拉低,便可以进行数据传送

3.配置结束函数 IIC结束需要在SCL为高的时候拉高SDA,这样为关闭IIC信号,从机便知道,IIC关闭,主机要结束发送或者接收数据了,实际上,在配置的IIC函数里面,只有结束函数里面SCL以高结束,其他的都为低,这样方便两个函数衔接。

void MyI2C_Stop(void)
{
	MyI2C_W_SDA(0);//先拉低SDA确保待会可以产生上升沿
	MyI2C_W_SCL(1);
	MyI2C_W_SDA(1);
}

4.配置主机发送函数
主机在SCL低的时候只会发送一位,从机在SCL为高的时候一次也只接收一位,每次都是一位一位进行的

void MyI2C_SentByte(uint8_t Byte)
{
	uint8_t i;
	for(i=0;i<8;i++)
	{
		MyI2C_W_SDA(Byte&(0x80>>i));
		MyI2C_W_SCL(1);
		MyI2C_W_SCL(0);
	}
}

一次发送八位数据也就是一个字节的数据,所以在for循环里面循环8次
在8次数据发送完以后,主机需要释放SDA,这时从机会自己占据SDA线给主机发送应答后面写的主机的接收应答就会主动去释放SDA(所有的发送和接收都是相对主机而言的)
5.配置主机接收函数

uint8_t MyI2C_ReceiveByte(void)//主机接收时,从机在时钟线拉低的时候只会发送一位数据
{
	uint8_t i,Byte=0x00;
	MyI2C_W_SDA(1);
	for(i=0;i<8;i++)
	{ 
		MyI2C_W_SCL(1);
		if(MyI2C_R_SDA()==1){Byte |= (0x80>>i);}//高位先行,所以右移
		MyI2C_W_SCL(0);
	}
	return Byte;
}

主机接收的数据要处理,所以要用变量存起来,发送的数据从机会自动处理
6.配置IIC发送应答

void MyI2C_SentAck(uint8_t AckBit)
{
	MyI2C_W_SDA(AckBit);//当发送完一个数据以后,SCL本身就是低的,所以前面不需要再给SCL低了
	MyI2C_W_SCL(1);
	MyI2C_W_SCL(0);
}

发送应答是主机接收了一个数据以后发送个主机的应答,SDA拉高,相当于主机发送1,为非应答,不需要再接收数据时就要发非应答,需要接收数据时,就在SDA拉低,为应答。从机发送完一个字节数据以后,会自动释放SDA,此时主机应占据SDA,从机便会去读取SDA的值,接收主机的应答(应答信号在第9个时钟周期出现,这时发送器必须在这一时钟位上释放数据线,由接收设备拉低SDA电平来产生应答信号或非应答信号)
7.配置IIC接收应答

uint8_t MyI2C_ReceiveAck(void)
{
	uint8_t AckBit;
	MyI2C_W_SDA(1);//主机主动空出SDA,从机会立刻占据,发送应答或者非应答信号
	MyI2C_W_SCL(1);//SCL拉高以后,主机便可以去读取从机给的信号
	AckBit=MyI2C_R_SDA();
	MyI2C_W_SCL(0);//放手SDA
	return AckBit;
}

在主机发送完数据以后,主机应空出SDA线,此时从机会产生应答或者非应答,因为是软件模拟IIC所以可以选择读取也可以不去读取,选择读取便可以根据读取的值判断下一步要不要再继续操作。因为一个时钟信号只进行一位传输,所以从机检测到电平变化以后如果接下来还是主机操作便不在占据SDA。

以上便是软件IIC的所有配置

以MPU6050为例,演示IIC的进行
MPU6050初始化即IIC初始化
如果要给MPU6050写一个字节的数据:

void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data)
{
	MyI2C_Start();//打开IIC通信
	MyI2C_SentByte(0xD0);//选中MPU6050,最后一位为0为写操作
	MyI2C_ReceiveAck();//从机发送应答,主机要接收应答
	MyI2C_SentByte(RegAddress);//主机继续发送要写的寄存器地址
	MyI2C_ReceiveAck();//主机接收从机的应答
	MyI2C_SentByte(Data);//主机发送要写的数据
	MyI2C_ReceiveAck();//主机接收从机的应答
	MyI2C_Stop();//停止IIC通信SDA与SCL都为高
}

IIC开始以后,第一次发送的是硬件的地址,每一个硬件都有一个地址,出厂的时候写好的,发送的数据前七位为地址,最后一位为读写位,0为写,1为读。
如果要读MPU6050一个字节的数据:

uint8_t MPU6050_ReadReg(uint8_t RegAddress)//读指定寄存器
{
	uint8_t Data;//接收读出数据的变量
	MyI2C_Start();
	MyI2C_SentByte(0xD0);
	MyI2C_ReceiveAck();
	MyI2C_SentByte(RegAddress);
	MyI2C_ReceiveAck();//前面几步确定地址
	MyI2C_Start();
	/*Start里面先SDA置1就是这里在上一步SCL为0的时候赶快为高然后重新开始,
	避免还没为高的时候SCL已经拉高了。
	如果SDA还没为高的时候SCL已经拉高了,这样再产生下降沿之前产生的就是上升沿了,就是停止的意思了。
	但是接收应答后,从机释放SDA,此时SDA就是高主机没有进行操作,SDA一直为高,所以个人感觉不重要*/
	MyI2C_SentByte(0xD1);//对指定地址进行读
	MyI2C_ReceiveAck();//从机要回应这个指令
	Data=MyI2C_ReceiveByte();//从机把指定地址的数据通过SDA线发出来
	MyI2C_SentAck(1);//主机回应1表示不给应答,从机便会结束发送
	MyI2C_Stop();//结束通信
	return Data;
}

因为无法直接指定寄存器读,但可以指定寄存器写,指定的地址指针在下一次操作前不变,所以指定地址写,然后什么都不写,重新开始读,便可以指定地址读文章来源地址https://www.toymoban.com/news/detail-723730.html

到了这里,关于STM32 软件IIC配置(MPU6050演示)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32软件模拟实现IIC写入和读取AT24C02(STM32CubeMx配置)

    IIC:Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工 通信总线。 在使用IIC时分为硬件IIC以及软件IIC,下图为两者的区别: 在使用IIC前先来了解一下IIC总线结构图,即下图: 从图中可以看出IIC有两个双向信号线,一根是数据线SDA,一根是时钟线SCL,并且都接上拉

    2024年02月04日
    浏览(53)
  • 【STM32】STM32学习笔记-MPU6050简介(32)

    •MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景 •3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度 •3轴陀螺仪传感器(Gyroscope):测量X、Y、

    2024年01月19日
    浏览(46)
  • STM32软件I2C驱动MPU6050

    这里没有什么复杂的地方,采用MPU6050的现成模块.模块的SCL接B10,SDA接B11,这里连接了一个OLED显示屏,用于显示获取到的数据. 注意:这里使用的模块自带上拉电阻 首先在工程目录里创建: \\\"MyI2C.h\\\"和\\\"MyI2C.c\\\"文件,用于软件驱动I2C. \\\"MPU6050.h\\\",\\\"MPU6050.c\\\"和\\\"MPU6050Reg.h\\\"文件,用于MPU6050的驱动. 在

    2024年02月15日
    浏览(44)
  • 【stm32】软件I2C读写MPU6050

    概况 首先建立通信层的.c和.h模块 在通信层里写好I2C底层的GPIO初始化 以及6个时序基本单元 起始、终值、发送一个字节、接收一个字节、发送应答、接收应答 写好I2C通信层之后,再建立MPU6050的.c和.h模块 基于I2C通信的模块,来实现指定地址读、指定地址写 再实现写寄存器对

    2024年04月26日
    浏览(43)
  • stm32之软件模拟IIC

            在之前的文章中分析过在52上的IIC时序,也测试过stm32的自带IIC功能,这里大致写下如何模拟stm32上的IIC。实验硬件基于stm32f103c8t6 废话不多说,先直接上代码。 头文件 .m文件  实验用了PB8和PB9,设置的都是开漏输出式,因为在这个模式下有如下说明: 在配置成开

    2024年02月07日
    浏览(51)
  • 【CubeMX配置STM32驱动MPU6050】

    一、使用CubeMX进行相关配置 1、配置OLED的IIC接口 OLED的具体使用方法我就不细说了,我前面的文章里面有讲OLED的,如果有需要可以去看看。 2、配置MPU6050的接口 我用MPU6050使用的是 软件IIC (其实是只找到软件IIC的驱动),所以我们只需要配置两个GPIO口就可以实现对MPU6050的控

    2024年02月12日
    浏览(38)
  • 使用C++编写STM32软件IIC

    最近在重构自己的平衡车代码,里面需要用到MPU6050的DMP,从中读取四元数进行欧拉角解算,但是看着软件IIC的代码实在是很变扭,因为之前不会C++,所以如果需要调用多个IIC设备,那么使用的时候就需要重复的去进行软件IIC底层代码的初始化,非常的麻烦,而且需要调整各个

    2024年02月04日
    浏览(36)
  • 陀螺仪MPU6050(IIC&源码)

    1. 陀螺仪 1.1   什么是陀螺仪? 检测角度变化的一个装置。 1.1.1  有什么用?? 用于检测角度变化,用角度变化的值判断物体的运动轨迹。 1.1.2  我们怎么用? 我们是使用这个装置(或者说设备)获取到数据,再使用这个数据得到我们想要的信息。 这里我使用陀螺仪获取板

    2024年02月13日
    浏览(33)
  • STM32硬件IIC实验(STM32CubeMx配置)

    IIC:Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工 通信总线。 在这里贴一下硬件IIC和软件IIC的区别: 从图中可以看出两者的区别,硬件IIC比软件IIC的用法会比较复杂,但是这里如果不关注底层的实现去使用STM32CubeMx进行IIC的配置,再使用特定函数就能够实现

    2024年02月12日
    浏览(34)
  • STM32(HAL库)软件IIC驱动OLED

    目录 1、简介 2、CubeMX初始化配置 2.1 基础配置 2.1.1 SYS配置  2.1.2 RCC配置 2.2 软件IIC引脚配置 2.3 项目生成  3、KEIL端程序整合 3.1 OLED驱动添加 3.3 主函数代 3.4 效果展示 本文通过STM32F103C8T6单片机(HAL库)通过软件IIC方式对OLED进行驱动。 2.1.1 SYS配置  2.1.2 RCC配置 首先在建立Ha

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包