跳转至

exs_qmc5883p 扩展库

作者:江访 | 最后修改:2026-08-07

一、概述

exs_qmc5883p 是 上海矽睿科技股份有限公司(QST) QMC5883P 三轴地磁传感器的 LuatOS 扩展库。 QMC5883P 是 QMC5883L 的 Pin-To-Pin 替代型号(QMC5883L 已停产), 是一款低功耗、高精度的三轴地磁传感器,广泛应用于电子罗盘、导航定位、磁力检测、无人机等领域, 并通过 AEC-Q100 grade 2 车规认证,支持工业/车载应用。

1.1 主要特性

  • 16 位 ADC,三轴磁场测量(X/Y/Z),输出范围 -32768~32767

  • I2C 接口通信,固定 7 位地址 0x2C(写 0x58,读 0x59)

  • 支持四种量程:±2G / ±8G / ±12G / ±30G(默认 ±8G)

  • 支持 4 种输出数据速率(ODR):10Hz / 50Hz / 100Hz / 200Hz

  • 支持过采样率(OSR1)8/4/2/1 与降采样率(OSR2)1/2/4/8 组合滤波 (默认 OSR1=8、OSR2=8,两者乘积最大 64)

  • 内置 SET/RESET 偏移消除与温度自动补偿,输出数据无需外部校准

  • 连续测量模式,无需手动触发

  • 数据输出单位为微特斯拉(μT),1 Gauss = 100 μT

  • 支持软件 I2C 和硬件 I2C 两种模式

  • 内置 I2C 总线卡死自动检测与恢复

  • 内置自检功能,可验证信号链路是否正常

1.2 注意事项

  • 推荐使用软件 I2C 模式:QMC5883P 在异常 I2C 通信后可能锁死 SDA 总线 (拉低 SDA 不放),软件 I2C 模式可以通过 GPIO 直接脉冲 SCL 恢复总线。 硬件 I2C 模式传引脚号同样支持总线恢复。

  • 初始化总线恢复:每次调用 setup() 时,如果传入了 scl/sda 引脚号, 驱动会先将 SCL/SDA 临时切为 GPIO 模式,向 SCL 发最多 9 个时钟脉冲, 每发一个检测 SDA 是否释放,释放后发 STOP 信号使总线恢复空闲, 确保总线在通信开始前处于正常状态。仅传 i2c_id 时跳过此步骤。

  • 运行时自动恢复:扩展库已内置 I2C 总线卡死自动检测与恢复。 当 i2c.send()i2c.recv() 返回失败时,驱动自动执行上述恢复流程并重试通信。 此功能同样需要 scl/sda 引脚配置。

  • 与 QMC5883L 不兼容:QMC5883P 的 I2C 地址、芯片 ID、寄存器定义均与 QMC5883L 不同,不能直接沿用 QMC5883L 的扩展库或驱动代码,请使用本扩展库。

  • SET/RESET 偏移消除:默认开启("on"),测量中持续消除传感器偏移, 输出数据已内置温度补偿,正常使用无需额外校准。

  • 协程限制setup()soft_reset()self_test() 内部使用 sys.wait(),必须在 sys.taskInit 创建的协程中调用,详见函数详解。

  • SCL 和 SDA 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC

1.3 功耗说明

通过 setup()config.odrconfig.osrconfig.osr2 控制采样速率来调节功耗, ODR/OSR 越低功耗越低。连续测量模式典型功耗(来自芯片手册):

输出数据速率 低采样配置 高采样配置
10 Hz 35 μA 78 μA
50 Hz 85 μA 310 μA
100 Hz 150 μA 600 μA
200 Hz 280 μA 1180 μA

挂起(sleep)模式功耗约 22 μA。将 SET/RESET 模式设为 "off" 可进一步降低功耗。

1.4 硬件连接

