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