修改书《嵌入式Linux系统设计及应用-基于国产龙芯SOCV2.3.0》中IIC的例子,获取MPU6050的数据。

1.连线方式,MPU6050的AD0连接GND,SDA连接P00,SCL连接P01。

             智龙V3 获取MPU6050原始数据(iic驱动)

2.注册新设备。使用i2c_new _device方法。文件保存为mpu6050_dev.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <loongson1.h>
#include <linux/slab.h>


static struct i2c_board_info mpu6050_info = {    
    I2C_BOARD_INFO("mpu6050",0x68),
};

static struct i2c_client *mpu6050_client;

static int mpu6050_dev_init(void)
{
    struct i2c_adapter *i2c_adap;
    //打开第2复用gpio00,01,必须做
    __raw_writel(readl(LS1X_CBUS_SECOND0) | 1 ,LS1X_CBUS_SECOND0);
    __raw_writel(readl(LS1X_CBUS_SECOND0) |( 1 << 1 ) ,LS1X_CBUS_SECOND0);
        //使用i2c-0设备
    i2c_adap = i2c_get_adapter(0);
    mpu6050_client = i2c_new_device(i2c_adap, &mpu6050_info);
    i2c_put_adapter(i2c_adap);
    
    return 0;
}

static void mpu6050_dev_exit(void)
{
    i2c_unregister_device(mpu6050_client);
}


module_init(mpu6050_dev_init);
module_exit(mpu6050_dev_exit);
MODULE_LICENSE("GPL");

 i2c-*设备通过iic工具查询。

智龙V3 获取MPU6050原始数据(iic驱动)

 3.注册新驱动。文件保存为mpu6050_drv.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/err.h>
//#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <asm/uaccess.h>


static int major;
static struct class *class;
static struct i2c_client *mpu6050_client;

/* 传入: buf[0] : addr
 * 输出: buf[0] : data
 */
static ssize_t mpu6050_read(struct file * file, char __user *buf, size_t count, loff_t *off)
{
    unsigned char addr, data;
    
    copy_from_user(&addr, buf, 1);
    data = i2c_smbus_read_byte_data(mpu6050_client, addr);
    copy_to_user(buf, &data, 1);
    return 1;
}

/* buf[0] : addr
 * buf[1] : data
 */
static ssize_t mpu6050_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
    unsigned char ker_buf[2];
    unsigned char addr, data;

    copy_from_user(ker_buf, buf, 2);
    addr = ker_buf[0];
    data = ker_buf[1];

    printk("addr = 0x%02x, data = 0x%02x\n", addr, data);

    if (!i2c_smbus_write_byte_data(mpu6050_client, addr, data))
        return 2;
    else
        return -EIO;    
}

static struct file_operations mpu6050_fops = {
    .owner = THIS_MODULE,
    .read  = mpu6050_read,
    .write = mpu6050_write,
};

static int __devinit mpu6050_probe(struct i2c_client *client,
                  const struct i2c_device_id *id)
{
    mpu6050_client = client;
        
    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    major = register_chrdev(0, "mpu6050", &mpu6050_fops);
    class = class_create(THIS_MODULE, "mpu6050");
    device_create(class, NULL, MKDEV(major, 0), NULL, "mpu6050"); /* /dev/at24cxx */
    
    return 0;
}

static int __devexit mpu6050_remove(struct i2c_client *client)
{
    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    device_destroy(class, MKDEV(major, 0));
    class_destroy(class);
    unregister_chrdev(major, "mpu6050");
        
    return 0;
}

static const struct i2c_device_id mpu6050_id_table[] = {
    { "mpu6050", 0 },
    {}
};


/* 1. 分配/设置i2c_driver */
static struct i2c_driver mpu6050_driver = {
    .driver    = {
        .name    = "mpu6050",
        .owner    = THIS_MODULE,
    },
    .probe        = mpu6050_probe,
    .remove        = __devexit_p(mpu6050_remove),
    .id_table    = mpu6050_id_table,
};

static int mpu6050_drv_init(void)
{
    /* 2. 注册i2c_driver */
    i2c_add_driver(&mpu6050_driver);
    
    return 0;
}

static void mpu6050_drv_exit(void)
{
    i2c_del_driver(&mpu6050_driver);
}


module_init(mpu6050_drv_init);
module_exit(mpu6050_drv_exit);
MODULE_LICENSE("GPL");

 3.makefile文件。分别编译mpu6050_dev.c和mpu6050_drv.c,得到.ko文件。

