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.odr、config.osr、config.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
-
更新时间:2026-08-05
-
更新内容:
-
初版,实现 QMC5883P 驱动所有基础功能
-
支持软件 I2C 和硬件 I2C 两种模式
-
支持量程切换(±2G / ±8G / ±12G / ±30G)
-
支持输出速率切换(10Hz / 50Hz / 100Hz / 200Hz)
-
支持过采样率(OSR1)与降采样率(OSR2)配置
-
支持 SET/RESET 偏移消除模式配置
-
支持软复位与芯片自检
-
支持挂起/唤醒/关闭
-
六、产品支持说明
所有支持 luatos 二次开发的模块,具体可以查看选型手册。