1
气压传感器
气压传感器是用来测量空气(或者其他气体)气压的传感器。将压力值转换为电信号输出,以直接的电压信号或者数字信号协议输出。常用于航空、气象、医疗等方面。
在无人机测高的方案中,激光测距的成本极高并且会受阻碍物影响。GPS的精度受信号影响。 ** 气压高度计 ** 无疑是一个成本低廉,精度较高的选择。
在理想条件下(假设温度保持不变),气压与高度的关系可以通过指数公式来近似表示:
P(h) 是高度 h 处的气压。
P₀ 是海平面处的标准气压,约为 101325 Pa(或 1013.25 hPa)。
h 是相对于海平面的高度(单位:米)。
L 是温度梯度(国际标准大气中为 0.0065 K/m)。
T₀ 是海平面上的温度,通常为 288.15 K(15°C)。
g₀ 是地球表面重力加速度,约为 9.80665 m/s²。
M 是空气的摩尔质量,约为 0.0289644 kg/mol。
R 是气体常数,约为 8.314 J/(mol·K)。
利用这些数据我们可以根据气压值获取一个近似的高度值。
BMP180/280是目前比较通用的,成本较低的气压传感器。气压测量范围为:300 hPa 到 1100 hPa(海拔从-500m到9000m)。
模块输出接口为标准I2C协议。本期我们利用STM32实现气压数据获取并转化为高度。
实验使用STM32F103C8T6最小系统板,气压传感器采用BMP280(买错了买成280了)
2
CubeMX配置
开启时钟和I2C即可,接着创建工程。这里别忘记开启Debug调试。
3
代码实现
#define BMP280_REG_ID 0xD0 // 芯片ID寄存器#define BMP280_REG_RESET 0xE0 // 软复位寄存器#define BMP280_REG_STATUS 0xF3 // 状态寄存器#define BMP280_REG_CTRL_MEAS 0xF4 // 测量控制寄存器#define BMP280_REG_CONFIG 0xF5 // 配置寄存器#define BMP280_REG_PRESS_MSB 0xF7 // 压力数据高字节#define BMP280_REG_PRESS_LSB 0xF8 // 压力数据中字节#define BMP280_REG_PRESS_XLSB 0xF9 // 压力数据低字节#define BMP280_REG_TEMP_MSB 0xFA // 温度数据高字节#define BMP280_REG_TEMP_LSB 0xFB // 温度数据中字节#define BMP280_REG_TEMP_XLSB 0xFC // 温度数据低字节
从BMP280的芯片手册中添加关于寄存器的宏定义,之后我们为BMP280的功能定义成结构体。
typedef struct BMP280_Device BMP280_Device;
typedef uint8_t (*BMP280_Init_Func)(BMP280_Device* dev, I2C_HandleTypeDef *hi2c);typedef void (*BMP280_SetConfig_Func)(BMP280_Device* dev, BMP280_Oversampling tempOS, BMP280_Oversampling pressOS, BMP280_Mode mode, BMP280_Filter filter, uint8_t standbyTime);typedef float (*BMP280_ReadTemp_Func)(BMP280_Device* dev);typedef float (*BMP280_ReadPress_Func)(BMP280_Device* dev);typedef float (*BMP280_ReadAlt_Func)(BMP280_Device* dev, float seaLevel);struct BMP280_Device {// BMP280设备结构体struct BMP280_Device { // 硬件相关 I2C_HandleTypeDef *hi2c; uint8_t devAddr; BMP280_CalibData calibData; // 传感器数据 BMP280_Data data; // 校准参数 struct { float knownAltitude; float knownPressure; float calibrationError; } calibration; // 采样设置 struct { uint8_t samplesCount; uint32_t sampleDelay; } sampling; // 函数指针 BMP280_Init_Func Init; BMP280_SetConfig_Func SetConfig; BMP280_Update_Func Update; BMP280_Calibrate_Func Calibrate;};
我们在正常的结构体基础上用函数指针来封装入结构体。
实现接口统一到结构体中。
这样子我们就实现了BMP280的数据读取,不过数据校准依旧是一件难事,具体代码会上传到交流群里面,大家可以从主页获取群号。