linux下i2c分析,【linux】i2c使用分析&源码实战

目录

前言

1. 设备检查命令

1.1 查看I2C驱动

1.2 i2c-tools

1.2.1 I2C-detect安装

1.2.2 i2cdetect 命令

1.2.3 i2cget 命令

1.2.4 i2cset 命令

1.2.5 i2cdump 命令

2. 源码实战

2.1 编写 bsp_mpu6050.h 文件

2.2 编写 bsp_mpu6050.c 文件

2.3 编写 main.c 文件

相关链接

前言

目前不涉及驱动源码

原文

1. 设备检查命令

1.1 查看I2C驱动

命令:ls /sys/bus/i2c/devices 用于查看系统上存在的 I2C 总线

1.2 i2c-tools

i2c-tools,安装 i2c-tools 方便调试 i2c设备

1.2.1 I2C-detect安装

使用命令:sudo apt install i2c-tools -y 安装 i2c-tools

安装后可以使用命令:i2cdetect、i2cdump、i2cset 和 i2cget

1.2.2 i2cdetect 命令

i2cdetect

用于扫描 I2C 总线上的设备

语法

i2cdetect [-y] [-a] [-q|-r] i2cbus [first last]

参数

y:关闭交互模式,使用该参数时,不会提示警告信息。

a:扫描总线上的所有设备

q:使用SMBus的“quick write”命令进行检测,不建议使用该参数

r:使用SMBus的“receive byte”命令进行检测,不建议使用该参数

i2cbus:指定i2c总线的编号

first、last:扫描的地址范围

返回值

‘-‘:表示该地址被检测,但是没有芯片应答

‘UU’:表示该地址当前由内核驱动程序使用

‘**’:** 表示以16进制表示的设备地址编号,如“68”

例子:

i2cdetect -a 0

i2cdetect:i2cdetect命令

-a:总线上所有设备

0:标号为 0 的 I2C,即是 I2C 1。

b1c15fdeafecca97d9c81705c60696f3.png

上图中扫描出存在设备地址为 0x1e 和 0x68 的设备。

i2cdetect -F i2cbus:查询 i2c 总线的功能,参数 i2cbus 表示 i2c 总线(看上)

i2cdetect -V:打印软件的版本号

i2cdetect -l:检测当前系统有几组 i2c 总线

1.2.3 i2cget 命令

i2cget

用于读取 I2C 设备的某个寄存器的值

语法

i2cget [-f] [-y] i2cbus chip-address [data-address [mode]]

参数

f:强制访问

y:关闭交互模式,使用该参数时,不会提示警告信息

i2cbus:指定 I2C 总线的编号

chip-address:I2C 设备地址

data-address:I2C 寄存器地址

mode:指定读取的大小, 可以是b, w, s或i,分别对应了字节,字,SMBus块, I2C块

1.2.4 i2cset 命令

i2cset

写入指定 I2C 设备的某个寄存器的值

语法

i2cset [-f] [-y] [-m mask] [-r] i2cbus chip-address data-address [value] … [mode]

参数

f:强制访问

y:关闭交互模式,使用该参数时,不会提示警告信息

m:

r:写入后立即回读寄存器值,并将结果与写入的值进行比较

i2cbus:指定 I2C 总线的编号

chip-address:I2C 设备地址

data-address:I2C 寄存器地址

value:要写入的值

mode:指定读取的大小, 可以是b, w, s或i,分别对应了字节,字,SMBus块, I2C块

1.2.5 i2cdump 命令

i2cdump

读取指定设备的全部寄存器的值

语法

i2cdump [-f] [-r first-last] [-y] i2cbus address [mode [bank [bankreg]]]

参数

r:指定寄存器范围,只能扫描从 first 到 last 区域

f:强制访问设备

y:关闭人机交互模式

i2cbus:指定 I2C 总线的编号

address:指定设备地址

mode:指定读取的大小, 可以是b, w, s或i,分别对应了字节,字,SMBus块, I2C块

例子

i2cdump -V:打印软件的版本号

2. 源码实战

采用MPU6050设备进行实验

步骤:

先编写基础的 I2C 基础函数

编写 MPU6050 初始化函数和关闭设备文件函数

编写获取 MPU6050 数据函数

编写业务函数

2.1 编写 bsp_mpu6050.h 文件

编写好 MPU6050 需要的宏

extern 外部函数

/** @file         bsp_mpu6050.h

*  @brief        简要说明

*  @details      详细说明

*  @author       lzm

*  @date         2020-11-28 19:22:20

*  @version      v1.0

*  @copyright    Copyright By lizhuming, All Rights Reserved

*

**********************************************************

*  @LOG 修改日志:

**********************************************************

*/

#ifndef _BSP_MPU6050_H_

#define _BSP_MPU6050_H_

/* 宏 */

#define SMPLRT_DIV                                  0x19

#define CONFIG                                      0x1A

#define GYRO_CONFIG                                 0x1B

#define ACCEL_CONFIG                                0x1C

#define ACCEL_XOUT_H                                0x3B

#define ACCEL_XOUT_L                                0x3C

#define ACCEL_YOUT_H                                0x3D

#define ACCEL_YOUT_L                                0x3f

#define ACCEL_ZOUT_H                                0x3F

#define ACCEL_ZOUT_L                                0x40

#define TEMP_OUT_H                                  0x41

#define TEMP_OUT_L                                  0x42

#define GYRO_XOUT_H                                 0x43

#define GYRO_XOUT_L                                 0x44

#define GYRO_YOUT_H                                 0x45

#define GYRO_YOUT_L                                 0x46

#define GYRO_ZOUT_H                                 0x47

#define GYRO_ZOUT_L                                 0x48