QMC5883P 通过 I2C 接口与主控连接,SCL/SDA 需外接 4.7kΩ~10kΩ 上拉电阻。

  ┌──────────────┐                    ┌──────────────────┐
  │    主控      │                    │    QMC5883P      │
  │  (AirXXX)    │                    │  三轴地磁传感器   │
  │              │                    │                  │
  │ GPIO_SCL ────┼────────────────────┼──→ SCL           │
  │              │                    │                  │
  │ GPIO_SDA ←───┼────────────────────┼──→ SDA           │
  │              │                    │ (需外接上拉电阻)│
  │              │                    │                  │
  │ VCC 3.3V ────┼────────────────────┼──→ VCC           │
  │              │                    │                  │
  │ GND      ────┼────────────────────┼──→ GND           │
  └──────────────┘                    └──────────────────┘

各平台示例接线(以软件 I2C 模式为例):

  • Air780EPM:SCL=GPIO31, SDA=GPIO30

  • Air780EHM/EHV/EGH:SCL=GPIO31, SDA=GPIO30

  • Air8101:SCL=GPIO4, SDA=GPIO5

  • Air8000:SCL=GPIO1, SDA=GPIO2

1.5 加载方式

-- 扩展库需要 require 加载后才能调用
local exs_qmc5883p = require "exs_qmc5883p"

二、核心示例

核心示例是使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码,帮助开发者快速理解如何使用本库。

更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/sensor/qmc5883p

2.1 按使用接口划分

2.1.1 软件 I2C 模式(推荐)

通过 GPIO 模拟 I2C 时序,不依赖硬件 I2C 外设,任何 GPIO 引脚都可使用。软件 I2C 支持总线异常时通过 GPIO 直接脉冲 SCL 恢复总线。

主动轮询读取:

local exs_qmc5883p = require "exs_qmc5883p"
local result = exs_qmc5883p.setup({scl = 31, sda = 30})
if not result then return end

while true do
    local data = exs_qmc5883p.get_data()
    if data then
        log.info("exs_qmc5883p", string.format("X=%.1f Y=%.1f Z=%.1f uT", data.x, data.y, data.z))
    end
    sys.wait(1000)  -- 等待 1 秒后继续
end

2.1.2 硬件 I2C 模式

使用芯片内置的硬件 I2C 外设,引脚固定。传入引脚号同样支持总线恢复。

主动轮询读取:

local exs_qmc5883p = require "exs_qmc5883p"
local result = exs_qmc5883p.setup({i2c_id = 0, scl = 31, sda = 30})
if not result then return end

while true do
    local data = exs_qmc5883p.get_data()
    if data then
        log.info("exs_qmc5883p", string.format("X=%.1f Y=%.1f Z=%.1f uT", data.x, data.y, data.z))
    end
    sys.wait(1000)  -- 等待 1 秒后继续
end

2.2 按使用场景划分

2.2.1 电子罗盘静态指向(省电)

适用场景:指南针、导航设备、需要持续输出方向信息。

local result = exs_qmc5883p.setup({
    scl = 31, sda = 30,
    range = "8G",   -- 标准地磁场范围
    odr = 10,       -- 10Hz 低功耗
    osr = 8,        -- 最高过采样,噪声最低
    osr2 = 8,       -- 最高降采样,滤波最强
})
if not result then return end

2.2.2 量程切换示例

适用场景:弱磁场环境用高灵敏度 ±2G 量程,强磁场环境用宽范围 ±30G 量程。

-- 切换为 ±2G 量程(高精度,灵敏度 15000 LSB/G)
exs_qmc5883p.set_range("2G")
local data = exs_qmc5883p.get_data()
if data then
    log.info("exs_qmc5883p", string.format("2G 量程: X=%.1f Y=%.1f Z=%.1f uT", data.x, data.y, data.z))
end

-- 切换回 ±8G 量程(宽范围,灵敏度 3750 LSB/G)
exs_qmc5883p.set_range("8G")

2.2.3 输出速率切换

适用场景:低速采样省电(10Hz),高速采样跟踪快速运动(200Hz)。

-- 设置为 200Hz 高速输出(适合快速运动检测)
exs_qmc5883p.set_odr(200)

-- 设置为 10Hz 低功耗输出(适合静态指向)
exs_qmc5883p.set_odr(10)

