SPL06-001 驱动代码

1. .h文件需要定义的部分

/**************************************************************************
*宏定义
**************************************************************************/

//气压测量速率(sample/sec),Background 模式使用
#define  PM_RATE_1          (0<<4)      //1 measurements pr. sec.
#define  PM_RATE_2          (1<<4)      //2 measurements pr. sec.
#define  PM_RATE_4          (2<<4)      //4 measurements pr. sec.           
#define  PM_RATE_8          (3<<4)      //8 measurements pr. sec.
#define  PM_RATE_16         (4<<4)      //16 measurements pr. sec.
#define  PM_RATE_32         (5<<4)      //32 measurements pr. sec.
#define  PM_RATE_64         (6<<4)      //64 measurements pr. sec.
#define  PM_RATE_128        (7<<4)      //128 measurements pr. sec.

//气压重采样速率(times),Background 模式使用
#define PM_PRC_1            0       //Sigle         kP=524288   ,3.6ms
#define PM_PRC_2            1       //2 times       kP=1572864  ,5.2ms
#define PM_PRC_4            2       //4 times       kP=3670016  ,8.4ms
#define PM_PRC_8            3       //8 times       kP=7864320  ,14.8ms
#define PM_PRC_16           4       //16 times      kP=253952   ,27.6ms
#define PM_PRC_32           5       //32 times      kP=516096   ,53.2ms
#define PM_PRC_64           6       //64 times      kP=1040384  ,104.4ms
#define PM_PRC_128          7       //128 times     kP=2088960  ,206.8ms

//温度测量速率(sample/sec),Background 模式使用
#define  TMP_RATE_1         (0<<4)      //1 measurements pr. sec.
#define  TMP_RATE_2         (1<<4)      //2 measurements pr. sec.
#define  TMP_RATE_4         (2<<4)      //4 measurements pr. sec.           
#define  TMP_RATE_8         (3<<4)      //8 measurements pr. sec.
#define  TMP_RATE_16        (4<<4)      //16 measurements pr. sec.
#define  TMP_RATE_32        (5<<4)      //32 measurements pr. sec.
#define  TMP_RATE_64        (6<<4)      //64 measurements pr. sec.
#define  TMP_RATE_128       (7<<4)      //128 measurements pr. sec.

//温度重采样速率(times),Background 模式使用
#define TMP_PRC_1           0       //Sigle
#define TMP_PRC_2           1       //2 times
#define TMP_PRC_4           2       //4 times
#define TMP_PRC_8           3       //8 times
#define TMP_PRC_16          4       //16 times
#define TMP_PRC_32          5       //32 times
#define TMP_PRC_64          6       //64 times
#define TMP_PRC_128         7       //128 times

//SPL06_MEAS_CFG
#define MEAS_COEF_RDY       0x80
#define MEAS_SENSOR_RDY     0x40        //传感器初始化完成
#define MEAS_TMP_RDY        0x20        //有新的温度数据
#define MEAS_PRS_RDY        0x10        //有新的气压数据

#define MEAS_CTRL_Standby               0x00    //空闲模式
#define MEAS_CTRL_PressMeasure          0x01    //单次气压测量
#define MEAS_CTRL_TempMeasure           0x02    //单次温度测量
#define MEAS_CTRL_ContinuousPress       0x05    //连续气压测量
#define MEAS_CTRL_ContinuousTemp        0x06    //连续温度测量
#define MEAS_CTRL_ContinuousPressTemp   0x07    //连续气压温度测量

//FIFO_STS
#define SPL06_FIFO_FULL     0x02
#define SPL06_FIFO_EMPTY    0x01

//INT_STS
#define SPL06_INT_FIFO_FULL     0x04
#define SPL06_INT_TMP           0x02
#define SPL06_INT_PRS           0x01

//CFG_REG
#define SPL06_CFG_T_SHIFT   0x08    //oversampling times>8时必须使用
#define SPL06_CFG_P_SHIFT   0x04