#define PWR_MGMT_1                                  0x6B

#define WHO_AM_I                                    0x75

#define SlaveAddress                                0xD0

#define Address                                     0x68                  //MPU6050地址

#define I2C_RETRIES                                 0x0701

#define I2C_TIMEOUT                                 0x0702

#define I2C_SLAVE                                   0x0703       //IIC从器件的地址设置

#define I2C_BUS_MODE                                0x0780

/* 类型转换 */

typedef unsigned char uint8_t;

/* 函数 */

uint8_t mpu6050_init(char * i2cDev);

void    mpu6050_close(void);

short   getData(unsigned char regAddr);

#endif /* #define _BSP_MPU6050_H_ */

2.2 编写 bsp_mpu6050.c 文件

bsp_mpu6050.c

编写 I2C 读写函数

编写 MPU6050 设备初始化函数及关闭文件函数

编写获取 MPU6050 设备寄存器数据函数

/** @file         bsp_mpu6050.c

*  @brief        简要说明

*  @details      详细说明

*  @author       lzm

*  @date         2020-11-28 19:20:20

*  @version      v1.0

*  @copyright    Copyright By lizhuming, All Rights Reserved

*

**********************************************************

*  @LOG 修改日志:

**********************************************************

*/

/* 头文件 */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "bsp_mpu6050.h"

/* 设备句柄 */

int i2cFd; // i2c设备句柄

/**

* @brief  i2c 写

* @param  fd:i2c设备句柄

* @param  regAddr:寄存器地址

* @param  val:需要写入的值

* @retval 0:写入成功

* @retval -1:写入失败

* @author lzm

*/

static uint8_t i2c_write(int fd, uint8_t regAddr, uint8_t val)

{

int cnt; // 写入失败后,重复写入的次数

uint8_t data[2]; // data[0]为寄存器地址,data[1]为需要写入的值

data[0] = regAddr;

data[1] = val;

for(cnt=5; cnt>0; cnt--)

{

if(write(fd, data, 2) == 2)

return 0; // 写入成功

}

return -1; // 写入失败

}

/**

* @brief  i2c 读

* @param  fd:i2c设备句柄

* @param  regAddr:寄存器地址

* @param  val:读取到数据保存的地方

* @retval 0:读取成功

* @retval -1:读取失败

* @author lzm

*/

static uint8_t i2c_read(int fd, uint8_t regAddr, uint8_t * val)

{

int cnt; // 读取失败后,重新读取的次数

for(cnt=5; cnt>0; cnt--)

{

if(write(fd, &regAddr, 1) == 1)

{

if(read(fd, val, 1) == 1)

return 0;

}

}

return -1;

}

/**

* @brief  mpu6050初始化

* @param  i2cDev

* @retval 1:初始化成功

* @retval 0:初始化失败

* @author lzm

*/

uint8_t mpu6050_init(char * i2cDev)

{

i2cFd = open(i2cDev, O_RDWR); // 打开i2c设备文件

if(i2cFd 

{

printf("Can't open %s!n", i2cDev);

exit(1);

}

printf("Open %s success!", i2cDev);

if(ioctl(i2cFd, I2C_SLAVE, Address) 

{

printf("fail to set i2c device slave address!");

close(i2cFd); // 关闭i2c设备文件

return -1;

}

printf("set slave address to 0x%x success!", Address);

i2c_write(i2cFd, PWR_MGMT_1, 0X00);

i2c_write(i2cFd, SMPLRT_DIV, 0X07);

i2c_write(i2cFd, CONFIG, 0X06);

i2c_write(i2cFd, ACCEL_CONFIG, 0X01);

return 1;

}

/**

* @brief  关闭设备文件

* @param

* @retval

* @author lzm

*/

void mpu6050_close(void)

{

close(i2cFd);

}

/**

* @brief  获取数据

* @param  regAddr:寄存器地址

* @retval 获取到的数据

* @author lzm

*/

short getData(unsigned char regAddr)

{

char chH; // 高字节

char chL; // 低字节

i2c_read(i2cFd, regAddr, &chH);

usleep(1000);

i2c_read(i2cFd, regAddr, &chL);

return ((chH <

}

2.3 编写 main.c 文件

编写业务函数

/** @file         main.c

*  @brief        简要说明

*  @details      详细说明

*  @author       lzm

*  @date         2020-11-28 19:18:20

*  @version      v1.0

*  @copyright    Copyright By lizhuming, All Rights Reserved

*

**********************************************************

*  @LOG 修改日志:

**********************************************************

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "mpu6050/bsp_mpu6050.h"

int main(int argc, char * argv[])

{

/* 程序开始标语 */

printf("This is a mpu6050 test!n");

/* 初始化 MCPU6050 */

mpu6050_init("/dev/i2c-0");

sleep(1);

/* mpu6050 应用测试 */

while(1)

{

printf("get mpu6050 data!n");

usleep(1000 * 100);

printf("ACCE_X:%6dn ", getData(ACCEL_XOUT_H));

usleep(1000 * 100);

printf("ACCE_Y:%6dn ", getData(ACCEL_YOUT_H));

usleep(1000 * 100);

printf("ACCE_Z:%6dn ", getData(ACCEL_ZOUT_H));

usleep(1000 * 100);

printf("GYRO_X:%6dn ", getData(GYRO_XOUT_H));

usleep(1000 * 100);

printf("GYRO_Y:%6dn ", getData(GYRO_YOUT_H));

usleep(1000 * 100);

printf("GYRO_Z:%6dnn ", getData(GYRO_ZOUT_H));

sleep(1);

}

/* 退出 mpu6050 */

mpu6050_close();

}

相关链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值