STM32-IIC软件读写MPU6050

1.思路讲解

首先创建IIC模块,完成基本的起始终止,发送接收功能。然后创建MPU6050模块完成指定地址读写功能。

2.代码展示

IIC模块代码:

a.SDA,SCL读写

void MyIIC_W_SCL(uint8_t Value)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_10,Value);
	Delay_us(10);
}

void MyIIC_W_SDA(uint8_t Value)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_11,Value);
	Delay_us(10);
}

uint8_t MyIIC_R_SDA(void)
{
	uint8_t Value=0;
	Value = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);
	Delay_us(10);
	return Value;
}

b.IIC的初始化,就是对IIC需要使用的IO口初始化,注意使用开漏输出,并将SCL,SDA拉高为高电平。

void MyIIC_Init(void)
{
	GPIO_InitTypeDef GPIOBInitStrcture;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIOBInitStrcture.GPIO_Mode=GPIO_Mode_Out_OD;//开漏输出模式
	GPIOBInitStrcture.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11;
	GPIOBInitStrcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIOBInitStrcture);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11);//将SCL SDA置高电平 使IIC处于空闲状态
}

c.起始状态代码,SCL高电平期间,SDA由高到低,这里将SCL也下拉,是为了后面主机在SCL低电平期间输入数据到SDA,此步放到下一个写入数据代码也可以。

void MyIIC_Start(void)
{
	//起始状态:SCL,SDA 都在高电平 在SCL高电平时将SDA下拉进行起始状态,随后将SCL下拉
	MyIIC_W_SDA(1);
	MyIIC_W_SCL(1);
	MyIIC_W_SDA(0);
	MyIIC_W_SCL(0);
}

d. 终止状态,SCL高电平期间,SDA从低电平上升到高电平。

void MyIIC_Stop(void)
{
	//终止状态:在SCL高电平状态下,将SDA从低电平上拉到高电平,进入终止状态
	MyIIC_W_SDA(0);
	MyIIC_W_SCL(1);
	MyIIC_W_SDA(1);
}

e.发送字节

void MyIIC_SendByte(uint8_t Value)
{
	uint8_t i;
	//发送字节:在SCL低电平时,主机在SDA输入一个数据,在SCL高电平时从机在SDA上读取数据
	for(i=0;i<8;i++)
	{
		MyIIC_W_SDA(Value & (0x80 >> i));
		MyIIC_W_SCL(1);
		MyIIC_W_SCL(0);
	}
}

f.接收字节,这里接收的思路是用0X80(1000 000)的i位移位去与SDA上从机传输的数据对比,如果哪一位是1则哪一位为1。

uint8_t MyIIC_ReadByte(void)
{
	uint8_t Value=0x00;
	uint8_t i=0;
	//读入字节:主机释放SDA,将SDA置1,从机控制SDA,在SCL为低电平时,从机在SDA上放入数据
	//在SCL为高电平时主机从SDA上读取数据
	MyIIC_W_SDA(1);
	for(i=0;i<8;i++)
	{
		MyIIC_W_SCL(1);
		if(MyIIC_R_SDA() == 1){Value |= (0x80>>i);}
		MyIIC_W_SCL(0);
	}
	return Value;
}

g.发送应答

void MyIIC_SendAck(uint8_t Ack)
{
	MyIIC_W_SDA(Ack);
	MyIIC_W_SCL(1);
	MyIIC_W_SCL(0);
}

h.接收应答

uint8_t MyIIC_ReceiveAck(void)//收到0表示从机应答,1表示不应答
{
	uint8_t Ack;
	MyIIC_W_SDA(1);
	MyIIC_W_SCL(1);
	Ack=MyIIC_R_SDA();
	MyIIC_W_SCL(0);
	return Ack;
}

3.MPU6050代码展示

a.指定地址写,起始条件,写入从机地址,接收应答,写入寄存器地址,接收应答,写入数据,接收应答,终止条件。

void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Value)//寄存器地址,数据
{
	MyIIC_Start();
	MyIIC_SendByte(0xd0);//MPU6050的地址
	MyIIC_ReceiveAck();
	MyIIC_SendByte(RegAddress);//写入寄存器地址
	MyIIC_ReceiveAck();
	MyIIC_SendByte(Value);
	MyIIC_ReceiveAck();
	MyIIC_Stop();
}

b.指定地址读,起始条件,写入从机地址,接收应答,写入寄存器地址,接收应答。起始条件,写入从机地址,但是第八位为1,表示进行读操作。接收应答,读取从机输出的数据,发送应答,终止条件。返回读取数据。

uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
	uint8_t Value;
	//假写操作
	MyIIC_Start();
	MyIIC_SendByte(0xd0);//MPU6050的地址
	MyIIC_ReceiveAck();
	MyIIC_SendByte(RegAddress);//写入寄存器地址
	MyIIC_ReceiveAck();
	
	MyIIC_Start();
	MyIIC_SendByte(0xd1);//从机读地址
	MyIIC_ReceiveAck();
	Value = MyIIC_ReadByte();
	MyIIC_SendAck(1);
	MyIIC_Stop();
	
	return Value;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值