2.2.4 过采样/降采样配置

适用场景:需要极低噪声输出时提高 OSR,需要降低功耗时降低 OSR。

-- 最高滤波:OSR1=8(过采样 8 次) + OSR2=8(降采样 8 次)
exs_qmc5883p.set_osr(8, 8)

-- 最低功耗:OSR1=1(过采样 1 次) + OSR2=1(不降采样)
exs_qmc5883p.set_osr(1, 1)

2.2.5 休眠与唤醒示例

适用场景:间歇性采样的设备,不需要时休眠节省功耗。

-- 进入挂起模式(低功耗约 22 μA,保留配置)
exs_qmc5883p.sleep()

-- 需要时唤醒,无需重新 setup()
exs_qmc5883p.wakeup()
local data = exs_qmc5883p.get_data()

2.2.6 芯片自检示例

适用场景:生产测试、上电自检,验证传感器信号链路是否正常。

-- 自检函数(self_test 内部使用 sys.wait,必须在协程中调用)
local function self_test_func()
    local delta = exs_qmc5883p.self_test()
    if delta then
        log.info("exs_qmc5883p", string.format("自检增量 dx=%d dy=%d dz=%d",
            delta.dx, delta.dy, delta.dz))
    end
end
sys.taskInit(self_test_func)

三、常量解释

扩展库常量,顾名思义是由合宙 LuatOS 扩展库中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用,本扩展库没有常量。


四、函数详解

4.1 初始化

4.1.1 exs_qmc5883p.setup(config)

功能

初始化 QMC5883P 地磁传感器,配置 I2C 引脚和采样参数(量程、输出速率、过采样、降采样、SET/RESET 模式)

参数

config

参数含义:初始化配置表
数据类型:table
取值范围:包含以下子参数:
{
    参数含义:SCL 时钟引脚 GPIO 编号
    数据类型:number
    取值范围:有效的 GPIO 编号
    是否必选:与 sda 一起可选
    注意事项:与 sda 一起传入时,无 i2c_id 则创建软件 I2C(推荐),
              有 i2c_id 则走硬件 I2C 并附带总线恢复
    参数示例:31
    config.scl ,

    参数含义:SDA 数据引脚 GPIO 编号
    数据类型:number
    取值范围:有效的 GPIO 编号
    是否必选:与 scl 一起可选
    注意事项:该引脚需外接 4.7kΩ~10kΩ 上拉电阻到 VCC
    参数示例:30
    config.sda ,

    参数含义:硬件 I2C 总线 ID
    数据类型:number
    取值范围:有效的 I2C 总线编号
    是否必选:可选
    注意事项:默认 0。与 scl/sda 一起传时使用硬件 I2C 通信 + 引脚恢复总线;
              不传 scl/sda 时使用硬件 I2C 但无总线恢复能力
    参数示例:0
    config.i2c_id ,

    参数含义:I2C 设备地址(7 位地址)
    数据类型:number
    取值范围:0x00~0x7F
    是否必选:否
    注意事项:QMC5883P 地址固定为 0x2C(写 0x58,读 0x59),一般无需修改
    参数示例:0x2C
    config.addr ,

    参数含义:量程
    数据类型:string
    取值范围:
        "2G"(±2 高斯,15000 LSB/G,灵敏度最高,适合弱磁场环境或需要
              高分辨率检测微小磁场变化的场景,如金属探测、磁异常检测)
        "8G"(±8 高斯,3750 LSB/G,适合通用电子罗盘、导航定向等场景,默认)
        "12G"(±12 高斯,2500 LSB/G,适合较强磁场环境,如电机、磁体附近)
        "30G"(±30 高斯,1000 LSB/G,量程最宽抗干扰最强,适合工业/车载环境)
    是否必选:否
    注意事项:默认 "8G"。量程越小灵敏度越高,可测量最大值越小。
              地磁场强度一般 25~65 μT(约 0.25G~0.65G),±8G 量程完全覆盖。
              切换量程后 get_data() 返回的 μT 值自动按新灵敏度换算,无需干预
    参数示例:"8G"
    config.range ,

    参数含义:输出数据速率
    数据类型:number
    取值范围:10、50、100、200,单位 Hz
    是否必选:否
    注意事项:默认 10。传入非精确值时向下取整到最近的可用值
              (例如 75 会被设置为 50Hz)。ODR 越低功耗越低,
              各 ODR 对应的功耗见 1.3 功耗说明
    参数示例:50
    config.odr ,

    参数含义:过采样率(OSR1)
    数据类型:number
    取值范围:8(噪声最低,默认)、4、2、1
    是否必选:否
    注意事项:默认 8。过采样率越高噪声越低,但转换时间越长、功耗越高。
              与 config.osr2 组合使用,两者乘积最大 64
    参数示例:8
    config.osr ,

    参数含义:降采样率(OSR2)
    数据类型:number
    取值范围:1、2、4、8(滤波最强,默认)
    是否必选:否
    注意事项:默认 8。降采样率越高数字滤波越强、噪声越低。
              与 config.osr 组合使用,两者乘积最大 64
    参数示例:8
    config.osr2 ,

    参数含义:SET/RESET 偏移消除模式
    数据类型:string
    取值范围:
        "on"(SET 和 RESET 都开,测量中持续消除传感器偏移,推荐,默认)
        "set"(仅 SET 开,测量中偏移不更新)
        "off"(SET 和 RESET 都关,功耗最低但偏移不消除)
    是否必选:否
    注意事项:默认 "on"。芯片内置温度自动补偿,输出数据已补偿,
              正常使用无需额外校准
    参数示例:"on"
    config.set_reset ,
}
是否必选:是
参数示例:
         -- 方式一:软件 I2C 模式(推荐),指定任意 GPIO 号
         exs_qmc5883p.setup({scl = 31, sda = 30})

         -- 方式二:硬件 I2C 模式 + 总线恢复,传 i2c_id + I2C对应GPIO引脚
         exs_qmc5883p.setup({i2c_id = 0, scl = 31, sda = 30})

         -- 方式三:硬件 I2C 模式(无恢复),仅传 i2c_id
         exs_qmc5883p.setup({i2c_id = 0})

