Files
TencentOS-tiny/board/ALPHA_I.MX_emmc_256ddr/bsp/mpu9250/bsp_mpu9250.c
daishengdong 3d9d6198c8 add cortex-v7a support
How To Run:
    see TencentOS-tiny\board\ALPHA_I.MX_emmc_256ddr\README.md

TODO Next:
1. VFP support
2. fault diagnosis support
3. qemu vexpress ca9 support
4. raspberry pi support
5. SMP support
2020-01-19 19:06:24 +08:00

237 lines
7.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名 : bsp_mpu9250.c
作者 : 左忠凯
版本 : V1.0
描述 : MPU9250驱动文件。
其他 : 无
论坛 : www.openedv.com
日志 : 初版V1.0 2019/1/15 左忠凯创建
***************************************************************/
#include "bsp_mpu9250.h"
#include "bsp_i2c.h"
#include "bsp_delay.h"
#include "printf.h"
/*
* @description : 初始化MPU9250
* @param : 无
* @return : 0 成功,其他值 错误代码
*/
unsigned char mpu9250_init(void)
{
unsigned char data = 0;
i2c_init(); /* 初始化IIC */
mpu_write_byte(MPU9250_ADDR,MPU_PWR_MGMT1_REG,0X80);//复位MPU9250
delayms(100); //延时100ms
mpu_write_byte(MPU9250_ADDR,MPU_PWR_MGMT1_REG,0X00);//唤醒MPU9250
mpu_set_gyro_range(3); //陀螺仪传感器,±2000dps
mpu_set_accel_range(0); //加速度传感器,±2g
mpu_set_rate(50); //设置采样率50Hz
mpu_write_byte(MPU9250_ADDR,MPU_INT_EN_REG,0X00); //关闭所有中断
mpu_write_byte(MPU9250_ADDR,MPU_USER_CTRL_REG,0X00);//I2C主模式关闭
mpu_write_byte(MPU9250_ADDR,MPU_FIFO_EN_REG,0X00); //关闭FIFO
mpu_write_byte(MPU9250_ADDR,MPU_INTBP_CFG_REG,0X82);//INT引脚低电平有效开启bypass模式可以直接读取磁力计
data = mpu_read_byte(MPU9250_ADDR,MPU_DEVICE_ID_REG);
if(data == MPU6500_ID)
{
printf("MPU9250 ID=%#X\r\n", data);
mpu_write_byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X01); /* 设置CLKSEL,PLL X轴为参考 */
mpu_write_byte(MPU9250_ADDR, MPU_PWR_MGMT2_REG, 0X00); /* 加速度与陀螺仪都工作 */
mpu_set_rate(50); /* 设置采样率为50Hz */
}
else {
return 1;
}
data = mpu_read_byte(AK8963_ADDR, MAG_WIA); /* 读取AK8963 ID */
if(data == AK8963_ID)
{
printf("AK8963_ID=%#X\r\n", data);
mpu_write_byte(AK8963_ADDR, MAG_CNTL1, 0X11); /* 设置AK8963为单次测量模式 */
}else return 2;
return 0;
}
/*
* @description : 向MPU9250写入数据
* @param - addr: 设备地址
* @param - reg : 要写入的寄存器
* @param - data: 要写入的数据
* @return : 操作结果
*/
unsigned char mpu_write_byte(unsigned char addr,unsigned char reg, unsigned char data)
{
unsigned char status=0;
unsigned char writedata=data;
struct i2c_transfer masterXfer;
/* 配置I2C xfer结构体 */
masterXfer.slaveAddress = addr; /* 设备地址 */
masterXfer.direction = kI2C_Write; /* 写入数据 */
masterXfer.subaddress = reg; /* 要写入的寄存器地址 */
masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
masterXfer.data = &writedata; /* 要写入的数据 */
masterXfer.dataSize = 1; /* 写入数据长度1个字节 */
if(i2c_master_transfer(&masterXfer))
status=1;
return status;
}
/*
* @description : 从MPU9250读取一个字节的数据
* @param - addr: 设备地址
* @param - reg : 要读取的寄存器
* @return : 读取到的数据。
*/
unsigned char mpu_read_byte(unsigned char addr,unsigned char reg)
{
unsigned char val=0;
struct i2c_transfer masterXfer;
masterXfer.slaveAddress = addr; /* 设备地址 */
masterXfer.direction = kI2C_Read; /* 读取数据 */
masterXfer.subaddress = reg; /* 要读取的寄存器地址 */
masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
masterXfer.data = &val; /* 接收数据缓冲区 */
masterXfer.dataSize = 1; /* 读取数据长度1个字节 */
i2c_master_transfer(&masterXfer);
return val;
}
/*
* @description : 从MPU9250读取多个字节的数据
* @param - addr: 设备地址
* @param - reg : 要读取的开始寄存器地址
* @param - len : 要读取的数据长度.
* @param - buf : 读取到的数据缓冲区
* @return : 无
*/
void mpu_read_len(unsigned char addr,unsigned char reg,unsigned char len,unsigned char *buf)
{
struct i2c_transfer masterXfer;
masterXfer.slaveAddress = addr; /* 设备地址 */
masterXfer.direction = kI2C_Read; /* 读取数据 */
masterXfer.subaddress = reg; /* 要读取的寄存器地址 */
masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
masterXfer.data = buf; /* 接收数据缓冲区 */
masterXfer.dataSize = len; /* 读取数据长度1个字节 */
i2c_master_transfer(&masterXfer);
}
/*
* @description : 设置MPU9250陀螺仪量程
* @param - range : 量程范围,0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
* @return : 操作结果 0,设置成功 其他,设置失败
*/
unsigned char mpu_set_gyro_range(unsigned char range)
{
return mpu_write_byte(MPU9250_ADDR, MPU_GYRO_CFG_REG, range << 3);//设置陀螺仪满量程范围
}
/*
* @description : 设置MPU9250加速度量程
* @param - range : 量程范围,0,±2g;1,±4g;2,±8g;3,±16g
* @return : 操作结果 0,设置成功 其他,设置失败
*/
unsigned char mpu_set_accel_range(unsigned char range)
{
return mpu_write_byte(MPU9250_ADDR, MPU_ACCEL_CFG_REG,range << 3);//设置加速度传感器满量程范围
}
/*
* @description : 设置MPU9250的数字低通滤波器
* @param - range : 数字低通滤波频率(Hz)
* @return : 操作结果 0,设置成功 其他,设置失败
*/
unsigned char mpu_set_lpf(unsigned short fre)
{
unsigned char data = 0;
if(fre >= 188) data=1;
else if(fre >= 98) data=2;
else if(fre >= 42) data=3;
else if(fre >= 20) data=4;
else if(fre >= 10) data=5;
else data = 6;
return mpu_write_byte(MPU9250_ADDR,MPU_CFG_REG,data);
}
/*
* @description : 设置MPU9250采样率(假定Fs=1KHz)
* @param - rate: 4~1000(Hz)
* @return : 操作结果 0,设置成功 其他,设置失败
*/
unsigned char mpu_set_rate(unsigned short rate)
{
unsigned char data;
if(rate > 1000) rate = 1000;
if(rate < 4) rate = 4;
data = 1000 / rate - 1;
data = mpu_write_byte(MPU9250_ADDR,MPU_SAMPLE_RATE_REG,data); /* 设置数字低通滤波器 */
return mpu_set_lpf(rate / 2); /* 自动设置LPF为采样率的一半 */
}
/*
* @description : 得到陀螺仪值(原始值)
* @param - gx : 陀螺仪X轴原始数据
* @param - gy : 陀螺仪Y轴原始数据
* @param - gz 陀螺仪Z轴原始数据
* @return : 0,设置成功 其他,设置失败
*/
void mpu_get_gyroscope(short *gx,short *gy,short *gz)
{
unsigned char buf[6];
mpu_read_len(MPU9250_ADDR, MPU_GYRO_XOUTH_REG, 6, buf);
*gx=((short)buf[0] << 8) | buf[1];
*gy=((short)buf[2] << 8) | buf[3];
*gz=((short)buf[4] << 8) | buf[5];
}
/*
* @description : 得到加速度原始值
* @param - ax : 加速度X轴原始数据
* @param - ay : 加速度Y轴原始数据
* @param - az 加速度Z轴原始数据
* @return : 0,设置成功 其他,设置失败
*/
void mpu_get_accelerometer(short *ax,short *ay,short *az)
{
unsigned char buf[6];
mpu_read_len(MPU9250_ADDR, MPU_ACCEL_XOUTH_REG, 6, buf);
*ax=((short)buf[0] << 8) | buf[1];
*ay=((short)buf[2] << 8) | buf[3];
*az=((short)buf[4] << 8) | buf[5];
}
/*
* @description : 得到原始磁力计值
* @param - mx : 磁力计X轴原始数据
* @param - my : 磁力计Y轴原始数据
* @param - mz 磁力计Z轴原始数据
* @return : 0,设置成功 其他,设置失败
*/
void mpu_get_magnetometer(short *mx, short *my, short *mz)
{
unsigned char buf[6];
mpu_read_len(AK8963_ADDR, MAG_XOUT_L , 6, buf);
*mx = ((short)buf[1] << 8) | buf[0];
*my = ((short)buf[3] << 8) | buf[2];
*mz = ((short)buf[5] << 8) | buf[4];
mpu_write_byte(AK8963_ADDR, MAG_CNTL1, 0X11); /* AK8963每次读完以后都需要重新设置为单次测量模式 */
}