标签:异常 strong c11 first span efi conf set int
1、FBM320控制寄存器
a、AD数据寄存器地址(24bit数据):
0xF6:Data-LSB
0xF7:Data-CSB
0xF8:Data-MSB
b、CONFIG寄存器地址(0xF4):
OSR(bit6-bit7):00=1024X;01=2048X;10=4096X;11=8192X
Measurement_Control (bit0 ~ bit5):101110=温度转换;110100=压力转换
c、软件复位寄存器(0xE0):
向寄存器中写入0x6B,FBM320将执行复位功能,等待复位时间为15ms
d、校准数据寄存器(0xD0、0xF1、0xAA ~ 0xBB)
校准数据寄存器总共20Byte,用于传感器的校准
e、器件ID寄存器(0x6B)
器件ID寄存器上电默认值为0x42
f、SPI控制寄存器(0x00)
SDO_active(bot0、bit7):1=4线SPI,0=3线SPI
LSB_first(bit2、bit6):数据位传输顺序,1=LSB,0=MSB
2、FBM320代码实现
fbm320.h
#ifndef __FBM320_H
#define __FBM320_H
#pragma pack(push, 4)
// FBM320数据结构
typedef struct _sFbm320
{
// FBM320 转换结果
signed int real_pressure; // 真实压力值,单位:Pa
signed int real_temperature; // 真实温度值,单位:0.01℃
unsigned int raw_pressure; // 原始压力值
unsigned int raw_temperature; // 原始温度值
}sFbm320_t;
#pragma pack(pop)
/********************************************************
* 函数功能:FBM320初始化
* 形 参:无
* 返 回 值:0=初始化成功
* 1=芯片ID读取失败
* 2=版本号读取失败
* 3=校准系数读取失败
* 开发人员:icode
********************************************************/
unsigned char fbm320_init(void);
/********************************************************
* 函数功能:FBM320数据更新
* 形 参:psFbm320:数据结构指针
* ticks:当前的时间,单位:ms
* 返 回 值:0=数据更新完成
* 1=启动温度测量
* 2=读取温度数据
* 3=启动气压测量
* 4=读取气压数据
* 其它=状态机异常复位
* 0xFF=数据结构指针异常
* 开发人员:icode
********************************************************/
unsigned char fbm320_update(sFbm320_t * const psFbm320, unsigned int ticks);
#endif
fbm320.c
#include "fbm320.h"
#include "delay.h"
#include "iic.h"
// 器件地址:FBM320器件地址主要通过 SDO/ADDR 引脚配置
#define FBM320_SDO ((unsigned char)0x01) // 拉高或未连接为1,拉低为0
#define FBM320_ADDR ((unsigned char)(0x6C + FBM320_SDO))
// FBM320芯片ID
#define FBM320_CHIP_ID ((unsigned char)0x42)
// FBM320控制寄存器地址
#define FBM320_SPI_CTRL_REG 0x00
#define FBM320_SPI_CTRL_REG_SDO_ACTIVE_POS (0)
#define FBM320_SPI_CTRL_REG_SDO_ACTIVE_MSK (0x81 << FBM320_SPI_CTRL_REG_SDO_ACTIVE_POS)
#define FBM320_SPI_CTRL_REG_SDO_ACTIVE_EN (0x81 << FBM320_SPI_CTRL_REG_SDO_ACTIVE_POS)
#define FBM320_SPI_CTRL_REG_SDO_ACTIVE_DIS (0 << << FBM320_SPI_CTRL_REG_SDO_ACTIVE_POS)
#define FBM320_TAKE_MEAS_REG 0xF4
#define FBM320_READ_MEAS_REG_U 0xF6
#define FBM320_READ_MEAS_REG_L 0xF7
#define FBM320_READ_MEAS_REG_XL 0xF8
#define FBM320_SOFTRESET_REG 0xE0
#define FBM320_CHIP_ID_REG 0x6B
#define FBM320_VERSION_REG 0xA5
#define FBM320_P_CONFIG_REG 0xA6
#define FBM320_P_CONFIG_REG_GAIN_POS (3)
#define FBM320_P_CONFIG_REG_GAIN_MAK (7 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X1 (0 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X2 (1 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X4 (2 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X8 (3 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X16 (4 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X32 (5 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X64 (6 << FBM320_P_CONFIG_REG_GAIN_POS)
#define FBM320_P_CONFIG_REG_GAIN_X128 (7 << FBM320_P_CONFIG_REG_GAIN_POS)
// CMD list
#define FBM320_SOFTWARE_RESET 0xB6 // 软复位
#define FBM320_MEAS_TEMPERATURE 0x2E // 2.5ms wait for measurement
#define FBM320_MEAS_PRESS_OVERSAMP_0 0x34 // 2.5ms wait for measurement
#define FBM320_MEAS_PRESS_OVERSAMP_1 0x74 // 3.7ms wait for measurement
#define FBM320_MEAS_PRESS_OVERSAMP_2 0xB4 // 6ms wait for measurement
#define FBM320_MEAS_PRESS_OVERSAMP_3 0xF4 // 10.7ms wait for measurement
#define FBM320_CONVERSION_TIME_OSR1024 2500 // 单位:微秒
#define FBM320_CONVERSION_TIME_OSR2048 3700 // 单位:微秒
#define FBM320_CONVERSION_TIME_OSR4096 6000 // 单位:微秒
#define FBM320_CONVERSION_TIME_OSR8192 10700 // 单位:微秒
#define FBM320_CONVERSION_TIME_OSR16384 20500 // 单位:微秒
// 校准系数寄存器地址 {0xF1, 0xD0, 0xBB ~ 0xAA}
#define FBM320_CALIBRATION_DATA_START0 0xAA
#define FBM320_CALIBRATION_DATA_START1 0xD0
#define FBM320_CALIBRATION_DATA_START2 0xF1
#define FBM320_CALIBRATION_DATA_LENGTH 20 // 校准系数数据个数,单位:字节
#pragma pack(push, 1)
// FBM320硬件版本
typedef enum _eHardVersion
{
eVERSION_B1 = 0x00,
eVERSION_UNKNOWN = 0xFF,
}eHardVersion_t;
// FBM320采样率
typedef enum _eOsrType
{
eOSR_1024,
eOSR_2048,
eOSR_4096,
eOSR_8192,
eOSR_16384,
}eOsrType_t;
// FBM320校准系数
typedef struct _sCalibrationData
{
signed int c0;
signed int c1;
signed int c2;
signed int c3;
signed int c4;
signed int c5;
signed int c6;
signed int c7;
signed int c8;
signed int c9;
signed int c10;
signed int c11;
signed int c12;
}sCalibrationData_t;
// FBM320数据结构
typedef struct _sFbm320Dev
{
// 器件参数
eOsrType_t rate; // 采样率
unsigned char chip_id; // 芯片ID
eHardVersion_t version; // 版本号
sCalibrationData_t calibration; // 校准系数
// 转换配置参数
unsigned char start_pressure; // 气压转换启动命令
unsigned char start_temperature; // 温度转换启动命令
unsigned int convert_time_pressure; // 气压转换时间,单位:us
unsigned int convert_time_temperature; // 温度转换时间,单位:us
}sFbm320Dev_t;
#pragma pack(pop)
// 气压计数据结构对象
static sFbm320Dev_t sFbm320Dev;
/********************************************************
* 函数功能:读FBM320寄存器的值
* 形 参:addr:寄存器地址
* p:数据缓存地址
* length:数据长度,单位:字节
* 返 回 值:0=成功
* 1=数据缓存异常
* 2=总线应答超时
* 开发人员:icode
********************************************************/
static unsigned char fbm320_read(unsigned char addr, void * const p, unsigned int length)
{
unsigned char *pbuf = (unsigned char *)p;
if(!pbuf || !p || length < 1)
{
return 1;
}
iic_start();
// 发送器件地址(写模式)
if(iic_write((FBM320_ADDR << 1) | 0x00) != 0)
{
iic_stop();
return 2; // 应答超时
}
// 发送器件内部寄存器地址
if(iic_write(addr) != 0)
{
iic_stop();
return 2; // 应答超时
}
iic_start();
// 发送器件地址(读模式)
if(iic_write((FBM320_ADDR << 1) | 0x01) != 0)
{
iic_stop();
return 2; // 应答超时
}
// 读数据
for(unsigned int i = 0; i < length; i++)
{
pbuf[i] = iic_read((i < (length - 1))? 0 : 1);
}
iic_stop();
return 0;
}
/********************************************************
* 函数功能:写FBM320寄存器的值
* 形 参:addr:寄存器地址
* p:数据缓存地址
* length:数据长度,单位:字节
* 返 回 值:0=成功
* 1=数据缓存异常
* 2=总线应答超时
* 开发人员:icode
********************************************************/
static unsigned char fbm320_write(unsigned char addr, const void *p, unsigned int length)
{
unsigned char *pbuf = (unsigned char *)p;
if(!pbuf || !p || length < 1)
{
return 1;
}
iic_start();
// 发送器件地址(写模式)
if(iic_write((FBM320_ADDR << 1) | 0x00) != 0)
{
iic_stop();
return 2; // 应答超时
}
// 发送器件内部寄存器地址
if(iic_write(addr) != 0)
{
iic_stop();
return 2; // 应答超时
}
for(unsigned int i = 0; i < length; i++)
{
// 发送数据
if(iic_write(pbuf[i]) != 0)
{
iic_stop();
return 2; // 应答超时
}
}
iic_stop();
return 0;
}
/********************************************************
* 函数功能:读FBM320版本号寄存器的值
* 形 参:psFbm320:数据结构指针
* 返 回 值:0=成功
* 1=数据结构指针异常
* 2=软件复位失败
* 3=读寄存器失败
* 开发人员:icode
********************************************************/
static unsigned char fbm320_version_read(sFbm320Dev_t * const psFbm320)
{
unsigned char wdata = 0;
unsigned char rdata[2] = {0};
if(!psFbm320)
{
return 1; // 参数异常
}
// 器件执行复位指令时,总线是没有应答的
wdata = FBM320_SOFTWARE_RESET;
fbm320_write(FBM320_SOFTRESET_REG, &wdata, sizeof(wdata));
delay_ms(15); // The minimum start up time of fbm320 is 15ms
if(fbm320_read(FBM320_TAKE_MEAS_REG, rdata, sizeof(rdata[0])) != 0)
{
return 3; // 读寄存器失败
}
if(fbm320_read(FBM320_VERSION_REG, rdata + 1, sizeof(rdata[0])) != 0)
{
return 3; // 读寄存器失败
}
wdata = ((rdata[0] & 0xC0) >> 6) | ((rdata[1] & 0x70) >> 2);
if(wdata == eVERSION_B1)
{
psFbm320->version = eVERSION_B1;
}
else
{
// The version of sensor is unknown.
psFbm320->version = eVERSION_UNKNOWN;
}
return 0;
}
/********************************************************
* 函数功能:读FBM320校准系数寄存器的值
* 形 参:psFbm320:数据结构指针
* 返 回 值:0=成功
* 1=数据结构指针异常
* 2=校准系数读取失败
* 开发人员:icode
********************************************************/
static unsigned char fbm320_calibration_read(sFbm320Dev_t * const psFbm320)
{
unsigned short word[10] = {0};
unsigned char byte[FBM320_CALIBRATION_DATA_LENGTH] = {0};
if(!psFbm320)
{
return 1; // 参数异常
}
// 读校准系数,地址:0xBB ~ 0xAA
if(fbm320_read(FBM320_CALIBRATION_DATA_START0, byte, sizeof(byte) - 2) != 0)
{
return 2; // 校准系数读取失败
}
// 读校准系数,地址:0xD0
if(fbm320_read(FBM320_CALIBRATION_DATA_START1, byte + 18, sizeof(byte[0])) != 0)
{
return 2; // 校准系数读取失败
}
// 读校准系数,地址:0xF1
if (fbm320_read(FBM320_CALIBRATION_DATA_START2, byte + 19, sizeof(byte[0])) != 0)
{
return 2; // 校准系数读取失败
}
// 系数重建
word[0] = (byte[0] << 8 | byte[1]);
word[1] = (byte[2] << 8 | byte[3]);
word[2] = (byte[4] << 8 | byte[5]);
word[3] = (byte[6] << 8 | byte[7]);
word[4] = (byte[8] << 8 | byte[9]);
word[5] = (byte[10] << 8 | byte[11]);
word[6] = (byte[12] << 8 | byte[13]);
word[7] = (byte[14] << 8 | byte[15]);
word[8] = (byte[16] << 8 | byte[17]);
word[9] = (byte[18] << 8 | byte[19]);
psFbm320->calibration.c0 = word[0] >> 4;
psFbm320->calibration.c1 = ((word[1] & 0xFF00) >> 5 ) | (word[2] & 0x7);
psFbm320->calibration.c2 = ((word[1] & 0xFF) << 1 ) | (word[4] & 0x1);
psFbm320->calibration.c3 = word[2] >> 3;
psFbm320->calibration.c4 = ((unsigned int)word[3] << 2) | (word[0] & 0x3);
psFbm320->calibration.c5 = word[4] >> 1;
psFbm320->calibration.c6 = word[5] >> 3;
psFbm320->calibration.c7 = ((unsigned int)word[6] << 3) | (word[5] & 0x7);
psFbm320->calibration.c8 = word[7] >> 3;
psFbm320->calibration.c9 = word[8] >> 2;
psFbm320->calibration.c10 = ((word[9] & 0xFF00) >> 6) | (word[8] & 0x3);
psFbm320->calibration.c11 = word[9] & 0xFF;
psFbm320->calibration.c12 = ((word[0] & 0xC) << 1) | (word[7] & 0x7);
return 0;
}
/********************************************************
* 函数功能:FBM320采样率配置
* 形 参:psFbm320:数据结构指针
* rate:采样率类型
* 返 回 值:0=成功
* 1=数据结构指针异常
* 2=未知的采样率类型
* 开发人员:icode
********************************************************/
static unsigned char fbm320_oversampling_rate_config(sFbm320Dev_t * const psFbm320, eOsrType_t rate)
{
unsigned char rwdata;
if(!psFbm320)
{
return 1; // 参数异常
}
// 设定压力测量转换时间
switch (rate)
{
case eOSR_1024:
{
psFbm320->start_pressure = FBM320_MEAS_PRESS_OVERSAMP_0;
psFbm320->convert_time_pressure = FBM320_CONVERSION_TIME_OSR1024;
break;
}
case eOSR_2048:
{
psFbm320->start_pressure = FBM320_MEAS_PRESS_OVERSAMP_1;
psFbm320->convert_time_pressure = FBM320_CONVERSION_TIME_OSR2048;
break;
}
case eOSR_4096:
{
psFbm320->start_pressure = FBM320_MEAS_PRESS_OVERSAMP_2;
psFbm320->convert_time_pressure = FBM320_CONVERSION_TIME_OSR4096;
break;
}
case eOSR_8192:
{
psFbm320->start_pressure = FBM320_MEAS_PRESS_OVERSAMP_3;
psFbm320->convert_time_pressure = FBM320_CONVERSION_TIME_OSR8192;
break;
}
case eOSR_16384:
{
psFbm320->start_pressure = FBM320_MEAS_PRESS_OVERSAMP_2;
psFbm320->convert_time_pressure = FBM320_CONVERSION_TIME_OSR16384;
fbm320_read(0xA6, &rwdata, sizeof(rwdata));
rwdata = (rwdata & 0xF8) | 0x6;
fbm320_write(0xA6, &rwdata, sizeof(rwdata));
fbm320_read(0xA6, &rwdata, sizeof(rwdata));
break;
}
default:
{
return 2; // 未知的采样率类型
}
}
// 保存当前的采样率
psFbm320->rate = rate;
// 设定温度测量转换时间
psFbm320->start_temperature = FBM320_MEAS_TEMPERATURE;
psFbm320->convert_time_temperature = FBM320_CONVERSION_TIME_OSR1024;
return 0;
}
/********************************************************
* 函数功能:FBM320数据校准
* 形 参:psFbm320Dev:配置参数指针
* psFbm320:数据缓存指针
* 返 回 值:0=校准完成
* 1=数据结构指针异常
* 开发人员:icode
********************************************************/
static unsigned char fbm320_calculation(sFbm320Dev_t * const psFbm320Dev, sFbm320_t * const psFbm320)
{
signed int X01, X02, X03, X11, X12, X13, X21, X22, X23, X24, X25, X26;
signed int PP1, PP2, PP3, PP4, CF, X31, X32;
signed int RT, RP, UT, UP, DT, DT2;
if(!psFbm320Dev || !psFbm320)
{
return 1;
}
// calculation for real temperature value
UT = psFbm320->raw_temperature;
DT = ((UT - 8388608) >> 4) + (psFbm320Dev->calibration.c0 << 4);
X01 = (psFbm320Dev->calibration.c1 + 4498L) * DT >> 1;
X02 = ((((psFbm320Dev->calibration.c2 - 256L) * DT) >> 14) * DT) >> 4;
X03 = (((((psFbm320Dev->calibration.c3 * DT) >> 18) * DT) >> 18) * DT);
DT2 = (X01 + X02 + X03) >> 12;
RT = ((2500L << 15) - X01 - X02 - X03) >> 15;
// calculation for real pressure value
UP = psFbm320->raw_pressure;
X11 = ((psFbm320Dev->calibration.c5 - 15446L) * DT2);
X12 = ((((psFbm320Dev->calibration.c6 - 4096L) * DT2) >> 16) * DT2) >> 4;
X13 = ((X11 + X12) >> 11) + ((psFbm320Dev->calibration.c4 - 122684) << 4);
X21 = ((psFbm320Dev->calibration.c8 + 1528L) * DT2) >> 11;
X22 = (((psFbm320Dev->calibration.c9 * DT2) >> 17) * DT2) >> 13;
X23 = (X22 >= X21) ? (X22 - X21) : (X21 - X22);
X24 = (X23 >> 11) * (psFbm320Dev->calibration.c7 + 596352);
X25 = ((X23 & 0x7FF) * (psFbm320Dev->calibration.c7 + 596352)) >> 11;
X26 = (X21 >= X22 ? ((0 - X24 - X25) >> 9) : ((X24 + X25) >> 9)) + psFbm320Dev->calibration.c7 + 596352;
PP1 = (((UP - 8388608) >> 1) - X13) >> 4;
PP2 = ((X26 >> 12) * PP1) >> 1;
PP3 = ((X26 & 0xFFF) * PP1) >> 13;
PP4 = (PP2 + PP3) >> 3;
CF = (2097152 + psFbm320Dev->calibration.c12 * DT2) >> 2;
X31 = (((CF * psFbm320Dev->calibration.c10) >> 22) * PP4) >> 6;
X32 = (((((CF * psFbm320Dev->calibration.c11) >> 20) * PP4) >> 22) * PP4);
RP = ((X31 + X32) >> 11) + PP4 + 100000;
psFbm320->real_temperature = RT; // uint:0.01 degree Celsius
psFbm320->real_pressure = RP; // uint: Pa
return 0;
}
/********************************************************
* 函数功能:读FBM320芯片ID
* 形 参:psFbm320:数据结构指针
* 返 回 值:0=成功
* 1=数据结构指针异常
* 2=读寄存器失败
* 3=芯片ID错误
* 开发人员:icode
********************************************************/
static unsigned char fbm320_chip_id_check(sFbm320Dev_t * const psFbm320)
{
unsigned char chip_id = 0;
if(!psFbm320)
{
return 1; // 参数异常
}
if (fbm320_read(FBM320_CHIP_ID_REG, &chip_id, sizeof(chip_id)) != 0)
{
return 2; // 读寄存器失败
}
if(chip_id != FBM320_CHIP_ID)
{
return 3; // 芯片ID错误
}
psFbm320->chip_id = FBM320_CHIP_ID;
return 0;
}
/********************************************************
* 函数功能:FBM320初始化
* 形 参:无
* 返 回 值:0=初始化成功
* 1=芯片ID读取失败
* 2=版本号读取失败
* 3=校准系数读取失败
* 开发人员:icode
********************************************************/
unsigned char fbm320_init(void)
{
unsigned char rwdata = 0;
// The minimum start up time of fbm320 is 15ms
delay_ms(15);
if(fbm320_chip_id_check(&sFbm320Dev) != 0)
{
return 1; // 芯片ID读取失败
}
if(fbm320_version_read(&sFbm320Dev) != 0)
{
return 2; // 版本号读取失败
}
if(fbm320_calibration_read(&sFbm320Dev) != 0)
{
return 3; // 校准系数读取失败
}
// FBM320采样率配置
fbm320_oversampling_rate_config(&sFbm320Dev, eOSR_8192);
// Setting the P_CONFIG_REG_GAIN
fbm320_read(FBM320_P_CONFIG_REG, &rwdata, sizeof(rwdata));
rwdata &= ~(FBM320_P_CONFIG_REG_GAIN_MAK);
rwdata |= FBM320_P_CONFIG_REG_GAIN_X32;
fbm320_write(FBM320_P_CONFIG_REG, &rwdata, sizeof(rwdata));
return 0;
}
/********************************************************
* 函数功能:FBM320数据更新
* 形 参:psFbm320:数据结构指针
* ticks:当前的时间,单位:ms
* 返 回 值:0=数据更新完成
* 1=启动温度测量
* 2=读取温度数据
* 3=启动气压测量
* 4=读取气压数据
* 其它=状态机异常复位
* 0xFF=数据结构指针异常
* 开发人员:icode
********************************************************/
unsigned char fbm320_update(sFbm320_t * const psFbm320, unsigned int ticks)
{
static unsigned char status = 0;
static unsigned int start_time = 0;
if(!psFbm320)
{
return 0xFF;
}
switch(status)
{
case 0: // 用户处理数据
{
status++;
break;
}
case 1: // 启动温度测量
{
unsigned char wdata = sFbm320Dev.start_temperature;
if(fbm320_write(FBM320_TAKE_MEAS_REG, &wdata, sizeof(wdata)) == 0)
{
// 温度测量启动成功
status++;
start_time = ticks;
}
break;
}
case 2: // 读取温度值
{
// 判断温度测量时间
if((ticks - start_time) * 1000 > sFbm320Dev.convert_time_temperature)
{
unsigned char rbuf[3] = {0};
if(fbm320_read(FBM320_READ_MEAS_REG_U, rbuf, sizeof(rbuf)) == 0)
{
status++;
start_time = 0;
// 温度数据处理
ticks = 0;
ticks = (ticks << 8) + rbuf[0];
ticks = (ticks << 8) + rbuf[1];
ticks = (ticks << 8) + rbuf[2];
psFbm320->raw_temperature = ticks;
}
}
break;
}
case 3: // 启动气压测量
{
unsigned char wdata = sFbm320Dev.start_pressure;
if(fbm320_write(FBM320_TAKE_MEAS_REG, &wdata, sizeof(wdata)) == 0)
{
// 气压测量启动成功
status++;
start_time = ticks;
}
break;
}
case 4: // 读取气压值
{
// 判断温度测量时间
if((ticks - start_time) * 1000 > sFbm320Dev.convert_time_pressure)
{
unsigned char rbuf[3] = {0};
if(fbm320_read(FBM320_READ_MEAS_REG_U, rbuf, sizeof(rbuf)) == 0)
{
status = 0;
start_time = 0;
// 气压数据处理
ticks = 0;
ticks = (ticks << 8) + rbuf[0];
ticks = (ticks << 8) + rbuf[1];
ticks = (ticks << 8) + rbuf[2];
psFbm320->raw_pressure = ticks;
// 数据校准计算
fbm320_calculation(&sFbm320Dev, psFbm320);
}
}
break;
}
default: // 状态复位
{
// 这里不能将状态清零,因为零表示用户可以处理数据
status = 1;
break;
}
}
return status;
}
FBM320气压计
标签:异常 strong c11 first span efi conf set int
原文地址:https://www.cnblogs.com/icode-wzc/p/13218028.html