栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【51单片机快速入门指南】4.3: I2C读取MPU6050陀螺仪的原始数据

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【51单片机快速入门指南】4.3: I2C读取MPU6050陀螺仪的原始数据

目录
  • 示例程序
    • MPU6050.c
    • MPU6050.h
    • main.c
  • 实验现象

普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
串口示波器:Vofa+ 1.3.10


移植自正点原子ATK-MPU6050六轴传感器例程。

示例程序

       软件I2C程序见【51单片机快速入门指南】4: 软件 I2C
       stdint.h见【51单片机快速入门指南】1:基础知识和工程创建
       串口部分见【51单片机快速入门指南】3.3:USART 串口通信

MPU6050.c
#include "MPU6050.h"
#include "./Software_I2C/Software_I2C.h"

void Delay1ms();		//@11.0592MHz
void MPU_Delay_Ms(uint16_t Milliseconds)	//移植时需修改
{
	while(Milliseconds--)
		Delay1ms();
}

//IIC连续写
//reg:要写入的寄存器地址
//len:要写入的长度
//buf:要写入的数据的首地址
//返回值:0,正常
//    其他,错误代码
uint8_t MPU_Write_Len(uint8_t reg, uint8_t len, uint8_t *buf)
{
	return i2c_mem_write(MPU_ADDR, reg, buf, len);
}

//IIC连续读
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
uint8_t MPU_Read_Len(uint8_t reg, uint8_t len, uint8_t *buf)
{
	return i2c_mem_read(MPU_ADDR, reg, buf, len);
}

//IIC写一个字节 
//reg:寄存器地址
//data:数据
//返回值:0,正常
//    其他,错误代码
uint8_t MPU_Write_Byte(uint8_t reg, uint8_t Data)
{
	return i2c_mem_write(MPU_ADDR, reg, &Data, 1);
}

//IIC读一个字节 
//reg:寄存器地址 
//返回值:读到的数据
uint8_t MPU_Read_Byte(uint8_t reg)
{
	uint8_t res;
	i2c_mem_read(MPU_ADDR, reg, &res, 1);
	return res;
}

//写入8位寄存器的一个位
uint8_t MPU_Write_Bit(uint8_t addr, uint8_t bitNum, uint8_t Data)
{
	return i2c_write_bit(MPU_ADDR, addr, bitNum, Data);
}

//写入8位寄存器的多个位
uint8_t MPU_Write_Bits(uint8_t addr, uint8_t bitStart, uint8_t length, uint8_t Data)
{
	return i2c_write_bits(MPU_ADDR, addr, bitStart, length, Data);
}

//读取一个位从8位器件的寄存器
uint8_t MPU_Read_Bit(uint8_t addr, uint8_t bitNum, uint8_t *Data)
{
	return i2c_read_bit(MPU_ADDR, addr, bitNum, Data);
}

//读取8位寄存器的多个位
uint8_t MPU_Read_Bits(uint8_t addr, uint8_t bitStart, uint8_t length, uint8_t *Data)
{
	return i2c_read_bits(MPU_ADDR, addr, bitStart, length, Data);
}

//	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK NANO STM32F103开发板 
//MPU6050 驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2018/7/28
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 208-2028
//All rights reserved									  
// 

//初始化MPU6050
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Init(void)
{
	uint8_t res;
	MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0x80);	//复位MPU6050
	MPU_Delay_Ms(100);
	MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0x00);	//唤醒MPU6050 
	MPU_Set_Gyro_Fsr(3);						//陀螺仪传感器,±2000dps
	MPU_Set_Accel_Fsr(0);						//加速度传感器,±2g
	MPU_Set_Rate(50);							//设置采样率50Hz
	MPU_Write_Byte(MPU_INT_EN_REG, 0x01);		//使能数据就绪中断
	MPU_Write_Byte(MPU_USER_CTRL_REG, 0x00);	//I2C主模式关闭
	MPU_Write_Byte(MPU_FIFO_EN_REG, 0x00);		//关闭FIFO
	MPU_Write_Byte(MPU_INTBP_CFG_REG, 0x80);	//INT引脚低电平有效
	res = MPU_Read_Byte(MPU_DEVICE_ID_REG);
	if (res == MPU_ADDR)//器件ID正确
	{
		MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0x01);	//设置CLKSEL,PLL X轴为参考
		MPU_Write_Byte(MPU_PWR_MGMT2_REG, 0x00);	//加速度与陀螺仪都工作
		MPU_Set_Rate(200);							//设置采样率为200Hz
	}
	else
		return 1;
	return 0;
}

