气压传感器
气压传感器是用来测量空气(或者其他气体)气压的传感器。将压力值转换为电信号输出,以直接的电压信号或者数字信号协议输出。常用于航空、气象、医疗等方面。
在无人机测高的方案中,激光测距的成本极高并且会受阻碍物影响。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的数据读取,具体代码会上传到交流群里面,大家可以从主页获取群号。