linux下i2c通用接口读取和处理mag3110地磁传感器程序
来源:互联网 发布:cad线切割编程软件 编辑:程序博客网 时间:2024/06/07 23:16
/*mag3110是freescale公司的一个三轴地磁传感器模块,
可以感知地球磁场,通过算法处理得知地磁指向。*/
/*一个.c文件,没有分文件,不要在意这些细节,
包括了读取和数据处理得过程
用到反正切函数atan(),编译时加入-lm*/
/** I2C testing utility*/#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <math.h>#include <linux/fs.h>#include <sys/ioctl.h>#include <assert.h>#include <linux/i2c-dev.h>#include <linux/i2c.h>#define I2C_DEV"/dev/i2c-1"#define CHIP_ADDR0x0e#define DR_STATUS 0X00#define XYZ_DATA 0X01//x,y,z DATA register#define WHO_AM_I 0X07//x,y,z check register#define CTRL_REG 0X16int MAG3110_XOFF=0,MAG3110_YOFF=0;int MAG3110_XMax,MAG3110_YMax,MAG3110_XMin,MAG3110_YMin;int ang;int i2c_read_byte(int *fd, __u16 mem_addr);int i2c_write_byte(int *fd, __u16 mem_addr, __u8 data);/*************************************************************************/static int read_data_from_mag3110(int *fd,short *x,short *y,short *z){int i;char tmp_data[6] ="";printf(".>>>%d..\n",i2c_read_byte(fd, DR_STATUS));if(i2c_read_byte(fd, DR_STATUS) & 0x08)//一次数据转换完成{printf(",,enter well done\n");for(i = 0;i<6;i++){tmp_data[i] = i2c_read_byte(fd, XYZ_DATA+i);}*x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];*y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];*z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];return 1;}return 0;}int mag3110_adjust_position(short *data_x,short *data_y,short *data_z){static first_flag = 1;if (first_flag){MAG3110_XMax = *data_x;MAG3110_XMin = *data_x;MAG3110_YMax = *data_y;MAG3110_YMin = *data_y;first_flag = 0;}if (*data_x > MAG3110_XMax){MAG3110_XMax = *data_x;}else if (*data_x < MAG3110_XMin){MAG3110_XMin = *data_x;}if (*data_y > MAG3110_YMax){MAG3110_YMax = *data_y;}else if (*data_y < MAG3110_YMin){MAG3110_YMin = *data_y;}MAG3110_XOFF = (MAG3110_XMax + MAG3110_XMin) / 2;MAG3110_YOFF = (MAG3110_YMax + MAG3110_YMin) / 2;puts("**********************************\n");puts("turn a lap to adjust global variable\n"); printf("MAG3110_XMax:%d\n",MAG3110_XMax);printf("MAG3110_XMin:%d\n",MAG3110_XMin); printf("MAG3110_XOFF:%d\n",MAG3110_XOFF);printf("\n"); printf("MAG3110_YMax:%d\n",MAG3110_YMax);printf("MAG3110_YMin:%d\n",MAG3110_YMin); printf("MAG3110_YOFF:%d\n",MAG3110_YOFF);return 1;}static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, int size, union i2c_smbus_data *data){struct i2c_smbus_ioctl_data args;args.read_write = read_write;args.command = command;args.size = size;args.data = data;return ioctl(file, I2C_SMBUS, &args);}static int init_mag3110(int *fd){int i, ret;int data = 0x00;i2c_write_byte(fd, CTRL_REG, data);//STANDBY 模式data |= 0x04;i2c_write_byte(fd, CTRL_REG, data);//RF8位模式data += 1;i2c_write_byte(fd, CTRL_REG, data); //ACTIVE 模式usleep(500*1000);return 0;}void check_normal(int *fd){char ret;if(!(0xc4 == i2c_read_byte(fd,WHO_AM_I))){printf("check ID error\n");exit(-1);}}int i2c_read_byte(int *fd, __u16 mem_addr){int r;union i2c_smbus_data data;ioctl(*fd, BLKFLSBUF); //clear kernel read buffer__u8 buf = mem_addr & 0x0ff;r = i2c_smbus_access(*fd, I2C_SMBUS_WRITE, buf, I2C_SMBUS_BYTE, NULL);if (r < 0)return r;if (i2c_smbus_access(*fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data))return -1;elsereturn 0x0FF & data.byte;}int MAG3110_DataProcess(short MAG3110_XData,short MAG3110_YData){MAG3110_XData -= MAG3110_XOFF;MAG3110_YData -= MAG3110_YOFF;if (MAG3110_XData == 0){if (MAG3110_YData>0){ang = 90;}else{ang = 270;}}else if (MAG3110_YData == 0){if (MAG3110_XData>0){ang = 0;}else{ang = 180;}}else if((MAG3110_XData > 0) && (MAG3110_YData > 0)){ang = ( atan( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14;}else if ((MAG3110_XData < 0) && (MAG3110_YData > 0)){MAG3110_XData = -MAG3110_XData;ang = 180 - ( atan( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14;}else if ((MAG3110_XData < 0) && (MAG3110_YData < 0)){MAG3110_XData = -MAG3110_XData;MAG3110_YData = -MAG3110_YData;ang = (atan( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14 + 180;}else if ((MAG3110_XData > 0) && (MAG3110_YData < 0)){MAG3110_YData = -MAG3110_YData;ang = 360 -(atan( ( (float)MAG3110_YData) / ( (float) MAG3110_XData ) ) ) * 180 / 3.14;}return ang;}int iic_open(int *fd,char *dev_name, int addr){int funcs;int r;*fd = open(I2C_DEV, O_RDWR);if(fd <= 0){fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));return -1;}if((r = ioctl(*fd, I2C_FUNCS, &funcs) < 0)){fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));return -1;}if ((r = ioctl(*fd, I2C_SLAVE, addr)) < 0){fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));return -1;}usleep(500*1000);return 0;}int i2c_write_byte(int *fd, __u16 mem_addr, __u8 data){int r;__u8 command = mem_addr & 0x00ff;union i2c_smbus_data i2c_data;i2c_data.byte = data;r = i2c_smbus_access(*fd, I2C_SMBUS_WRITE, command, I2C_SMBUS_BYTE_DATA, &i2c_data);usleep(10);return r;}int main(int argc, char** argv){int fd;int ret;short data_x,data_y,data_z;/*1. open device..*/iic_open(&fd,I2C_DEV,CHIP_ADDR);/*2. checking whether normal*/check_normal(&fd);/*3. init the sensor*/init_mag3110(&fd);
/*4. begin main loop*/printf(" Reading xyz data from mag3110\n");while(1){system("clear");/*5.read raw data*/if(read_data_from_mag3110(&fd,&data_x,&data_y,&data_z)) /*6.adjust data*/if(mag3110_adjust_position(&data_x,&data_y,&data_z))/*data process*/{MAG3110_DataProcess(data_x,data_y);printf("Point to the south angle %d°\n",ang);}sleep(1);}}
0 0
- linux下i2c通用接口读取和处理mag3110地磁传感器程序
- 飞思卡尔地磁传感器MAG3110调试笔记
- 地磁传感器
- 方向传感器---使用加速度传感器和地磁传感器共同实现
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- HMC5883L地磁传感器驱动
- Linux I2C驱动分析(三)----i2c_dev通用接口驱动和应用层分析
- Windows和Linux下通用的线程接口
- Linux下I2C接口触摸屏驱动分析
- Linux下I2C接口触摸屏驱动分析
- Linux下I2C接口触摸屏驱动分析
- Linux下I2C接口触摸屏驱动分析
- 嵌入式Linux下I2C接口调试
- HMC5883L地磁传感器学习总结
- 【原创】zynq-7010下运用I2C总线完成对LSM303D传感器的数据读取
- iOS开发中地图(MapKit)的使用
- 用ConfigurationManager读取和修改配置文件
- 百鸡问题
- string转char*
- 抽象类与接口的深入区别
- linux下i2c通用接口读取和处理mag3110地磁传感器程序
- Bug 10121589 ORA-600 [kjbmprlst:shadow]
- tar命令详解
- eclipse中ADT离线安装方法
- (前、中、后)序遍历二叉树的递归、非递归算法!
- C++ 将字符串转换成date类型的数据
- SymmetricTree
- GNU对C语言的扩展---结构体
- 珍惜着美好的时光