//设置MPU6050陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)
{
	return MPU_Write_Byte(MPU_GYRO_CFG_REG, fsr << 3);//设置陀螺仪满量程范围  
}

//设置MPU6050加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)
{
	return MPU_Write_Byte(MPU_ACCEL_CFG_REG, fsr << 3);//设置加速度传感器满量程范围  
}

//设置MPU6050的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_LPF(uint16_t lpf)
{
	uint8_t Data = 0;
	if (lpf >= 188)Data = 1;
	else if (lpf >= 98)Data = 2;
	else if (lpf >= 42)Data = 3;
	else if (lpf >= 20)Data = 4;
	else if (lpf >= 10)Data = 5;
	else Data = 6;
	return MPU_Write_Byte(MPU_CFG_REG, Data);//设置数字低通滤波器  
}

//设置MPU6050的采样率(假定Fs=1KHz)
//rate:4~1000(Hz)
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Rate(uint16_t rate)
{
	uint8_t Data;
	if (rate>1000)rate = 1000;
	if (rate<4)rate = 4;
	Data = 1000 / rate - 1;
	Data = MPU_Write_Byte(MPU_SAMPLE_RATE_REG, Data);	//设置数字低通滤波器
	return MPU_Set_LPF(rate / 2);	//自动设置LPF为采样率的一半
}

//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)
{
	uint8_t buf[2];
	short raw;
	float temp;
	MPU_Read_Len(MPU_TEMP_OUTH_REG, 2, buf);
	raw = ((uint16_t)buf[0] << 8) | buf[1];
	temp = 36.53 + ((double)raw) / 340;
	return temp * 100;;
}

//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Get_Gyroscope(short *gx, short *gy, short *gz)
{
	uint8_t buf[6], res;
	res = MPU_Read_Len(MPU_GYRO_XOUTH_REG, 6, buf);
	if (res == 0)
	{
		*gx = ((uint16_t)buf[0] << 8) | buf[1];
		*gy = ((uint16_t)buf[2] << 8) | buf[3];
		*gz = ((uint16_t)buf[4] << 8) | buf[5];
	}
	return res;;
}

//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Get_Accelerometer(short *ax, short *ay, short *az)
{
	uint8_t buf[6], res;
	res = MPU_Read_Len(MPU_ACCEL_XOUTH_REG, 6, buf);
	if (res == 0)
	{
		*ax = ((uint16_t)buf[0] << 8) | buf[1];
		*ay = ((uint16_t)buf[2] << 8) | buf[3];
		*az = ((uint16_t)buf[4] << 8) | buf[5];
	}
	return res;;
}

MPU6050.h
#ifndef __MPU6050_H
#define __MPU6050_H

#include "stdint.h"

//	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK NANO STM32F103开发板 
//MPU6050 驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2018/7/28
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 208-2028
//All rights reserved									  
//  

