zoukankan      html  css  js  c++  java
  • 代码示例_陀螺仪_I2C

    陀螺仪_I2C


    mpu6500_i2c_drv.mod.c

      1 #include <linux/init.h>
      2 #include <linux/module.h>
      3 #include <linux/fs.h>
      4 #include <linux/device.h>
      5 #include <linux/slab.h>
      6 #include <linux/gpio.h>
      7 #include <linux/i2c.h>
      8 #include <linux/mod_devicetable.h>
      9 
     10 #include <asm/io.h>
     11 #include <asm/uaccess.h>
     12 
     13 #include <linux/kobject.h>
     14 #include <linux/kdev_t.h>
     15 #include <linux/list.h>
     16 
     17 #include <linux/cdev.h>
     18 #include <linux/interrupt.h>
     19 #include <linux/input.h>
     20 #include <linux/sched.h>
     21 
     22 #include <asm/string.h>
     23 #include <asm-generic/ioctl.h>
     24 
     25 
     26 #define MPU6500_MAGIC 'K'
     27 
     28 union mpu6500_data
     29 {
     30     struct {
     31         short x;
     32         short y;
     33         short z;
     34     }accel;
     35     struct {
     36         short x;
     37         short y;
     38         short z;
     39     }gyro;
     40     unsigned short temp;
     41 };
     42 
     43 
     44 
     45 #define GET_ACCEL _IOR(MPU6500_MAGIC, 0, union mpu6500_data)
     46 #define GET_GYRO  _IOR(MPU6500_MAGIC, 1, union mpu6500_data) 
     47 #define GET_TEMP  _IOR(MPU6500_MAGIC, 2, union mpu6500_data)
     48 
     49 
     50 
     51 #define SMPLRT_DIV          0x19    //陀螺仪采样率,典型值:0x07(125Hz)
     52 #define CONFIG              0x1A    //低通滤波频率,典型值:0x06(5Hz)
     53 #define GYRO_CONFIG         0x1B    //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
     54 #define ACCEL_CONFIG        0x1C    //加速计自检、测量范围及高通滤波,典型值:0x18(不自检,2G,5Hz)
     55 
     56 
     57 
     58 //    注册59到64 -加速度计测量值
     59 #define ACCEL_XOUT_H        0x3B    //加速度计x轴数据的高字节
     60 #define ACCEL_XOUT_L        0x3C    //加速度计x轴数据的低字节
     61 #define ACCEL_YOUT_H        0x3D    //加速度计y轴数据的高字节
     62 #define ACCEL_YOUT_L        0x3E    //加速度计y轴数据的低字节
     63 #define ACCEL_ZOUT_H        0x3F    //加速度计z轴数据的高字节
     64 #define ACCEL_ZOUT_L        0x40    //加速度计z轴数据的低字节
     65 
     66 
     67 //    寄存器65和66 -温度测量
     68 #define TEMP_OUT_H      0x41        //温度传感器输出的高字节
     69 #define TEMP_OUT_L      0x42        //温度传感器输出的低字节
     70 
     71 
     72 //    注册67至72 -陀螺仪测量
     73 #define GYRO_XOUT_H     0x43        //高字节的x轴陀螺仪输出
     74 #define GYRO_XOUT_L     0x44        //低字节的x轴陀螺仪输出
     75 #define GYRO_YOUT_H     0x45        //高字节的y轴陀螺仪输出
     76 #define GYRO_YOUT_L     0x46        //低字节的y轴陀螺仪输出
     77 #define GYRO_ZOUT_H     0x47        //高字节的z轴陀螺仪输出
     78 #define GYRO_ZOUT_L     0x48        //低字节的z轴陀螺仪输出
     79 
     80 
     81 #define PWR_MGMT_1      0x6B      //电源管理,典型值:0x00(正常启用)
     82 #define WHO_AM_I        0x75      //IIC地址寄存器(默认数值0x68,只读)
     83 #define SlaveAddress    0x68      //MPU6050-I2C地址寄存器
     84 
     85 
     86 
     87 
     88 #define W_FLG           0
     89 #define R_FLG           1
     90 
     91 
     92 #define DEV_CNT 1
     93 #define DEV_MI 0
     94 #define DEV_MAME "mpu6500"
     95 
     96 
     97 struct class *cls;
     98 dev_t dev_no ;
     99 
    100 static struct i2c_client *i2c_test_client = NULL; 
    101 
    102 struct mpu6500_pri {
    103     struct cdev dev;
    104     struct i2c_client *client;
    105 };
    106 
    107 struct mpu6500_pri dev;
    108 
    109 
    110 
    111 static void mpu6500_write_byte(struct i2c_client *client,const unsigned char reg,const unsigned char val)
    112 { 
    113     char txbuf[2] = {reg,val};
    114     struct i2c_msg msg[2] = {
    115         [0] = {
    116             .addr = client->addr,
    117             .flags= W_FLG,
    118             .len = sizeof(txbuf),
    119             .buf = txbuf,
    120         },
    121     };
    122     i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
    123 }
    124 
    125 
    126 static char mpu6500_read_byte(struct i2c_client *client,const unsigned char reg)
    127 {
    128     char txbuf[1] = {reg};
    129     char rxbuf[1] = {0};
    130     struct i2c_msg msg[2] = {
    131         [0] = {
    132             .addr = client->addr,
    133             .flags = W_FLG,
    134             .len = sizeof(txbuf),
    135             .buf = txbuf,
    136         },
    137         [1] = {
    138             .addr = client->addr,
    139             .flags = R_FLG,
    140             .len = sizeof(rxbuf),
    141             .buf = rxbuf,
    142         },
    143     };
    144 
    145     i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
    146     return rxbuf[0];
    147 }
    148 
    149 
    150 static int dev_open(struct inode *ip, struct file *fp)
    151 {
    152     printk("kernel  open  success ! 
    ");
    153     
    154     return 0;
    155 }
    156 
    157 
    158 
    159 static long dev_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
    160 {
    161     
    162     printk("kernel  ioctl  success ! 
    ");
    163     
    164     int res = 0;
    165     union mpu6500_data data = {{0}};
    166     switch(cmd){
    167     case GET_ACCEL:
    168         data.accel.x = mpu6500_read_byte(dev.client,ACCEL_XOUT_L);
    169         data.accel.x|= mpu6500_read_byte(dev.client,ACCEL_XOUT_H)<<8;
    170         data.accel.y = mpu6500_read_byte(dev.client,ACCEL_YOUT_L);
    171         data.accel.y|= mpu6500_read_byte(dev.client,ACCEL_YOUT_H)<<8;
    172         data.accel.z = mpu6500_read_byte(dev.client,ACCEL_ZOUT_L);
    173         data.accel.z|= mpu6500_read_byte(dev.client,ACCEL_ZOUT_H)<<8;
    174         break;
    175     case GET_GYRO:
    176         data.gyro.x = mpu6500_read_byte(dev.client,GYRO_XOUT_L);
    177         data.gyro.x|= mpu6500_read_byte(dev.client,GYRO_XOUT_H)<<8;
    178         data.gyro.y = mpu6500_read_byte(dev.client,GYRO_YOUT_L);
    179         data.gyro.y|= mpu6500_read_byte(dev.client,GYRO_YOUT_H)<<8;
    180         data.gyro.z = mpu6500_read_byte(dev.client,GYRO_ZOUT_L);
    181         data.gyro.z|= mpu6500_read_byte(dev.client,GYRO_ZOUT_H)<<8;
    182         printk("gyro:x %d, y:%d, z:%d
    ",data.gyro.x,data.gyro.y,data.gyro.z);
    183         break;
    184     case GET_TEMP:
    185         data.temp = mpu6500_read_byte(dev.client,TEMP_OUT_L);
    186         data.temp|= mpu6500_read_byte(dev.client,TEMP_OUT_H)<<8;
    187         printk("temp: %d
    ",data.temp);
    188         break;
    189     default:
    190         printk(KERN_INFO "invalid cmd");
    191         break;
    192     }
    193     printk("acc:x %d, y:%d, z:%d
    ",data.accel.x,data.accel.y,data.accel.z);
    194     res = copy_to_user((void *)arg,&data,sizeof(data));
    195     return sizeof(data);
    196 }
    197 
    198 
    199 
    200 static int dev_release(struct inode *ip, struct file *fp)
    201 {
    202     
    203     printk("kernel  close  success ! 
    ");
    204     
    205     return 0;
    206 }
    207 
    208 
    209 
    210 struct file_operations fops = {
    211     .open = dev_open,
    212     .release = dev_release,
    213     .unlocked_ioctl = dev_ioctl, 
    214 };
    215 
    216 
    217 
    218 
    219 static void mpu6500_init(struct i2c_client *client)
    220 {
    221     
    222     printk("kernel  mpu6500_init  success ! 
    ");
    223     
    224     mpu6500_write_byte(client, PWR_MGMT_1, 0x00);   //电源管理,解除休眠
    225     mpu6500_write_byte(client, SMPLRT_DIV, 0x07);    //设置陀螺仪采样率
    226     mpu6500_write_byte(client, CONFIG, 0x06);        //设置低通滤波频率
    227     mpu6500_write_byte(client, GYRO_CONFIG, 0x18);    //设置陀螺仪自检
    228     mpu6500_write_byte(client, ACCEL_CONFIG, 0x0);    //设置加速计自检
    229     
    230 }
    231 
    232 
    233 
    234 
    235 static int mpu6500_probe(struct i2c_client * client, const struct i2c_device_id * id)
    236 {
    237     
    238     printk("kernel  mpu6500_probe  success ! 
    ");
    239     
    240     dev.client = client;    // 保存当前的client信息
    241     
    242     printk(KERN_INFO "mpu6500  match  ok
    ");
    243     
    244     cdev_init(&dev.dev,&fops);
    245     
    246     alloc_chrdev_region(&dev_no,DEV_MI,DEV_CNT,DEV_MAME);
    247     
    248     cdev_add(&dev.dev,dev_no,DEV_CNT);
    249     
    250     mpu6500_init(client);
    251 
    252     /*自动创建设备文件*/
    253     cls = class_create(THIS_MODULE,DEV_MAME);
    254     device_create(cls,NULL,dev_no,NULL,"%s%d",DEV_MAME,DEV_MI);
    255     
    256     
    257     return 0;
    258 }
    259 
    260 
    261 
    262 static int mpu6500_remove(struct i2c_client * client)
    263 {
    264     
    265     printk("kernel  mpu6500_remove  success ! 
    ");
    266     
    267     device_destroy(cls,dev_no);
    268     class_destroy(cls);
    269     unregister_chrdev_region(dev_no,DEV_CNT);
    270     return 0;
    271 }
    272 
    273 
    274 
    275 struct i2c_device_id mpu6500_dev_match[] = {
    276     {"mpu6500", 0x1111},
    277     {},
    278 };
    279 
    280 
    281 struct i2c_driver mpu6500_drv = {
    282     .probe = mpu6500_probe,
    283     .remove = mpu6500_remove,
    284     .driver = {
    285         .owner = THIS_MODULE,
    286         .name = "mpu6500",
    287     },
    288     .id_table = mpu6500_dev_match,
    289 };
    290 
    291 
    292 static struct i2c_board_info i2c_test_info = {     
    293     I2C_BOARD_INFO("mpu6500", 0x68),  
    294 };
    295 
    296 
    297 static int __init mpu6500_drv_init(void)
    298 {
    299     
    300     printk("kernel  mpu6500_drv_init  success ! 
    ");
    301     
    302     
    303     //实例化 i2c_client
    304     static    struct i2c_adapter * i2c_adap = NULL;
    305     i2c_adap =    i2c_get_adapter(1);
    306     i2c_test_client = i2c_new_device(i2c_adap, &i2c_test_info);
    307     i2c_put_adapter(i2c_adap); 
    308         
    309         
    310     //注册一个i2c_driver
    311     return i2c_add_driver(&mpu6500_drv);
    312 }    
    313 
    314 
    315 static void __exit mpu6500_drv_exit(void)
    316 {
    317     
    318     printk("kernel  mpu6500_drv_exit  success ! 
    ");
    319     
    320     i2c_del_driver(&mpu6500_drv);
    321 }
    322 
    323 
    324 
    325 // 声明认证
    326 module_init(mpu6500_drv_init);
    327 module_exit(mpu6500_drv_exit);
    328 MODULE_LICENSE("GPL");

    mpu6500_i2c_app.cpp  (交叉编译)

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <unistd.h>
     5 #include <sys/types.h>
     6 #include <sys/stat.h>
     7 #include <sys/ioctl.h>
     8 #include <fcntl.h>
     9 
    10 
    11 #define MPU6500_MAGIC 'K'
    12 
    13 #define GET_ACCEL _IOR(MPU6500_MAGIC, 0, union mpu6500_data)
    14 #define GET_GYRO  _IOR(MPU6500_MAGIC, 1, union mpu6500_data) 
    15 #define GET_TEMP  _IOR(MPU6500_MAGIC, 2, union mpu6500_data)
    16 
    17 
    18 
    19 union mpu6500_data
    20 {
    21     struct {
    22         short x;
    23         short y;
    24         short z;
    25     }accel;
    26     struct {
    27         short x;
    28         short y;
    29         short z;
    30     }gyro;
    31     unsigned short temp;
    32 };
    33 
    34 
    35 int main(void)
    36 {
    37     int fd = open("/dev/mpu65000",O_RDWR);
    38     if(-1== fd){
    39         perror("open");
    40         return -1;
    41     }
    42     
    43     union mpu6500_data data = {{0}};
    44     
    45     while(1){
    46         ioctl(fd,GET_ACCEL,&data);
    47         printf("acc:x %d, y:%d, z:%d
    ",data.accel.x,data.accel.y,data.accel.z);
    48         ioctl(fd,GET_GYRO,&data);
    49         printf("gyro:x %d, y:%d, z:%d
    ",data.gyro.x,data.gyro.y,data.gyro.z);
    50         ioctl(fd,GET_TEMP,&data);
    51         printf("temp: %d
    ",data.temp);
    52         sleep(1);
    53     }
    54     return 0;
    55 }

    Android.mk

     1 # Copyright 2012 The Android Open Source Project
     2 
     3 LOCAL_PATH:= $(call my-dir)
     4 include $(CLEAR_VARS)
     5 
     6 LOCAL_SRC_FILES:= mpu6500_app.cpp
     7 
     8 LOCAL_C_INCLUDES += external/zlib
     9 
    10 LOCAL_MODULE:= mpu6500_app
    11 
    12 LOCAL_MODULE_TAGS:= optional
    13 
    14 LOCAL_SHARED_LIBRARIES := 
    15     libbinder 
    16     libcutils 
    17     libutils 
    18     libz 
    19 
    20 include $(BUILD_EXECUTABLE)

    测试:


    success !

    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the EditerInput
    React 综合事件 SyntheticEvent
    浏览器进程?线程?
    如何选择Redux的store和React的state?
    主流浏览器内核介绍(前端开发值得了解的浏览器内核历史)
    前端路由实现与 react-router 源码分析
    Sass Less SCSS 的抉择
    单行居中显示文字,多行居左显示,最多两行超过用省略号结尾
    link和@import的区别
    css选择符属性继承优先级算法以及css3新增伪类新特性
  • 原文地址:https://www.cnblogs.com/panda-w/p/11136939.html
Copyright © 2011-2022 走看看