#define SPL06_PSR_B2     0x00        //气压值
#define SPL06_PSR_B1     0x01
#define SPL06_PSR_B0     0x02
#define SPL06_TMP_B2     0x03        //温度值
#define SPL06_TMP_B1     0x04
#define SPL06_TMP_B0     0x05
		  
#define SPL06_PSR_CFG    0x06        //气压测量配置
#define SPL06_TMP_CFG    0x07        //温度测量配置
#define SPL06_MEAS_CFG   0x08        //测量模式配置
		  
#define SPL06_CFG_REG    0x09
#define SPL06_INT_STS    0x0A
#define SPL06_FIFO_STS   0x0B
		  
#define SPL06_RESET      0x0C
#define SPL06_ID         0x0D
		  
#define SPL06_COEF       0x10        //-0x21
#define SPL06_COEF_SRCE  0x28

#define SPL06DeviceAdd   (0x77<<1)        

/**************************************************************************
*结构体定义
**************************************************************************/ 
/*BMP280 校准参数*/
typedef struct  {

	INT16 C0;
	INT16 C1;
	INT32 C00;
	INT32 C10;
	INT16 C01;
	INT16 C11;
	INT16 C20;
	INT16 C21;
	INT16 C30;

	float kT;
	float kP;
}T_SPL06_calibPara;

/**************************************************************************
*全局变量申明
**************************************************************************/ 
extern T_SPL06_calibPara t_SPL06_calibPara;

2. .C函数

/**************************************************************************
*全局变量定义
**************************************************************************/ 
T_SPL06_calibPara t_SPL06_calibPara;

/**************************************************************************
*函数实现
**************************************************************************/


/**************************************************************************** 
    *  @function :  SPL06ReadRes_Buf
    *  @brief    :  SPL06 I2C 读取多字节函数 
    *  @input    : 
    *  @output   : 
    *  @return   : 
 
    *  @author   :  CaiNiao  2021/06/07 13:40
*****************************************************************************/ 
bool SPL06ReadRes_Buf(UINT8 ResAddr, UINT8 *pData,UINT8 DataLen)
{
	UINT8 i = 0;
	I2C1_Start();					//I2C start

	if (FALSE == I2C1_Write(SPL06DeviceAdd & 0xFE))	//写器件
		return FALSE;

	I2C1_Write(ResAddr);			//写入寄存器地址
	I2C1_Start();
	I2C1_Write(SPL06DeviceAdd | 0x01);					//读器件

	if (DataLen > 1)
	{//读取多个字节
		for (i = 0; i < DataLen; i++)
		{
			if (i < DataLen - 1)
				*(pData + i) = I2C1_Read(ACK);
			else
				*(pData + i) = I2C1_Read(NACK);
		}
	}
	else//读单个字节
		*(pData) = I2C1_Read(NACK);

	I2C1_Stop();
	return TRUE;
}

/**************************************************************************** 
    *  @function :  SPL06ReadRes_Single
    *  @brief    :  SPL06 I2C读取单字节函数 
    *  @input    : 
    *  @output   : 
    *  @return   : 
 
    *  @author   :  CaiNiao  2021/06/07 13:40
*****************************************************************************/
UINT8 SPL06ReadRes_Single(UINT8 ResAddr)
{
	UINT8 DataTemp = 0;
	I2C1_Start();					//I2C start

	if (FALSE == I2C1_Write(SPL06DeviceAdd & 0xFE))	//写器件
		return DataTemp;

	I2C1_Write(ResAddr);			//写入寄存器地址
	I2C1_Start();
	I2C1_Write(SPL06DeviceAdd | 0x01);					//读器件
	DataTemp = I2C1_Read(NACK);
	I2C1_Stop();
	return DataTemp;
}

/**************************************************************************** 
    *  @function :  SPL06WriteRes_Single
    *  @brief    :  SPL06 I2C WriteRes 
    *  @input    : 
    *  @output   : 
    *  @return   : 
 
    *  @author   :  CaiNiao  2021/06/07 13:40 
*****************************************************************************/ 
bool SPL06WriteRes_Single(UINT8 ResAddr,UINT8 DataTemp)
{
	I2C1_Start();					//I2C start

	if (FALSE == I2C1_Write(SPL06DeviceAdd & 0xFE))	//写器件
		return FALSE;

	I2C1_Write(ResAddr);			//写入寄存器地址
	I2C1_Write(DataTemp);			//写数据

	I2C1_Stop();					//I2C Stop
	return TRUE;
}

void SPL06_Config_Temperature(UINT8 rate, UINT8 oversampling, T_SPL06_calibPara *ptSPL06_calibPara)
{
	UINT8 temp;
	switch (oversampling)
	{
	case TMP_PRC_1:
		ptSPL06_calibPara->kT = 524288;
		break;
	case TMP_PRC_2:
		ptSPL06_calibPara->kT = 1572864;
		break;
	case TMP_PRC_4:
		ptSPL06_calibPara->kT = 3670016;
		break;
	case TMP_PRC_8:
		ptSPL06_calibPara->kT = 7864320;
		break;
	case TMP_PRC_16:
		ptSPL06_calibPara->kT = 253952;
		break;
	case TMP_PRC_32:
		ptSPL06_calibPara->kT = 516096;
		break;
	case TMP_PRC_64:
		ptSPL06_calibPara->kT = 1040384;
		break;
	case TMP_PRC_128:
		ptSPL06_calibPara->kT = 2088960;
		break;
	}

	SPL06WriteRes_Single(SPL06_TMP_CFG, rate | oversampling | 0x80);   //温度每秒128次测量一次
	if (oversampling > TMP_PRC_8)
	{
		temp = SPL06ReadRes_Single(SPL06_CFG_REG);
		SPL06WriteRes_Single(SPL06_CFG_REG, temp | SPL06_CFG_T_SHIFT);
	}
}

void SPL06_Config_Pressure(UINT8 rate, UINT8 oversampling, T_SPL06_calibPara *ptSPL06_calibPara)
{
	UINT8 temp;
	switch (oversampling)
	{
	case PM_PRC_1:
		ptSPL06_calibPara->kP = 524288;
		break;
	case PM_PRC_2:
		ptSPL06_calibPara->kP = 1572864;
		break;
	case PM_PRC_4:
		ptSPL06_calibPara->kP = 3670016;
		break;
	case PM_PRC_8:
		ptSPL06_calibPara->kP = 7864320;
		break;
	case PM_PRC_16:
		ptSPL06_calibPara->kP = 253952;
		break;
	case PM_PRC_32:
		ptSPL06_calibPara->kP = 516096;
		break;
	case PM_PRC_64:
		ptSPL06_calibPara->kP = 1040384;
		break;
	case PM_PRC_128:
		ptSPL06_calibPara->kP = 2088960;
		break;
	}

	SPL06WriteRes_Single(SPL06_PSR_CFG, rate | oversampling);
	if (oversampling > PM_PRC_8)
	{
		temp = SPL06ReadRes_Single(SPL06_CFG_REG);
		SPL06WriteRes_Single(SPL06_CFG_REG, temp | SPL06_CFG_P_SHIFT);
	}
}

void SPL06_Start(UINT8 mode)
{
	SPL06WriteRes_Single(SPL06_MEAS_CFG, mode);
}