⚠️ 协程限制:必须在 sys.taskInit 创建的协程中调用

原因:内部使用 sys.wait() 等待总线恢复和芯片就绪

最长等待:约 15ms

返回值

local init_result = exs_qmc5883p.setup(config)

init_result

含义说明:初始化是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:失败时请检查接线、供电和 I2C 地址
返回示例:true

示例

-- 方式一:软件 I2C 模式(推荐),指定任意 GPIO 号
local result = exs_qmc5883p.setup({scl = 31, sda = 30})

-- 方式二:硬件 I2C 模式 + 总线恢复,传 i2c_id + I2C对应GPIO引脚
local result = exs_qmc5883p.setup({i2c_id = 0, scl = 31, sda = 30})

-- 方式三:硬件 I2C 模式(无恢复),仅传 i2c_id
local result = exs_qmc5883p.setup({i2c_id = 0})

4.2 数据读取

4.2.1 exs_qmc5883p.get_data()

功能

读取 QMC5883P 三轴磁场数据,根据当前量程自动计算 μT 值,并返回溢出标志。

参数

返回值

local data = exs_qmc5883p.get_data()

data

含义说明:三轴磁场数据表
数据类型:table 或 nil
取值范围:
    data.x  - X 轴磁场强度,单位 μT
    data.y  - Y 轴磁场强度,单位 μT
    data.z  - Z 轴磁场强度,单位 μT
    data.overflow - 溢出标志,true 表示磁场强度超出当前量程
注意事项:x/y/z 分辨率与当前量程相关,每 LSB 对应:
          ±2G 量程 0.0067 μT、±8G 量程 0.0267 μT、
          ±12G 量程 0.04 μT、±30G 量程 0.1 μT;
          读取失败返回 nil
返回示例:{x = 25.3, y = -12.8, z = 35.6, overflow = false}

示例