KERN_DIR = /home/podu/Desktop/linux-3.0.101pwm/linux-3.0.101

all:
    make -C $(KERN_DIR) M=`pwd` modules ARCH=mips CROSS_COMPILE=mipsel-linux-

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

#obj-m    += mpu6050_dev.o
obj-m    += mpu6050_drv.o
 

智龙V3 获取MPU6050原始数据(iic驱动)

4.获取mpu6050数据。文件保存为mpu6050.c,编译得到mpu6050。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#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_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_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_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 
void transfer(char *val,char *val2){

     *val = (*val << 8) | (*val2);

}

int main(int argc, char **argv)
{
    int rx,ry,rz,ax,ay,az,rxl,ryl,rzl,axl,ayl,azl;
    int fd,res1,res2;
    int a,b,c;
    char x1,x2;
    char buf[2],buf2[1],buf3[6];
    fd = open("/dev/mpu6050", O_RDWR);
    if (fd < 0)
    {
        printf("can't open /dev/mpu6050\n");
        return -1;
    }
    buf[0]=MPU_PWR_MGMT1_REG;
    buf[1]=0x80;
    write(fd,buf,2);
    sleep(1);

    buf[0]=MPU_PWR_MGMT1_REG;
    buf[1]=0x40;
    write(fd,buf,2);
    sleep(1);

    buf[0]=MPU_PWR_MGMT1_REG;
    buf[1]=0x00;
    write(fd,buf,2);  

    buf[0]=MPU_SAMPLE_RATE_REG;
    buf[1]=0x7;
    write(fd,buf,2); 

    buf[0]=MPU_CFG_REG;
    buf[1]=0x6;
    write(fd,buf,2); 

    buf[0]=MPU_GYRO_CFG_REG;
    buf[1]=(0X03<<3);
    write(fd,buf,2);  

    buf[0]=MPU_ACCEL_CFG_REG;
    buf[1]=(0X00<<3);
    write(fd,buf,2);  

    buf[0]=MPU_PWR_MGMT1_REG;
    buf[1]=0X01;
    write(fd,buf,2); 
   
    buf[0]=MPU_PWR_MGMT2_REG;
    buf[1]=0X00;
    write(fd,buf,2); 

    while(1){
    buf[0]=MPU_ACCEL_XOUTH_REG;
    read(fd,buf,2);
    x1=buf[0];
    rx=((int)buf[0]<<8) | (int)buf[1];
    //transfer(&rx);
    printf("rx=%.2f  rxh=%d  rxl=%d  ",rx/16384.0,buf[0],buf[1]);

    buf[0]=MPU_ACCEL_ZOUTL_REG;
    read(fd,buf,1);
    x2=buf[0];
    printf("xx=%d  xx2=%.2f xx3=%d\n",((int)x1<<8) | (int)x2,(((int)x1<<8) | (int)x2)/16364.0,x2);

    buf[0]=MPU_ACCEL_YOUTH_REG;
    read(fd,buf,2);
    ry=((int)buf[0]<<8) | (int)buf[1];
    printf("ry=%.2f  ",ry/16384.0);

    buf[0]=MPU_ACCEL_ZOUTH_REG;
    read(fd,buf,2);
    rz=((int)buf[0]<<8) | (int)buf[1];
    printf("rz=%.2f\n",rz/16384.0);

    buf[0]=MPU_GYRO_XOUTH_REG;
    read(fd,buf,2);
    ax=((int)buf[0]<<8)|buf[1];
    //transfer(&rx);
    printf("ax=%.2f  ",ax/16384.0);

    buf[0]=MPU_GYRO_YOUTH_REG;
    read(fd,buf,2);
    ay=((int)buf[0]<<8)|buf[1];
    printf("ay=%.2f  ",ay/16384.0);

    buf[0]=MPU_GYRO_ZOUTH_REG;
    read(fd,buf,2);
    az=((int)buf[0]<<8)|buf[1];
    printf("az=%.2f\n",az/16384.0);

}


    return 0;
}

6.把mpu6050_dev.ko,mpu6050_drv.ko,mpu6050传输到智龙v3开发板上,先加载.ko文件,后运行程序mpu6050。大功告成。

智龙V3 获取MPU6050原始数据(iic驱动)

智龙V3 获取MPU6050原始数据(iic驱动)

源码:https://download.csdn.net/download/qq_25537607/12341357

 

 

 

相关文章: