acdt/board/Src/ms5803.c

371 lines
7.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ms5803.h"
PromVar PROMData;
volatile int32_t CurrentTemp = 0,CurrentPress = 0;
/* SPI handler declaration */
/* Buffer used for transmission */
uint8_t aTxBuffer[4];
uint8_t aRxBuffer[4];
uint8_t NSS_Select = 1;
//拉高所有片选脚
void setcs(void)
{
HAL_GPIO_WritePin(MS5803_NSS1_GPIO_Port,MS5803_NSS1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS2_GPIO_Port,MS5803_NSS2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS3_GPIO_Port,MS5803_NSS3_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS4_GPIO_Port,MS5803_NSS4_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(MS5803_NSS5_GPIO_Port,MS5803_NSS5_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS6_GPIO_Port,MS5803_NSS6_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS7_GPIO_Port,MS5803_NSS7_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(MS5803_NSS8_GPIO_Port,MS5803_NSS8_Pin,GPIO_PIN_RESET);
}
void clrcs(void)
{
switch(NSS_Select)
{
case 1 :
HAL_GPIO_WritePin(MS5803_NSS1_GPIO_Port,MS5803_NSS1_Pin,GPIO_PIN_RESET);
break;
case 2 :
HAL_GPIO_WritePin(MS5803_NSS2_GPIO_Port,MS5803_NSS2_Pin,GPIO_PIN_RESET);
break;
case 3 :
HAL_GPIO_WritePin(MS5803_NSS3_GPIO_Port,MS5803_NSS3_Pin,GPIO_PIN_RESET);
break;
case 4 :
HAL_GPIO_WritePin(MS5803_NSS5_GPIO_Port,MS5803_NSS5_Pin,GPIO_PIN_RESET);
break;
case 5 :
HAL_GPIO_WritePin(MS5803_NSS6_GPIO_Port,MS5803_NSS6_Pin,GPIO_PIN_RESET);
break;
case 6 :
HAL_GPIO_WritePin(MS5803_NSS7_GPIO_Port,MS5803_NSS7_Pin,GPIO_PIN_RESET);
break;
case 7 :
HAL_GPIO_WritePin(MS5803_NSS4_GPIO_Port,MS5803_NSS4_Pin,GPIO_PIN_SET);
break;
case 8 :
HAL_GPIO_WritePin(MS5803_NSS8_GPIO_Port,MS5803_NSS8_Pin,GPIO_PIN_SET);
break;
}
}
/************************************************
函数名称 Write_SPI_Byte
功 能 SPI写一个字节
参 数 Byte ---- 数据
返 回 值 Byte ---- 数据
*************************************************/
uint8_t ms5803_write_byte( uint8_t Byte )
{
uint8_t i;
for(i = 0;i < 8;i++)
{
MS5803_SCK(0);
delay_us(1); // 空等待
if(Byte & 0x80)
{
MS5803_MOSI(1);
}
else
{
MS5803_MOSI(0);
}
Byte <<= 1;
delay_us(1); // 空等待
MS5803_SCK(1);
delay_us(1); // 空等待
Byte |= MS5803_MISO;
}
MS5803_SCK(0);
return Byte;
}
/************************************************
函数名称 Read_SPI_Byte
功 能 SPI只读一个字节
参 数
返 回 值 temp ---- 数据
*************************************************/
uint8_t ms5803_read_byte(void)
{
uint8_t i;
uint8_t temp = 0;
for(i = 0;i < 8;i++)
{
MS5803_SCK(0);
delay_us(1); // 空等待
temp <<= 1;
temp |= MS5803_MISO;
//delay_us(1); // 空等待
MS5803_SCK(1);
delay_us(1); // 空等待
}
MS5803_SCK(0);
return temp;
}
//****************************************
//*功能向MS5803写入命令
//*参数CMD
//*返回True/False
static int writecmd(uint8_t CMD)
{
memset(aTxBuffer,0,sizeof(aTxBuffer));
aTxBuffer[0] = CMD;
clrcs();// pull CSB low to start the command
delay_tick(10);
ms5803_write_byte(CMD);
setcs();
return 1;
}
//****************************************
//*功能根据指令从MS5803读相应数据
//*参数CMD,Count
//*返回True/False
static int readcmddata(uint8_t CMD,uint8_t Count)
{
memset(aTxBuffer,0,sizeof(aTxBuffer));
aTxBuffer[0] = CMD;
clrcs();
delay_tick(10);
ms5803_write_byte(CMD);
for(int cnt = 0;cnt < Count+1;cnt++)
{
aRxBuffer[cnt] = ms5803_read_byte();
}
setcs();
return 1;
}
//****************************************
//*功能复位MS5803
//*参数:
//*返回:
static void resetdevice()
{
writecmd(RESET);
delay_ms(3); //必须延时3ms
}
//****************************************
//*功能获取PROM校准参数,只需要获取一次
//*参数:
//*返回:
static void getpromdata()
{
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof1,2);
PROMData.C1[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof2,2);
PROMData.C2[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof3,2);
PROMData.C3[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof4,2);
PROMData.C4[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof5,2);
PROMData.C5[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
memset(aRxBuffer,0,sizeof(aRxBuffer));
readcmddata(Cof6,2);
PROMData.C6[NSS_Select] = (aRxBuffer[0] << 8) + aRxBuffer[1];
}
//****************************************
//*功能MS5803初始化
//*参数:
//*返回:
void ms5803_init()
{
setcs();
SENSOR_SELECT(0);
NSS_Select = 1;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
NSS_Select = 2;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
NSS_Select = 3;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
SENSOR_SELECT(1);
NSS_Select = 4;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
NSS_Select = 5;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
NSS_Select = 6;
delay_tick(10);
//初始化代码
resetdevice();
getpromdata();
}
//****************************************
//*功能:获取温度和压力 MS5803-14BA
//*参数:
//*返回:
void start_calculation()
{
uint32_t D1,D2;
int32_t dT,TEMP;
int64_t OFF,SENS;
//转换压力
writecmd(CD1_256);
delay_ms(1); //必须延时1ms
readcmddata(ADC_Read,3);
D1 = (aRxBuffer[2] * pow(2,16)) + (aRxBuffer[1] * pow(2,8)) + aRxBuffer[0];
//转换温度
writecmd(CD2_256);
delay_ms(1); //必须延时1ms
readcmddata(ADC_Read,3);
D2 = (aRxBuffer[2] * pow(2,16)) + (aRxBuffer[1] * pow(2,8)) + aRxBuffer[0];
//计算温度
dT = D2 - (PROMData.C5[NSS_Select] * pow(2,8));
if(dT > 16777216)
{
dT = 16777216;
}
else if(dT < -16776960)
{
dT = -16776960;
}
TEMP = 2000 + ((((long long)dT) * PROMData.C6[NSS_Select]) / pow(2,23));
//计算压力
OFF = (PROMData.C2[NSS_Select] * pow(2,16)) + ((((long long)dT) * PROMData.C4[NSS_Select]) / pow(2,7));
if(OFF > 51538821120)
{
OFF = 51538821120;
}
else if(OFF < -34358689800)
{
OFF = -34358689800;
}
SENS = (((long long)PROMData.C1[NSS_Select]) * pow(2,15)) + ((((long long)dT) * PROMData.C3[NSS_Select]) / pow(2,8));
if(SENS > 17179607040)
{
SENS = 17179607040;
}
else if(SENS < -8589672450)
{
SENS = -8589672450;
}
__nop();
//Second order compensation
long T2 = 0,OFF2 = 0,SENS2 = 0;
if(TEMP < 2000)
{
T2 = (3*pow(dT,2)) / pow(2,33);
OFF2 = (3*pow((TEMP - 2000),2)) / pow(2,1);
SENS2 = (5*pow((TEMP - 2000),2)) / pow(2,3);
if(TEMP < -1500)
{
OFF2 += 7 * pow(TEMP + 1500,2);
SENS2 += 4 * pow((TEMP + 1500),2);
}
}
else
{
T2 = (7 * pow(dT,2)) / pow(2,37);
OFF2 = pow((TEMP - 2000),2) / pow(2,4);
}
CurrentTemp = TEMP - T2;
OFF -= OFF2;
SENS -= SENS2;
CurrentPress = (((((long long)SENS) * D1) / pow(2,21)) - OFF) / pow(2,15);
__nop();
}
void ms5803_task(void)
{
if(NSS_Select > 3)
{
SENSOR_SELECT(1);
delay_tick(10);
}
if(NSS_Select > 6)
{
SENSOR_SELECT(0);
delay_tick(10);
NSS_Select = 1;
}
start_calculation();
InputReg[NSS_Select + 12] = CurrentPress / 10;//压力数据存入
NSS_Select++;
}