This commit is contained in:
2024-09-26 22:32:20 +08:00
commit 097089ef4e
323 changed files with 135661 additions and 0 deletions
+287
View File
@@ -0,0 +1,287 @@
/*
* Baro_MS5611.c
*
* Created on: July 12, 2020
* Author: lqh
*/
#include "Baro_MS5611.h"
#include "main.h"
/* MS5611 Presure registers addresses */
#define PRESURE_RESET 0x1E
#define PRESURE_CVD1_OSR256 0x40
#define PRESURE_CVD1_OSR512 0x42
#define PRESURE_CVD1_OSR1024 0x44
#define PRESURE_CVD1_OSR2048 0x46
#define PRESURE_CVD1_OSR4096 0x48
#define PRESURE_CVD2_OSR256 0x50
#define PRESURE_CVD2_OSR512 0x52
#define PRESURE_CVD2_OSR1024 0x54
#define PRESURE_CVD2_OSR2048 0x56
#define PRESURE_CVD2_OSR4096 0x58
#define PRESURE_ADC_READ 0x00
#define PRESURE_PROM_SETUP 0xA0
#define PRESURE_PROM_COF1 0xA2
#define PRESURE_PROM_COF2 0xA4
#define PRESURE_PROM_COF3 0xA6
#define PRESURE_PROM_COF4 0xA8
#define PRESURE_PROM_COF5 0xAA
#define PRESURE_PROM_COF6 0xAC
#define PRESURE_PROM_CRC 0xAE
static unsigned char crc4(unsigned int n_prom[]) {
int cnt; // simple counter
unsigned int n_rem; // crc reminder
unsigned int 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);
}
/** MS5611压力补偿算法 */
void Ms5611_Pressure_Compensat(Baro_MS5611_t *Baro) {
int64_t dT;
int64_t dT1;
int64_t OFF, SENS;
int64_t TmpVar;
uint64_t UnsignTmpVar;
dT1 = (Baro->Ms5611_Cof[4] << 8);
dT = Baro->Ms5611_Raw_Temp - dT1;
TmpVar = (dT * Baro->Ms5611_Cof[5]) >> 16;
TmpVar = TmpVar >> 7;
Baro->temp = 2000 + TmpVar; //w温度最终输出
TmpVar = (Baro->Ms5611_Cof[3] * dT) >> 7;
UnsignTmpVar = (uint64_t) Baro->Ms5611_Cof[1] << 16;
OFF = (int64_t) UnsignTmpVar + TmpVar;
TmpVar = (Baro->Ms5611_Cof[2] * dT) >> 8;
SENS = ((uint64_t) Baro->Ms5611_Cof[0] << 15) + TmpVar;
TmpVar = (Baro->Ms5611_Raw_Pressure * SENS) >> 16;
TmpVar = (TmpVar >> 5) - OFF;
TmpVar = TmpVar >> 15;
Baro->pressure = (int32_t) TmpVar;
Baro->seq++;
}
/** MS5611气压高度计初始化 */
int MS5611_Pressure_init(Baro_MS5611_t *Baro, const char *name, SPI_DEV_t *dev) {
uint8_t TxdBuf[4];
uint8_t RxdBuf[4];
unsigned int C[8];
int rslt;
int i;
Baro->name = name;
Baro->_dev = dev;
Baro->status = 0;
Baro->cnt = 0;
Baro->last_cnt = 0;
Baro->pps = 0;
Baro->seq = 0;
SPI_DEV_begin(dev, -1);
//Reset Chip(Command: Just Specifying an Address)
TxdBuf[0] = PRESURE_RESET;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 1, NULL, 0, 2);
SPI_DEV_unselect(dev);
//Wait 2.8(5)ms to be sure chip reseted
HAL_Delay(5);
//Read PROM Data(Start Measure)
//Read C1
TxdBuf[0] = PRESURE_PROM_COF1;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[0] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read C2
TxdBuf[0] = PRESURE_PROM_COF2;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[1] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read C3
TxdBuf[0] = PRESURE_PROM_COF3;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[2] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read C4
TxdBuf[0] = PRESURE_PROM_COF4;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[3] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read C5
TxdBuf[0] = PRESURE_PROM_COF5;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[4] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read C6
TxdBuf[0] = PRESURE_PROM_COF6;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Cof[5] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read CRC
TxdBuf[0] = PRESURE_PROM_CRC;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
C[7] = (RxdBuf[1] << 8 | RxdBuf[2]);
//Read Setup State
TxdBuf[0] = PRESURE_PROM_SETUP;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 3, RxdBuf, 3, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Setup = (RxdBuf[1] << 8 | RxdBuf[2]);
//check CRC and setup
C[0] = Baro->Ms5611_Setup;
for (i = 0; i < 6; ++i) {
C[i + 1] = Baro->Ms5611_Cof[i];
}
if ((crc4(C) & 0x0F) != (C[7] & 0x0F)) {
rslt = -1;
} else {
//Convert D2 Start 1 time(osr = 4096, 0.012mbar)
TxdBuf[0] = PRESURE_CVD2_OSR4096;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 1, RxdBuf, 1, 2);
SPI_DEV_unselect(dev);
//Wait 10ms to be sure D2 conver over
HAL_Delay(10);
//Read D2 information
TxdBuf[0] = PRESURE_ADC_READ;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 4, RxdBuf, 4, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Raw_Temp = ((RxdBuf[1] << 16) | (RxdBuf[2] << 8)
| RxdBuf[3]);
//Convert D1 Start 1 time(osr = 4096)
TxdBuf[0] = PRESURE_CVD1_OSR4096;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 1, NULL, 0, 2);
SPI_DEV_unselect(dev);
//Wait 10ms to be sure D1 conver over
HAL_Delay(10);
//Read D1 information
TxdBuf[0] = PRESURE_ADC_READ;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 4, RxdBuf, 4, 2);
SPI_DEV_unselect(dev);
Baro->Ms5611_Raw_Pressure = ((RxdBuf[1] << 16) | (RxdBuf[2] << 8)
| RxdBuf[3]);
//Preasure & Temperature compensat
Ms5611_Pressure_Compensat(Baro);
//Init Preasure State Flag
Baro->PresurReadFlag = MS5611_D1_CONVERTING;
//Convert D1 Start 1 time(osr = 4096)
TxdBuf[0] = PRESURE_CVD1_OSR4096;
SPI_DEV_select(dev);
SPI_DEV_transfer(dev, TxdBuf, 1, NULL, 0, 2);
SPI_DEV_unselect(dev);
rslt = 0;
}
SPI_DEV_end(dev);
return rslt;
}
/** MS5611数据读取 */
int MS5611_Pressure_update(Baro_MS5611_t *Baro) {
uint8_t TxdBuf[6];
uint8_t RxdBuf[6];
uint32_t ms5611_read_data;
int rslt;
if (SPI_DEV_begin(Baro->_dev, 0)) //进入临界区
{
TxdBuf[0] = PRESURE_ADC_READ;
SPI_DEV_select(Baro->_dev);
SPI_DEV_transfer(Baro->_dev, TxdBuf, 4, RxdBuf, 4, 2);
SPI_DEV_unselect(Baro->_dev);
if (((RxdBuf[0] << 16) | (RxdBuf[1] << 8) | RxdBuf[2]) != 0) {
ms5611_read_data =
((RxdBuf[1] << 16) | (RxdBuf[2] << 8) | RxdBuf[3]);
if (Baro->PresurReadFlag == MS5611_D1_CONVERTING) { //read d1, and start d2
Baro->Ms5611_Raw_Pressure = ms5611_read_data;
Baro->PresurReadFlag = MS5611_D2_CONVERTING;
TxdBuf[0] = PRESURE_CVD2_OSR4096; //Convert D2 Start 1 time(osr = 4096)
} else { //read d2, and start d1
Baro->Ms5611_Raw_Temp = ms5611_read_data;
Baro->PresurReadFlag = MS5611_D1_CONVERTING;
TxdBuf[0] = PRESURE_CVD1_OSR4096; //Convert D1 Start 1 time(osr = 4096)
}
SPI_DEV_select(Baro->_dev);
SPI_DEV_transfer(Baro->_dev, TxdBuf, 1, NULL, 0, 2);
SPI_DEV_unselect(Baro->_dev);
//Preasure & Temperature compensat
Ms5611_Pressure_Compensat(Baro);
rslt = 0;
Baro->cnt++;
} else {
rslt = -2;
}
SPI_DEV_end(Baro->_dev);
} else {
rslt = -1;
}
return rslt;
}
void MS5611_Pressure_stats(Baro_MS5611_t *Baro) {
Baro->pps = Baro->cnt - Baro->last_cnt;
Baro->last_cnt = Baro->cnt;
}