代码示例_陀螺仪_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 待续。。。
原文地址:https://www.cnblogs.com/panda-w/p/11136939.html