Files
motor/Common/spi/Baro_MS5525DS_SPI.c
T
2024-09-26 22:32:20 +08:00

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;
}