#define MPU_ACCEL_OFFS_REG		0x06	//accel_offs寄存器,可读取版本号,寄存器手册未提到
#define MPU_PROD_ID_REG			0x0C	//prod id寄存器,在寄存器手册未提到
#define MPU_SELF_TESTX_REG		0x0D	//自检寄存器X
#define MPU_SELF_TESTY_REG		0x0E	//自检寄存器Y
#define MPU_SELF_TESTZ_REG		0x0F	//自检寄存器Z
#define MPU_SELF_TESTA_REG		0x10	//自检寄存器A
#define MPU_SAMPLE_RATE_REG		0x19	//采样频率分频器
#define MPU_CFG_REG				0x1A	//配置寄存器
#define MPU_GYRO_CFG_REG		0x1B	//陀螺仪配置寄存器
#define MPU_ACCEL_CFG_REG		0x1C	//加速度计配置寄存器
#define MPU_MOTION_DET_REG		0x1F	//运动检测阀值设置寄存器
#define MPU_FIFO_EN_REG			0x23	//FIFO使能寄存器
#define MPU_I2CMST_CTRL_REG		0x24	//IIC主机控制寄存器
#define MPU_I2CSLV0_ADDR_REG	0x25	//IIC从机0器件地址寄存器
#define MPU_I2CSLV0_REG			0x26	//IIC从机0数据地址寄存器
#define MPU_I2CSLV0_CTRL_REG	0x27	//IIC从机0控制寄存器
#define MPU_I2CSLV1_ADDR_REG	0x28	//IIC从机1器件地址寄存器
#define MPU_I2CSLV1_REG			0x29	//IIC从机1数据地址寄存器
#define MPU_I2CSLV1_CTRL_REG	0x2A	//IIC从机1控制寄存器
#define MPU_I2CSLV2_ADDR_REG	0x2B	//IIC从机2器件地址寄存器
#define MPU_I2CSLV2_REG			0x2C	//IIC从机2数据地址寄存器
#define MPU_I2CSLV2_CTRL_REG	0x2D	//IIC从机2控制寄存器
#define MPU_I2CSLV3_ADDR_REG	0x2E	//IIC从机3器件地址寄存器
#define MPU_I2CSLV3_REG			0x2F	//IIC从机3数据地址寄存器
#define MPU_I2CSLV3_CTRL_REG	0x30	//IIC从机3控制寄存器
#define MPU_I2CSLV4_ADDR_REG	0x31	//IIC从机4器件地址寄存器
#define MPU_I2CSLV4_REG			0x32	//IIC从机4数据地址寄存器
#define MPU_I2CSLV4_DO_REG		0x33	//IIC从机4写数据寄存器
#define MPU_I2CSLV4_CTRL_REG	0x34	//IIC从机4控制寄存器
#define MPU_I2CSLV4_DI_REG		0x35	//IIC从机4读数据寄存器

#define MPU_I2CMST_STA_REG		0x36	//IIC主机状态寄存器
#define MPU_INTBP_CFG_REG		0x37	//中断/旁路设置寄存器
#define MPU_INT_EN_REG			0x38	//中断使能寄存器
#define MPU_INT_STA_REG			0x3A	//中断状态寄存器

#define MPU_ACCEL_XOUTH_REG		0x3B	//加速度值,X轴高8位寄存器
#define MPU_ACCEL_XOUTL_REG		0x3C	//加速度值,X轴低8位寄存器
#define MPU_ACCEL_YOUTH_REG		0x3D	//加速度值,Y轴高8位寄存器
#define MPU_ACCEL_YOUTL_REG		0x3E	//加速度值,Y轴低8位寄存器
#define MPU_ACCEL_ZOUTH_REG		0x3F	//加速度值,Z轴高8位寄存器
#define MPU_ACCEL_ZOUTL_REG		0x40	//加速度值,Z轴低8位寄存器

#define MPU_TEMP_OUTH_REG		0x41	//温度值高八位寄存器
#define MPU_TEMP_OUTL_REG		0x42	//温度值低8位寄存器

#define MPU_GYRO_XOUTH_REG		0x43	//陀螺仪值,X轴高8位寄存器
#define MPU_GYRO_XOUTL_REG		0x44	//陀螺仪值,X轴低8位寄存器
#define MPU_GYRO_YOUTH_REG		0x45	//陀螺仪值,Y轴高8位寄存器
#define MPU_GYRO_YOUTL_REG		0x46	//陀螺仪值,Y轴低8位寄存器
#define MPU_GYRO_ZOUTH_REG		0x47	//陀螺仪值,Z轴高8位寄存器
#define MPU_GYRO_ZOUTL_REG		0x48	//陀螺仪值,Z轴低8位寄存器

#define MPU_I2CSLV0_DO_REG		0x63	//IIC从机0数据寄存器
#define MPU_I2CSLV1_DO_REG		0x64	//IIC从机1数据寄存器
#define MPU_I2CSLV2_DO_REG		0x65	//IIC从机2数据寄存器
#define MPU_I2CSLV3_DO_REG		0x66	//IIC从机3数据寄存器

