软件IIC通信以及源码解析(如何使用)

以对读取MPU6050为例,解析如何采用IIC通信源码。

IIC的的通信,通常三种用途读写。分为:

1:

 2:

 3:

 注:其中最常用的就是1和3了。

对1进行讲解:

指定地址写,通常用作对状态机模块的控制寄存器写入二进制数,操作控制寄存器,进而让模块进行我们需要的功能。

分为三个步骤:

1:发送   从机地址+读写位(因为是写,所以是从机地址+写(写=0))

2:发送(要写)要操作的寄存器地址。

3:写入你想发送的八位数据(该八位数据用来控制寄存器功能)。

时序图如下:

 源码如下(以读取MPU6050为例,如果读取其它从机,只要把从机地址改了即可。):

软件IIC.C文件

#define MPU6050_ADDRESS		0xD0  //1101 0000= AD0(1101000)+ 0 :融入了写数据位: 0

//写数据给从机的指定寄存器  参数1:要写入的地址  参数2:要写入的八位数据
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
	MyI2C_Start();  //起始条件
	MyI2C_SendByte(MPU6050_ADDRESS);  //写入从机地址
	MyI2C_ReceiveAck();  //从机应答
	MyI2C_SendByte(RegAddress);  //发送写入的寄存器地址
	MyI2C_ReceiveAck();  // 从机应答
	
	MyI2C_SendByte(Data);  //发送一个字节数据
	MyI2C_ReceiveAck();  //从机应答
	//可加For循环多读
	MyI2C_Stop();  //停止条件
}

对3进行讲解:

指定地址读,通常用做读取状态寄存器标志位的值。或者读取数据寄存器的值。

步骤如下:

1:发送   从机地址+读写位(因为读之前必须先写入从机地址,所以是从机地址+写(写=0))

2:发送(要读)要操作的寄存器地址。

3:重复1的步骤,不过这次是从机地址+读。

4:接受从机的寄存器发送来的数据。

时序图如下:

 

IIC.h文件如下:(注释均已做详细说明)

//从从机指定寄存器中读数据  参数:要读的数据地址
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
	uint8_t Data;
	
	MyI2C_Start();  //起始条件
	MyI2C_SendByte(MPU6050_ADDRESS);  //写入从机地址包含写操作
	MyI2C_ReceiveAck();  //从机应答0  有该地址
	MyI2C_SendByte(RegAddress);  //发送(写)需要读的寄存器地址
	MyI2C_ReceiveAck();  // 从机应答0有该地址
	
	MyI2C_Start();  //重新起始条件
	MyI2C_SendByte(MPU6050_ADDRESS | 0x01);  //发送需要读的寄存器地址包含读操作
	MyI2C_ReceiveAck();  //从机应答0 
	Data = MyI2C_ReceiveByte();  //开始接受(读指定地址)从机数据
	MyI2C_SendAck(1);  主机应答1
	MyI2C_Stop();  //停止条件
	
	return Data;
}

两部分的IIC.H文件函数原型如下:

#ifndef __MPU6050_H
#define __MPU6050_H

void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);


#endif

读取mpu6050六轴数据为例。实例如下(读取其它传感器框架流程基本一样):

首先我们读取从机地址。用来测试IIC通信是否可行。

uint8_t MPU6050_GetID(void)
{
	return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}

其次需要对mpu6050模块的功能寄存器进行写,这样就配置好传感器的功能了,也就是传感器供能初始化

代码如下:

void MPU6050_Init(void)
{
	MyI2C_Init();
	MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);  //配置电源管理寄存器1  :解除睡眠状态
	MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);  //配置电源管理寄存器2
	MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);  //配置采样率分频:ADC转换数据的快慢
	MPU6050_WriteReg(MPU6050_CONFIG, 0x06);      //配置寄存器
	MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); //陀螺仪配置寄存器  :量程选择最大16g
	MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);//加速度计配置寄存器 :量程选择最大
}

最后我们就可以读取数据寄存器的数据了(因为配置好功能寄存器了,所以数据寄存器开始产生数据)。

代码如下(采用指针传参,可以节省内存):

void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
	uint8_t DataH, DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);  //读取加速度寄存器的高8位
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);  //读取加速度寄存器的低8位
	*AccX = (DataH << 8) | DataL;  // *AccX = (DataH << 8) | DataL; :将数据传给该地址下的变量中  :重点
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
	*AccY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
	*AccZ = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
	*GyroX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
	*GyroY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
	*GyroZ = (DataH << 8) | DataL;
}

完整的main.c如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"

uint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;

int main(void)
{
	OLED_Init();
	MPU6050_Init();
	
	OLED_ShowString(1, 1, "ID:");
	ID = MPU6050_GetID();
	OLED_ShowHexNum(1, 4, ID, 2);
	
	while (1)
	{
		MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);
		OLED_ShowSignedNum(2, 1, AX, 5);
		OLED_ShowSignedNum(3, 1, AY, 5);
		OLED_ShowSignedNum(4, 1, AZ, 5);
		OLED_ShowSignedNum(2, 8, GX, 5);
		OLED_ShowSignedNum(3, 8, GY, 5);
		OLED_ShowSignedNum(4, 8, GZ, 5);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值