/**************************************************************************** 
    *  @function :  SPL06_Init
    *  @brief    :  SPL06 初始化函数 
    *  @input    : 
    *  @output   : 
    *  @return   : 
 
    *  @author   :  CaiNiao  2021/06/07 13:40
*****************************************************************************/ 
void SPL06_Init(T_SPL06_calibPara *ptSPL06_calibPara)
{
	UINT8 coef[18];
	UINT8 id;

	id = SPL06ReadRes_Single(SPL06_ID);//ID 正常情况是0x10
	
	SPL06ReadRes_Buf(SPL06_COEF, coef, 18);
	ptSPL06_calibPara->C0 = ((INT16)coef[0] << 4) + ((coef[1] & 0xF0) >> 4);
	ptSPL06_calibPara->C0 = (ptSPL06_calibPara->C0 & 0x0800) ? (0xF000 | ptSPL06_calibPara->C0) : ptSPL06_calibPara->C0;
	ptSPL06_calibPara->C1 = ((INT16)(coef[1] & 0x0F) << 8) + coef[2];
	ptSPL06_calibPara->C1 = (ptSPL06_calibPara->C1 & 0x0800) ? (0xF000 | ptSPL06_calibPara->C1) : ptSPL06_calibPara->C1;
	ptSPL06_calibPara->C00 = ((INT32)coef[3] << 12) + ((INT32)coef[4] << 4) + (coef[5] >> 4);
	ptSPL06_calibPara->C00 = (ptSPL06_calibPara->C00 & 0x080000) ? (0xFFF00000 | ptSPL06_calibPara->C00) : ptSPL06_calibPara->C00;
	ptSPL06_calibPara->C10 = ((INT32)(coef[5] & 0x0F) << 16) + ((INT32)coef[6] << 8) + coef[7];
	ptSPL06_calibPara->C10 = (ptSPL06_calibPara->C10 & 0x080000) ? (0xFFF00000 | ptSPL06_calibPara->C10) : ptSPL06_calibPara->C10;
	ptSPL06_calibPara->C01 = ((INT16)coef[8] << 8) + coef[9];
	ptSPL06_calibPara->C11 = ((INT16)coef[10] << 8) + coef[11];
	ptSPL06_calibPara->C20 = ((INT16)coef[12] << 8) + coef[13];
	ptSPL06_calibPara->C21 = ((INT16)coef[14] << 8) + coef[15];
	ptSPL06_calibPara->C30 = ((INT16)coef[16] << 8) + coef[17];

	SPL06_Config_Pressure(PM_RATE_4, PM_PRC_32, ptSPL06_calibPara);
	SPL06_Config_Temperature(PM_RATE_4, TMP_PRC_8, ptSPL06_calibPara);

	SPL06_Start(MEAS_CTRL_ContinuousPressTemp); //启动连续的气压温度测量
}

/**************************************************************************** 
	*  @function :  SPL06_SoftReset
	*  @brief    :  SPL06软件复位
	*  @input    :
	*  @output   :
	*  @return   :

	*  @author   :  CaiNiao  2021/06/07 13:40
*****************************************************************************/
void SPL06_SoftReset()
{
	I2C1_Start();				//I2C start
	
	I2C1_Write(SPL06DeviceAdd & 0xFE);			//写入从机地址与写标志位
	I2C1_Write(SPL06_RESET);					//写入寄存器地址--芯片复位
	I2C1_Write(0x89);			//写数据
	I2C1_Stop();				//I2C Stop
}

INT32 SPL06_Get_Pressure_Adc()
{
	UINT8 buf[3];
	INT32 adc;

	SPL06ReadRes_Buf(SPL06_PSR_B2, buf, 3);
	adc = (INT32)(buf[0] << 16) + (INT32)(buf[1] << 8) + buf[2];
	adc = (adc & 0x800000) ? (0xFF000000 | adc) : adc;
	return adc;
}

INT32 SPL06_Get_Temperature_Adc()
{
	UINT8 buf[3];
	INT32 adc;

	SPL06ReadRes_Buf(SPL06_TMP_B2, buf, 3);
	adc = (INT32)(buf[0] << 16) + (INT32)(buf[1] << 8) + buf[2];
	adc = (adc & 0x800000) ? (0xFF000000 | adc) : adc;
	return adc;
}

