242 lines
5.4 KiB
C
242 lines
5.4 KiB
C
/*
|
|
* Baro_MS5525DS_SPI.c
|
|
*
|
|
* Created on: July 12, 2020
|
|
* Author: lqh
|
|
*/
|
|
#include "Baro_MS5525DS_SPI.h"
|
|
#include "main.h"
|
|
|
|
#define M_PI (float)3.1415926535
|
|
|
|
#define RESET_CMD 0x1E
|
|
#define D1_CMD 0x48
|
|
#define D2_CMD 0x58
|
|
#define READ_ADC_CMD 0x00
|
|
#define READ_ROM_CMD 0xA0
|
|
|
|
/** us延时 */
|
|
static void Mdelay_us(uint16_t Time) {
|
|
uint8_t i;
|
|
uint8_t j;
|
|
while (Time--)
|
|
for (i = 0; i < 10; i++) {
|
|
j++;
|
|
}
|
|
}
|
|
|
|
/** reset ms5525*/
|
|
static void Baro_MS5525DS_Reset(Baro_MS5525DS_t *baro) {
|
|
uint8_t TxdBuf[2];
|
|
|
|
Mdelay_us(1000);
|
|
|
|
TxdBuf[0] = RESET_CMD;
|
|
SPI_DEV_select(baro->_dev);
|
|
SPI_DEV_transfer(baro->_dev, TxdBuf, 1, NULL, 0, 2);
|
|
SPI_DEV_unselect(baro->_dev);
|
|
|
|
Mdelay_us(3000);
|
|
|
|
}
|
|
|
|
static unsigned char crc4(uint16_t n_prom[]) {
|
|
int cnt; // simple counter
|
|
uint16_t n_rem; // crc reminder
|
|
uint16_t crc_read; // original value of the crc
|
|
unsigned char n_bit;
|
|
n_rem = 0x00;
|
|
crc_read = n_prom[7]; //save read CRC
|
|
n_prom[7] = (0xFF00 & (n_prom[7])); //CRC byte is replaced by 0
|
|
for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes
|
|
{ // choose LSB or MSB
|
|
if (cnt % 2 == 1)
|
|
n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00FF);
|
|
else
|
|
n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8);
|
|
for (n_bit = 8; n_bit > 0; n_bit--) {
|
|
if (n_rem & (0x8000)) {
|
|
n_rem = (n_rem << 1) ^ 0x3000;
|
|
} else {
|
|
n_rem = (n_rem << 1);
|
|
}
|
|
}
|
|
}
|
|
n_rem = (0x000F & (n_rem >> 12)); // // final 4-bit reminder is CRC code
|
|
n_prom[7] = crc_read; // restore the crc_read to its original place
|
|
return (n_rem ^ 0x00);
|
|
}
|
|
|
|
|
|
/** 读取prom的数据 */
|
|
static void Baro_MS5525DS_ReadProm(Baro_MS5525DS_t *baro) {
|
|
int i;
|
|
uint8_t TxdBuf[3];
|
|
uint8_t RxdBuf[3];
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
TxdBuf[0] = READ_ROM_CMD + i * 2;
|
|
SPI_DEV_select(baro->_dev);
|
|
SPI_DEV_transfer(baro->_dev, TxdBuf, 3, RxdBuf, 3, 2);
|
|
baro->C[i] = (RxdBuf[1] << 8) | RxdBuf[2];
|
|
SPI_DEV_unselect(baro->_dev);
|
|
|
|
Mdelay_us(20);
|
|
}
|
|
}
|
|
|
|
/** 读取转换后的数据 在这个函数之后应该打开下一步读取的转换 比如读取完D1后打开D2的转换 */
|
|
static uint32_t Baro_MS5525DS_ReadData(Baro_MS5525DS_t *baro) {
|
|
uint8_t TxdBuf[4];
|
|
uint8_t RxdBuf[4];
|
|
|
|
unsigned int ret_val;
|
|
|
|
TxdBuf[0] = READ_ADC_CMD;
|
|
SPI_DEV_select(baro->_dev);
|
|
SPI_DEV_transfer(baro->_dev, TxdBuf, 1, NULL, 0, 2);
|
|
SPI_DEV_transfer(baro->_dev, NULL, 0, RxdBuf, 3, 2);
|
|
Mdelay_us(10);
|
|
SPI_DEV_unselect(baro->_dev);
|
|
|
|
ret_val = ((RxdBuf[0] << 16) | (RxdBuf[1] << 8) | RxdBuf[2]) & 0x00FFFFFF;
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
/** MD5525DS写入指令 转换的指令需要外部调用*/
|
|
static void Baro_MS5525DS_WriteCmd(Baro_MS5525DS_t *baro, unsigned char cmd) {
|
|
uint8_t TxdBuf[2];
|
|
|
|
TxdBuf[0] = cmd;
|
|
|
|
SPI_DEV_select(baro->_dev);
|
|
SPI_DEV_transfer(baro->_dev, TxdBuf, 1, NULL, 0, 2);
|
|
SPI_DEV_unselect(baro->_dev);
|
|
}
|
|
|
|
/** cal temp */
|
|
static void Baro_MS5525DS_Cal_Temp(Baro_MS5525DS_t *baro) {
|
|
baro->dT = baro->D2 - baro->T_ref;
|
|
baro->temp = 2000 + ((baro->dT * (int64_t)baro->C[6]) >> baro->Q6);
|
|
if (baro->temp > 13000 || baro->temp < -4000 )
|
|
{
|
|
baro->temp = baro->ext_temp;
|
|
baro->dT = (((int64_t)baro->temp-2000) << baro->Q6) / (int64_t)baro->C[6];
|
|
}
|
|
}
|
|
|
|
/** cal pressure */
|
|
static void Baro_MS5525DS_Cal_TruePress(Baro_MS5525DS_t *baro) {
|
|
int64_t OFF;
|
|
int64_t SENS;
|
|
int64_t P;
|
|
|
|
int64_t TCO;
|
|
|
|
TCO = baro->dT*(int64_t)baro->C[4];
|
|
OFF = baro->OFF_T1 + (TCO >> baro->Q4);
|
|
|
|
//TCS
|
|
TCO = baro->dT*(int64_t)baro->C[3];
|
|
SENS = baro->SENS_T1 + (TCO >> baro->Q3);
|
|
|
|
P = ((((baro->D1 * SENS) >>21) - OFF) >> 15);
|
|
baro->pressure = P * 6895 /10000;
|
|
}
|
|
|
|
/** Baro_MS5525DS初始化 */
|
|
int Baro_MS5525DS_init(Baro_MS5525DS_t *baro, const char *name, SPI_DEV_t *dev,
|
|
MS5525DSO_t typ) {
|
|
int rslt;
|
|
baro->name = name;
|
|
baro->_dev = dev;
|
|
baro->_type = typ;
|
|
switch (typ)
|
|
{
|
|
case pp001DS:
|
|
baro->Q1 = 15;
|
|
baro->Q2 = 17;
|
|
baro->Q3 = 7;
|
|
baro->Q4 = 5;
|
|
baro->Q5 = 7;
|
|
baro->Q6 = 21;
|
|
break;
|
|
case pp015DS:
|
|
baro->Q1 = 17;
|
|
baro->Q2 = 19;
|
|
baro->Q3 = 5;
|
|
baro->Q4 = 3;
|
|
baro->Q5 = 7;
|
|
baro->Q6 = 22;
|
|
break;
|
|
}
|
|
baro->cnt = 0;
|
|
baro->last_cnt = 0;
|
|
baro->pps = 0;
|
|
|
|
SPI_DEV_begin(baro->_dev, -1);
|
|
|
|
Baro_MS5525DS_Reset(baro); //复位MS5525DS芯片
|
|
HAL_Delay(10);
|
|
Baro_MS5525DS_ReadProm(baro); //获取PROM数据
|
|
|
|
SPI_DEV_end(baro->_dev);
|
|
|
|
baro->ext_temp = 3000;
|
|
|
|
if (crc4(baro->C) != (baro->C[7] & 0xFF)) {
|
|
rslt = -1;
|
|
} else {
|
|
baro->T_ref = ((int32_t)baro->C[5] << baro->Q5);
|
|
baro->OFF_T1 = ((int64_t)baro->C[2] << baro->Q2);
|
|
baro->SENS_T1 = ((int64_t)baro->C[1] << baro->Q1);
|
|
|
|
HAL_Delay(10);
|
|
Baro_MS5525DS_WriteCmd(baro, D1_CMD); //开启MS5525DS的D1转换
|
|
HAL_Delay(10);
|
|
baro->D1 = Baro_MS5525DS_ReadData(baro);
|
|
Baro_MS5525DS_WriteCmd(baro, D2_CMD);
|
|
HAL_Delay(10);
|
|
baro->D2 = Baro_MS5525DS_ReadData(baro);
|
|
Baro_MS5525DS_WriteCmd(baro, D1_CMD);
|
|
baro->stage = 0;
|
|
rslt = 0;
|
|
}
|
|
|
|
Baro_MS5525DS_Cal_Temp(baro);
|
|
Baro_MS5525DS_Cal_TruePress(baro);
|
|
|
|
return rslt;
|
|
}
|
|
|
|
bool Baro_MS5525S_update(Baro_MS5525DS_t *baro) {
|
|
if (SPI_DEV_begin(baro->_dev, 0)) {
|
|
if (baro->stage) {
|
|
baro->D2 = Baro_MS5525DS_ReadData(baro);
|
|
Baro_MS5525DS_WriteCmd(baro, D1_CMD);
|
|
baro->stage = 0;
|
|
} else {
|
|
baro->D1 = Baro_MS5525DS_ReadData(baro);
|
|
Baro_MS5525DS_WriteCmd(baro, D2_CMD);
|
|
baro->stage = 1;
|
|
}
|
|
SPI_DEV_end(baro->_dev);
|
|
baro->cnt++;
|
|
|
|
Baro_MS5525DS_Cal_Temp(baro);
|
|
Baro_MS5525DS_Cal_TruePress(baro);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void Baro_MS5525S_stats(Baro_MS5525DS_t *Baro)
|
|
{
|
|
Baro->pps = Baro->cnt - Baro->last_cnt;
|
|
Baro->last_cnt = Baro->cnt;
|
|
}
|
|
|