Banana Pi M1 读取 MPU6050(Shell 脚本方式)

写在前面

一直在想,嵌入式 Linux 系统中,已经集成了完整的 I2C 驱动,并且应用层还有 i2c-tools 这样的工具供我们使用,那么我们应该能够很容易地完成对一个 I2C 设备的访问和控制。
今天我们就试着,只使用 i2c-tools 命令,以 Shell 脚本的方式来实现对 I2C 设备的访问。

准备

硬件:Banana Pi M1、MPU6050
环境:Linux、buildroot

编译 firmware

make bananapi_m1_defconfig
make

最终在 output/images 目录下生成相应 image,这里我们只需要使用 sdcard.img 就可以了

liyongjun@Box:~/project/board/buildroot-2021.05$ ls output/images/
boot.scr  boot.vfat  rootfs.ext2  rootfs.ext4  rootfs.tar  sdcard_57600.img  sdcard.img  sun7i-a20-bananapi.dtb  u-boot.bin  u-boot-sunxi-with-spl.bin  zImage

烧录

使用 SDFormatter 将 SD 卡格式化,再使用 Win32DiskImager 将 sdcard.img 烧录到 SD 卡,这样 SD 卡系统盘就做好了
Banana Pi M1 读取 MPU6050(Shell 脚本方式)_第1张图片

启动

启动后,可以看到 /dev/ 目录下有三个 i2c 设备,

# ls /dev/i2c-*
/dev/i2c-0  /dev/i2c-1  /dev/i2c-2

哪个可以用呢?这时候就要看板子原理图了

原理图

扩展引脚中,3 号、5 号两个引脚为 I2C 引脚Banana Pi M1 读取 MPU6050(Shell 脚本方式)_第2张图片
对应 CPU 的 PB20、PB21 引脚
Banana Pi M1 读取 MPU6050(Shell 脚本方式)_第3张图片

设备树

然后去设备树中查看哪个 I2C 设备绑定了这两个引脚
Banana Pi M1 读取 MPU6050(Shell 脚本方式)_第4张图片
可以看到,i2C2 这个设备绑定了 PB20、PB21。i2C2 就是 /dev/i2c-2,接下来开始连线

硬件连线

i2c-tools

使用 i2c-tools 扫描设备

# i2cdetect -y 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
#

0x68 正是 MPU6050 的设备地址,说明连线正确,且驱动、i2c-tools 功能均正常。

数据手册

接下来就要根据数据手册,配置寄存器,并读取寄存器数据了
以电源管理 1 寄存器为例,它的寄存器地址为 0x6B
Banana Pi M1 读取 MPU6050(Shell 脚本方式)_第5张图片
Bit7 为 DEVICE_RESET 功能
在这里插入图片描述
像这样,我们只要跟着数据手册,一步一步配置就行了

脚本

编写脚本,主要用到 i2c-tools 的两个命令 i2cgeti2cset,用法就不多介绍了,直接上完整脚本
mpu6050.sh

#/bin/sh

init() {
        i2cset -y 2 0x68 0x6B 0x80      # 复位
        usleep 100000

        i2cset -y 2 0x68 0x19 0x00      # 设置采样频率
        i2cset -y 2 0x68 0x6B 0x05      # 关闭低功耗
        i2cset -y 2 0x68 0x23 0x00      # 关闭 FIFO
}

read() {
        h=$(i2cget -y 2 0x68 0x41)      # 读取温度值高 8 位
        l=$(i2cget -y 2 0x68 0x42)      # 读取温度值低 8 位
        t=$((($h << 8) + $l))

        if [ $t -gt 32768 ];then
                t=$(echo "$t - 65536" | bc)
        fi

        temp=$(echo "scale=2;36.53 + $t / 340" | bc)
        echo $temp}

main() {
        init
        while [[ 1 ]]
        do
                read
                usleep 200000
        done
}

main

执行

# ./mpu6050.sh
16.3916.4416.7217.1518.6119.7320.5821.1921.5721.6621.3321.5722.2322.7923.1223.4523.6923.8324.1624.3524.5324.7224.9625.1525.3325.4825.3325.1925.0525.1925.6626.7026.4226.5626.8426.9327.17

用手给它加热一下,可以看到温度在不断升高,说明功能是正常的。
可以看出,善于利用系统已有的功能和工具,能够极大的减轻我们的编程负担。上面的脚本仅仅三十多行,就完成了从 MPU6050 读取温度的功能。更多的时候,我们不要为了编程而编程,要多想想已有什么条件(资源),还差什么,我们把缺少的那部分补上,不就成功了吗,没必要从头造轮子。不过,有时间了,可以研究轮子!

你可能感兴趣的:(嵌入式,#,Shell,Linux,i2c-tools,MPU6050,Shell,脚本,温度)