-- 数据读取
local data = exs_qmc5883p.get_data()
if data then
    log.info("exs_qmc5883p", string.format("X=%.1f Y=%.1f Z=%.1f uT", data.x, data.y, data.z))
else
    log.error("exs_qmc5883p", "读取数据失败")
end

4.3 参数配置

4.3.1 exs_qmc5883p.set_range(range)

功能

切换量程,量程改变后自动更新内部灵敏度系数

参数

range

参数含义:目标量程
数据类型:string
取值范围:
    "2G"(±2 高斯,15000 LSB/G,灵敏度最高,适合弱磁场环境或需要
          高分辨率检测微小磁场变化的场景,如金属探测、磁异常检测)
    "8G"(±8 高斯,3750 LSB/G,适合通用电子罗盘、导航定向等场景,默认)
    "12G"(±12 高斯,2500 LSB/G,适合较强磁场环境)
    "30G"(±30 高斯,1000 LSB/G,量程最宽抗干扰最强,适合工业/车载环境)
是否必选:是
注意事项:仅在 setup() 之后调用有效。切换成功后 get_data() 返回的
          μT 值自动按新灵敏度换算,无需重新 setup()。
          I2C 通信失败时返回 false,量程不变
参数示例:"2G"

返回值

local result = exs_qmc5883p.set_range(range)

result

含义说明:量程切换是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:失败时请检查接线和通信参数
返回示例:true

示例

-- 切换为 ±2G 量程(高精度)
exs_qmc5883p.set_range("2G")

-- 切换回 ±8G 量程(宽范围)
exs_qmc5883p.set_range("8G")

4.3.2 exs_qmc5883p.set_odr(hz)

功能

切换输出数据速率(ODR)

参数

hz

参数含义:目标输出速率
数据类型:number
取值范围:10、50、100、200(单位 Hz)
是否必选:是
注意事项:传入整数,非精确匹配时向下取整到最近的可用值
          (例如 75 会被设置为 50Hz)。仅在 setup() 之后调用有效。
          ODR 选择参考:
          - 10Hz:低功耗,适合电子罗盘静态指向、静止姿态监测等
            不需要快速更新的场景
          - 50Hz:中等功耗,适合步行导航、手持设备方向跟踪
          - 100Hz:较高功耗,适合游戏控制、快速姿态变化跟踪
          - 200Hz:高功耗,适合高速运动检测、无人机飞行控制等
            需要快速响应的场景
参数示例:100

返回值

local result = exs_qmc5883p.set_odr(hz)

result

含义说明:输出速率切换是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:失败时请检查接线和通信参数
返回示例:true

示例

-- 设置为 100Hz 输出
exs_qmc5883p.set_odr(100)

-- 设置为 10Hz 输出(低功耗)
exs_qmc5883p.set_odr(10)

4.3.3 exs_qmc5883p.set_osr(osr, osr2)

功能

配置过采样率(OSR1)与降采样率(OSR2),缺省参数保持当前值

参数

osr

参数含义:过采样率(OSR1)
数据类型:number
取值范围:8(噪声最低,默认)、4、2、1
是否必选:否
注意事项:缺省时保持当前值。过采样率越高噪声越低,但转换时间越长、
          功耗越高。与 osr2 组合使用,两者乘积最大 64
参数示例:8

osr2

参数含义:降采样率(OSR2)
数据类型:number
取值范围:1、2、4、8(滤波最强,默认)
是否必选:否
注意事项:缺省时保持当前值。降采样率越高数字滤波越强、噪声越低。
          与 osr 组合使用,两者乘积最大 64
参数示例:8

返回值

local result = exs_qmc5883p.set_osr(osr, osr2)

result

含义说明:配置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:失败时请检查接线和通信参数
返回示例:true

示例

-- 最高滤波:OSR1=8(过采样 8 次)+ OSR2=8(降采样 8 次)
exs_qmc5883p.set_osr(8, 8)

-- 仅调整过采样为 4,降采样保持当前值
exs_qmc5883p.set_osr(4)

-- 最低功耗:OSR1=1 + OSR2=1
exs_qmc5883p.set_osr(1, 1)