float ReadSPL06_Pressure(T_SPL06_calibPara *ptSPL06_calibPara)
{
	float Traw_src,Praw_src;
	float Temp;
	float qua2, qua3;
	INT32  raw_temp,raw_press;

	raw_temp = SPL06_Get_Temperature_Adc();
	raw_press = SPL06_Get_Pressure_Adc();

	Traw_src = raw_temp/ptSPL06_calibPara->kT;
	Praw_src = raw_press/ptSPL06_calibPara->kP;

	//计算温度
	Temp = 0.5f*ptSPL06_calibPara->C0 + Traw_src * ptSPL06_calibPara->C1;

	//计算气压
	qua2 = ptSPL06_calibPara->C10 + Praw_src * (ptSPL06_calibPara->C20 + Praw_src * ptSPL06_calibPara->C30);
	qua3 = Traw_src * Praw_src * (ptSPL06_calibPara->C11 + Praw_src * ptSPL06_calibPara->C21);
	return ptSPL06_calibPara->C00 + Praw_src * qua2 + Traw_src * ptSPL06_calibPara->C01 + qua3;
}

3. 函数调用

1.芯片初始化
SPL06_Init(&t_SPL06_calibPara);//气压传感器初始化
2.气压读取
Press = ReadSPL06_Pressure(&t_SPL06_calibPara);//气压   
  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
匿名科创四轴同款传感器方案设计ICM20602+AK8975+SPL06-001 电赛必备!!! 四轴必备!!! 四轴起飞时,发出触发信号使导航模块开始工作,同时读取ICM20602的加速度计、陀螺仪数据,对数据卡尔曼滤波后姿态解算,对角度与角速度采取串级PID调节。 控制系统算法设计主要有ICM20602滤波算法,姿态解算算法、串级PID控制算法和定高部分控制算法。碍于篇幅所限,下面介绍最重要的串级PID控制算法和定高部分控制算法。 地理坐标系中重力的水平分量为零,仅用三轴陀螺仪和三轴加速度计无法计算出航向角,由于巡线机器人保持稳定飞行只需要横滚角(roll)和俯仰角(pitch),所以四元数转换成欧拉角。 定高控制算法采用的是增量式PID控制,定高控制的输出最后与姿态控制的输出叠加到四个电机的控制中。数据滤波使用的是低通滤波,采用近三次的平均值。为了防止姿态对激光测距的影响及减小高度控制对姿态控制的干扰使用欧拉角来校正高度值,即Hight=(float)Hight*(cos(roll)* cos(pitch))。将四元数转换后的欧拉角与陀螺仪测出来的角速度进行串级PID控制,其中欧拉角作为外环,角速度作为内环。外环的PID以及内环的PD设定值为测试数据值。由于内环的角速度控制不需要无静差,所以内环采用PD控制,为防止测量的误差造成较大影响,外环积分需要限幅。
SPL06是一种用于气压和温度测量的传感器,而Keil是SPL06的应用程序开发的工具。 SPL06是一种先进的气压和温度传感器,它可以在多种应用中进行使用。它可以通过测量大气压力来获取高度信息,并且可以测量环境的温度。SPL06采用了精密的精度和高度分辨率,使得它在气象、导航、气候监测等领域中非常有用。 Keil是一种用于SPL06应用程序开发的工具。它是一款集成开发环境(IDE),为开发人员提供了一个便捷的平台来编写、调试和测试代码。Keil支持多种编程语言,如汇编语言和C语言,为开发人员提供了丰富的开发工具和功能。 使用Keil,开发人员可以轻松地创建和管理SPL06传感器的应用程序。他们可以编写代码来读取传感器数据,并进行必要的处理和计算。Keil提供了调试功能,可以帮助开发人员快速定位和解决问题。此外,Keil还支持模拟和仿真功能,使得开发人员可以在不实际部署SPL06传感器的情况下进行开发和测试。 在使用SPL06和Keil进行开发时,开发人员需要注意传感器的规格和特性,以及合适的编码和算法来处理传感器数据。他们还应该遵循良好的软件开发实践,以确保应用程序的可靠性和稳定性。 总而言之,SPL06和Keil共同构成了一个强大的工具链,用于开发高性能、精确的气压和温度测量应用程序。通过合理利用这些工具,开发人员可以实现各种领域的应用和创新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值