Linux驱动开发-编写MMA7660三轴加速度传感器

【摘要】 通过mma7660可以做出很多项目: 比如: 老人防跌倒手环、自行车自动刹车灯,智能闹钟,烤火炉跌倒自动断电、运动手环等等。 这篇文章就介绍如何在linux下编写mma7660三轴加速度芯片的驱动,读取当前芯片的方向姿态,得到x,y,z三个轴的数据。mma7660是iic接口的,当前驱动就采用标准的iic子系统编写驱动,使用字符设备框架将得到的数据上传递给应用层。
1. mma7660芯片介绍 mma7660fc 是 ± 1.5 克的三轴数字输出、超低功率、紧凑型电容式微电机的三轴加速度计,是非常低功耗,小型容性 mems 的传感器。具有低通滤波器,用于偏移和增益误差补偿, 以及用户可配置的转换成 6 位分辨率,用户可配置输出速率等功能。mma7660芯片可以通过中断引脚(int)向外通知传感器数据变化、方向、姿态识别等信息。模拟工作电压范围是 2.4v 至 3.6v,数字工作电压范围是 1.71v 到 3.6v 。常用在手机、掌上电脑、车载导航,便携式电脑的防盗,自动自行车刹车灯、运动检测手环、数码机、自动叫醒闹钟里等等。
特别是计步的功能是现在最常见,不管是智能手环、还是手机都带有三轴加速度计,可以记录每天的步数,计算运动量等。现在很多的不倒翁,无人机、相机云台,很多常见的产品里都能看到三轴加速计的身影。
通过mma7660可以做出很多项目: 比如: 老人防跌倒手环、自行车自动刹车灯,智能闹钟,烤火炉跌倒自动断电、运动手环等等。
这篇文章就介绍如何在linux下编写mma7660三轴加速度芯片的驱动,读取当前芯片的方向姿态,得到x,y,z三个轴的数据。mma7660是iic接口的,当前驱动就采用标准的iic子系统编写驱动,使用字符设备框架将得到的数据上传递给应用层。
2. 硬件连线 当前使用的开发板是友善之臂tiny4412开发板,使用三星exynos4412芯片,板子本身自带了一颗mma7660芯片,芯片的原理图如下:
内核本身有mma7660的驱动,下面是源码的路径:
如果加载自己编写的驱动,还需要去掉原来内核自带的驱动,不然无法匹配。
device drivers ---> hardware monitoring support ---> freescale mma7660 accelerometer (将*号去掉,编译内核、烧写内核即可) 3. 源代码 3.1 mma7660设备端代码: iic子系统#include #include #include #include #include #include #include static struct i2c_client *i2cclient = null;static unsigned short i2c_addr_list[]= {0x4c, i2c_client_end};/*地址队列*//*1. 获取控制器(总线)2. 探测设备是否存在3. 定义一个名字用于找到驱动端 */static int __init mma7660_dev_init(void){ /*mach-tiny4412.c*/ struct i2c_adapter *i2c_adap=null; /*获取到的总线存放在这个结构体*/ struct i2c_board_info i2c_info; /*设备描述结构体,里面存放着设备的名字还有地址*/ /*1. 获取iic控制器*/ i2c_adap = i2c_get_adapter(3); /*要使用iic_3号总线*/ if(!i2c_adap) { printk(获取iic控制器信息失败!\n); return -1; } memset(&i2c_info,0,sizeof(struct i2c_board_info)); /*清空结构体*/ strlcpy(i2c_info.type,mma7660_drv,i2c_name_size); /*名称的赋值*/ i2c_info.irq=exynos4_gpx3(1); /*中断io口*/ /*2. 创建iic设备客户端*/ i2cclient = i2c_new_probed_device(i2c_adap,&i2c_info,i2c_addr_list,null); if(!i2cclient) { printk(mma7660_探测地址出现错误!!\n); return -1; } i2c_put_adapter(i2c_adap);/*设置模块使用计数*/ printk(mma7660_dev_init!!\n); return 0;}static void __exit mma7660_dev_exit(void)//平台设备端的出口函数{ printk( mma7660_dev_exit ok!!\n); /*注销设备*/ i2c_unregister_device(i2cclient); /*释放*/ i2c_release_client(i2cclient);}module_init(mma7660_dev_init);module_exit(mma7660_dev_exit);module_license(gpl); 3.2 mma7660驱动端代码: iic子系统#include #include #include #include #include #include #include #include #include #include #include /* mma7760 registers */#define mma7660_xout 0x00 // 6-bit output value x#define mma7660_yout 0x01 // 6-bit output value y#define mma7660_zout 0x02 // 6-bit output value z#define mma7660_tilt 0x03 // tilt status#define mma7660_srst 0x04 // sampling rate status#define mma7660_spcnt 0x05 // sleep count#define mma7660_intsu 0x06 // interrupt setup#define mma7660_mode 0x07 // mode#define mma7660_sr 0x08 // auto-wake/sleep and debounce filter#define mma7660_pdet 0x09 // tap detection#define mma7660_pd 0x0a // tap debounce countstatic const struct i2c_device_id mma7660_id[] ={ {mma7660_drv,0}, /*设备端的名字,0表示不需要私有数据*/ {}};static u32 mma7660_irq; /*触摸屏的中断编号*/static struct i2c_client *mma7660_client=null;static int last_tilt = 0;#define __need_retry(__v) (__v & (1 << 6))#define __is_negative(__v) (__v & (1 2) & 0x07; if (pola != ((last_tilt >> 2) & 0x07)) { printk(%s\n, mma7660_pola[pola]); } shake = (val >> 5) & 0x01; if (shake && shake != ((last_tilt >> 5) & 0x01)) { printk(shake\n); } tap = (val >> 7) & 0x01; if (tap && tap != ((last_tilt >> 7) & 0x01)) { printk(tap\n); } /* save current status */ last_tilt = val; int axis[3]; int i; for (i = 0; i dev, no device\n); return -enodev; } /* goto standby mode for configuration */ i2c_smbus_write_byte_data(client, mma7660_mode, 0x00); mdelay(10); /* sample rate: 64hz / 16hz; filt: 3 samples */ i2c_smbus_write_byte_data(client, mma7660_sr, ((2<<5) | (1irq);/*获取中断编号*/ if(request_irq(mma7660_irq,mma7660_interrupt,irqf_trigger_falling,mma7660_irq,null)!=0) { printk(mma7660_中断注册失败!\n); } /*2. 初始化mma7660*/ if(mma7660_initialize(client) < 0) { printk( 初始化mma7660失败!\n); } return 0;}static int mma7660_remove(struct i2c_client *client){ free_irq(mma7660_irq,null); printk(mma7660_remove!!!\n); return 0;}struct i2c_driver i2c_drv ={ .driver = { .name = mma7660, .owner = this_module, }, .probe = mma7660_probe, //探测函数 .remove = mma7660_remove, //资源卸载 .id_table = mma7660_id, //里面有一个名字的参数用来匹配设备端名字};static int __init mma7660_drv_init(void){ /*向iic总线注册一个驱动*/ i2c_add_driver(&i2c_drv); return 0;}static void __exit mma7660_drv_exit(void){ /*从iic总线注销一个驱动*/ i2c_del_driver(&i2c_drv);}module_init(mma7660_drv_init);module_exit(mma7660_drv_exit);module_license(gpl);
GGII预计2024快充大规模应用元年将至
BOSCH焊接控器手动焊钳控制的温度传感器连接故障分析
新能源汽车测试技术发展论坛召开,主要是关于动力电池的安全可靠性分析
现代 AI技术加持,修复巴黎圣母院并非难事
哈工大教授提出新型柔性触觉传感器阵列
Linux驱动开发-编写MMA7660三轴加速度传感器
富士康大陆裁员转移印度_市场转向东南亚?
5G随身WiFi不如二手旧手机?实测结果出乎意料
Littelfuse的≥2 kVHV分立硅MOSFET器件介绍
fireflyAndroid双屏异显简介
芯片设计之仿真工具
iphone8什么时候上市?iphone8最新消息:iphone8给我们带来的这个四大惊喜,我们必须要知道
非接触式传感器技术有哪些新进展
天马:OLED和mini-LED在车载上应用的趋势如何?
东莞市英联电子有限公司简介
便携式多普勒超声波明渠流量计的重要性及使用
直线模组如何进行精度校准?
三电平半桥拓扑采用移相控制存在的问题
6家PCB企业入选赣州龙头企业重点培育名单
2018年全球SSD模组厂出货量排名公布 第一名市占率竟高达25%