4.4 复位与自检

4.4.1 exs_qmc5883p.soft_reset()

功能

软复位 QMC5883P 芯片,复位完成后自动重新应用当前配置(量程/ODR/OSR 等)

参数

返回值

local result = exs_qmc5883p.soft_reset()

result

含义说明:复位并重新配置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:复位后芯片寄存器回到出厂默认值,本库会自动重新应用当前配置,
          调用后可直接读取数据,无需重新 setup()
返回示例:true

⚠️ 协程限制:必须在 sys.taskInit 创建的协程中调用

原因:内部使用 sys.wait() 等待复位完成

最长等待:约 6ms

示例

-- 软复位并恢复配置
exs_qmc5883p.soft_reset()

4.4.2 exs_qmc5883p.self_test()

功能

利用芯片内置自检激励信号验证信号链路是否正常。自检完成后自动恢复原配置

参数

返回值

local delta = exs_qmc5883p.self_test()

delta

含义说明:自检前后三轴增量表
数据类型:table 或 nil
取值范围:
    delta.dx - X 轴自检增量,单位 LSB(原始 ADC 计数)
    delta.dy - Y 轴自检增量,单位 LSB
    delta.dz - Z 轴自检增量,单位 LSB
注意事项:数据手册未给出判定阈值,增量明显大于正常噪声即表示
          信号链路正常;各轴增量方向因芯片安装方向而异;自检失败返回 nil
返回示例:{dx = -154, dy = -130, dz = -84}

⚠️ 协程限制:必须在 sys.taskInit 创建的协程中调用

原因:内部使用 sys.wait() 等待测量完成

最长等待:约 200ms

示例

-- 执行芯片自检
local delta = exs_qmc5883p.self_test()
if delta then
    log.info("exs_qmc5883p", string.format("自检增量 dx=%d dy=%d dz=%d",
        delta.dx, delta.dy, delta.dz))
else
    log.error("exs_qmc5883p", "自检失败")
end

4.5 电源管理

4.5.1 exs_qmc5883p.sleep()

功能

将传感器切换到挂起模式,保持内部配置状态。调用 wakeup() 可快速恢复工作,无需重新 setup()。挂起模式功耗约 22 μA

参数

返回值

示例

exs_qmc5883p.sleep()

4.5.2 exs_qmc5883p.wakeup()

功能

从挂起模式唤醒,恢复传感器到正常测量模式,配置保持休眠前的参数。无需重新调用 setup()。

参数

返回值

示例

exs_qmc5883p.wakeup()

4.6 资源释放

4.6.1 exs_qmc5883p.close()

功能

关闭 QMC5883P 传感器。将传感器切换到挂起模式,重置内部状态。close 后需要重新调用 setup() 才能再次使用。

参数

返回值

示例

exs_qmc5883p.close()

4.7 版本信息

4.7.1 exs_qmc5883p.version()

功能

获取 exs_qmc5883p 库的版本号

参数

返回值

local ver = exs_qmc5883p.version()

ver

含义说明:版本号字符串
数据类型:string
取值范围:格式 "yyyymmddhhmm",表示 yyyy年mm月dd日hh时mm分发布的版本
注意事项:无
返回示例:"202608050000"

示例

local ver = exs_qmc5883p.version()
log.info("exs_qmc5883p", "版本号:", ver)

五、版本更新说明

版本号:202608050000

  1. 更新时间:2026-08-05

  2. 更新内容:

    • 初版,实现 QMC5883P 驱动所有基础功能

    • 支持软件 I2C 和硬件 I2C 两种模式

    • 支持量程切换(±2G / ±8G / ±12G / ±30G)

    • 支持输出速率切换(10Hz / 50Hz / 100Hz / 200Hz)

    • 支持过采样率(OSR1)与降采样率(OSR2)配置

    • 支持 SET/RESET 偏移消除模式配置

    • 支持软复位与芯片自检

    • 支持挂起/唤醒/关闭


六、产品支持说明

所有支持 luatos 二次开发的模块,具体可以查看选型手册

搜索
AirMaster 实时解答