#define MPU_I2CMST_DELAY_REG	0x67	//IIC主机延时管理寄存器
#define MPU_SIGPATH_RST_REG		0x68	//信号通道复位寄存器
#define MPU_MDETECT_CTRL_REG	0x69	//运动检测控制寄存器
#define MPU_USER_CTRL_REG		0x6A	//用户控制寄存器
#define MPU_PWR_MGMT1_REG		0x6B	//电源管理寄存器1
#define MPU_PWR_MGMT2_REG		0x6C	//电源管理寄存器2 
#define MPU_FIFO_CNTH_REG		0x72	//FIFO计数寄存器高八位
#define MPU_FIFO_CNTL_REG		0x73	//FIFO计数寄存器低八位
#define MPU_FIFO_RW_REG			0x74	//FIFO读写寄存器
#define MPU_DEVICE_ID_REG		0x75	//器件ID寄存器

//如果AD0脚(9脚)接地,IIC地址为0x68(不包含最低位).
//如果接V3.3,则IIC地址为0x69(不包含最低位).
#define MPU_ADDR				0x68	//此为7位地址

//因为模块AD0默认接GND,所以转为读写地址后,为0xD1和0xD0(如果接VCC,则为0xD3和0xD2)  
#define MPU_READ    0xD1
#define MPU_WRITE   0xD0

uint8_t MPU_Init(void); 													//初始化MPU6050
uint8_t MPU_Read_Len(uint8_t reg, uint8_t len, uint8_t *buf);				//IIC连续读 
uint8_t MPU_Write_Len(uint8_t reg, uint8_t len, uint8_t *buf);				//IIC连续写
uint8_t MPU_Write_Byte(uint8_t reg, uint8_t Data);							//IIC写一个字节
uint8_t MPU_Read_Byte(uint8_t reg);											//IIC读一个字节
uint8_t MPU_Write_Bit(uint8_t addr, uint8_t bitNum, uint8_t Data);			//写入8位寄存器的一个位
uint8_t MPU_Write_Bits(uint8_t addr, uint8_t bitStart, uint8_t length, uint8_t Data);//写入8位寄存器的多个位
uint8_t MPU_Read_Bit(uint8_t addr, uint8_t bitNum, uint8_t *Data);			//读取一个位从8位器件的寄存器
uint8_t MPU_Read_Bits(uint8_t addr, uint8_t bitStart, uint8_t length, uint8_t *Data);//读取8位寄存器的多个位

uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr);
uint8_t MPU_Set_Accel_Fsr(uint8_t fsr);
uint8_t MPU_Set_LPF(uint16_t lpf);
uint8_t MPU_Set_Rate(uint16_t rate);

int16_t MPU_Get_Temperature(void);
uint8_t MPU_Get_Gyroscope(int16_t *gx, int16_t *gy, int16_t *gz);
uint8_t MPU_Get_Accelerometer(int16_t *ax, int16_t *ay, int16_t *az);

#define MPU_Refresh() MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0x00)	//唤醒MPU6050 

void MPU_Delay_Ms(uint16_t Milliseconds);						//移植时需修改

#endif

main.c
#include 
#include "intrins.h"
#include "stdint.h"
#include "USART.h"
#include "./MPU6050/MPU6050.h"

void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void Delay_ms(int i)
{
	while(i--)
		Delay1ms();
}

void main(void)
{
	int16_t aacx,aacy,aacz;		//加速度传感器原始数据
	int16_t gyrox,gyroy,gyroz;	//陀螺仪原始数据
	int16_t temp;				//温度

	USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 11059200, 57600, DOUBLE_BAUD_ENABLE, USART_TIMER_1);
	MPU_Init(); 

	while(1)
	{	
		temp = MPU_Get_Temperature();				//得到温度值
		MPU_Get_Accelerometer(&aacx, &aacy, &aacz);	//得到加速度传感器数据
		MPU_Get_Gyroscope(&gyrox, &gyroy, &gyroz);	//得到陀螺仪数据
		printf("%d, %d, %d, %d, %d, %d, %drn", aacx,aacy,aacz,gyrox,gyroy,gyroz,temp);
	}
}

实验现象


轻轻转动陀螺仪,可见数据随之变化。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/588429.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号