一、基礎(chǔ)知識(shí)
首先,MS5611是什么
MS5611氣壓傳感器是由MEAS(瑞士)推出的一款SPI和I2C總線接口的新一代高分辨率氣壓傳感器,分辨率可達(dá)到10cm。該傳感器模塊包括一個(gè)高線性度的壓力傳感器和一個(gè)超低功耗的24位Σ模數(shù)轉(zhuǎn)換器(工廠校準(zhǔn)系數(shù))。
計(jì)算溫度:
D2 = MS5611_DO_Conversion(OSR_Temp);
delay_ms(10);
dT = D2 - (((u32)c5)*256) ;
Temperature = 2000 + dT*((float)c6)/8388608 ;
計(jì)算大氣壓:
D1 = MS5611_DO_Conversion(OSR_Pressure) ;
delay_ms(10) ;
OFF = (((int64_t)c2)*65536 + (((int64_t)c4*dT)/128)) ;
SENS = (((int64_t)c1)*32768) + (((int64_t)c3*dT)/256) ;
if(Temperature 《 2000) //μ±???è?μTEMPD?óú2000ê±Dèòa×????è213¥
{
T2 = (float)(dT*dT)/0x80000000 ;
Aux = (Temperature - 2000)*(Temperature - 2000) ;
OFF2 = 2.5f*Aux ;
SENS2 = 1.25f*Aux ;
if(Temperature 《 -1500) //μ±???è?μTEMPD?óú-1500ê±Dèòa×????è213¥
{
Aux = (Temperature+1500)*(Temperature+1500);
OFF2 = OFF2 + 7*Aux;
SENS2 = SENS2 + 5.5f*Aux;
}
}
else
{
T2 = 0 ;
OFF2 = 0 ;
SENS2= 0 ;
}
Temperature = Temperature - T2 ;
OFF = OFF - OFF2 ;
SENS = SENS - SENS2 ;
Pressure = ((D1*SENS)/2097152 - OFF)/32768 ;
海拔計(jì)算:
Altitude = (44330.0f*(1.0f - pow((float)Pressure/101325.0f, 0.190295f))) ;
MS5611主要用于智能手機(jī)、海拔高度測(cè)量和導(dǎo)航輔助,做四軸的朋友一般都了解。
其次,對(duì)于飛行器的姿態(tài)控制,我們使用GY-86 10DOF 的模塊,里面帶有MS5611 + MPU6050 + HMC5883,通過(guò)IIC協(xié)議讀取數(shù)據(jù)進(jìn)行操作。MS5611掛在MPU5060的從I2C接口上。MS5611的I2C地址為0b111011Cx,其中C比特位由CSB引腳決定,為CSB引腳的補(bǔ)碼值(取反)。GY-86上 MS5611的CSB引腳接地,所以CSB引腳值為0,8位I2C地址為0b1110111x(0xEE),7位I2C地址為 0b1110111(0x77)。
這里,0b表示二進(jìn)制,0x表示十六進(jìn)制,數(shù)字前加0表示八進(jìn)制。例如:
‘\077’ //是8進(jìn)制表示‘ ’,0可以省略,因?yàn)镃,C++規(guī)定不允許使用斜杠加10進(jìn)制數(shù)來(lái)表示字符;
‘\0x3F’ //是16進(jìn)制表示。這些都是C語(yǔ)言中的基礎(chǔ)
二、運(yùn)行結(jié)果
三、相應(yīng)模塊
程序涉及的模塊有:
RCC:復(fù)位及時(shí)鐘控制模塊,用于初始化STM32 USART外設(shè)時(shí)鐘及IO口復(fù)用時(shí)鐘;
IIC:模擬IIC 協(xié)議,好多人都說(shuō)STM32的硬件IIC模塊用不了,主要是因?yàn)镾TM32 的硬件 IIC 模塊有個(gè)天生的 BUG,就是不能被中斷,也就是IIC要處于中斷的最高級(jí),ST在自己后來(lái)的 DataSheet 中已經(jīng)證實(shí)了這一點(diǎn)。
Delay:利用系統(tǒng)時(shí)鐘SysTick,也號(hào)稱“滴答”,寫的延時(shí)模塊;
USART:串口模塊;
MS5611:MS5611模塊配置。
四:代碼
RCC
#include “Rcc.h”
void RCC_Init(void)
{
ErrorStatus HSEStartUpStatus;
//定義枚舉類型錯(cuò)誤狀態(tài)變量
RCC_DeInit();//復(fù)位系統(tǒng)時(shí)鐘設(shè)置
RCC_HSEConfig(RCC_HSE_ON);
//打開(kāi)外部高速時(shí)鐘晶振,使能HSE
/*RCC_HSE_ON 開(kāi)
_off 關(guān) _bypass hse晶振被外部時(shí)鐘旁路*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/*RCC_WaitForHSEStartUp()返回一個(gè)ErrorStatus枚舉值,
success好,error未好*/
if(HSEStartUpStatus == SUCCESS)//HES就緒
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//AHB時(shí)鐘(HCLK)=系統(tǒng)時(shí)鐘
RCC_PCLK1Config(RCC_HCLK_Div2);
//設(shè)置低速AHB時(shí)鐘(APB1)為HCLK的2分頻
RCC_PCLK2Config(RCC_HCLK_Div1);
//設(shè)置高速AHB時(shí)鐘(APB2)=HCLK時(shí)鐘
FLASH_SetLatency(FLASH_Latency_2);
//設(shè)置FLASH延時(shí)周期數(shù)為2
//使能領(lǐng)取指緩存
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//設(shè)置PLL時(shí)鐘源及倍頻系數(shù),為HSE的9倍頻 8MHz * 9 = 72MHz
/*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul)
RCC_PLLSource_HSI_Div2 pll輸入時(shí)鐘=hsi/2;
RCC_PLLSource_HSE_Div1 pll輸入時(shí)鐘 =hse
RCC_PLLSource_HSE_Div2 pll輸入時(shí)鐘=hse/2
RCC_PLLMul_2 ------_16 pll輸入時(shí)鐘*2---16
pll輸出時(shí)鐘不得超過(guò)72MHZ*/
RCC_PLLCmd(ENABLE);
//ENABLE / DISABLE
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待PLL輸出穩(wěn)定
/*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG) 檢查指定RCC標(biāo)志位
返回SET OR RESET
RCC_FLAG_HSIRDY HSI晶振就緒
RCC_FLAG_HSERDY
RCC_FLAG_PLLRDY
RCC_FLAG_LSERDY
RCC_FLAG_LSIRDY.。。。。。.*/
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//設(shè)置PLL為系統(tǒng)時(shí)鐘源
/*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) 設(shè)置系統(tǒng)時(shí)鐘
RCC_SYSCLKSource_HSI
RCC_SYSCLKSource_HSE
RCC_SYSCLKSource_PLLCLK 選HSI HSE PLL 作為系統(tǒng)時(shí)鐘*/
while(RCC_GetSYSCLKSource() != 0x08);
//判斷PLL是否是系統(tǒng)時(shí)鐘
/*u8 RCC_GetSYSCLKSource(void) 返回用作系統(tǒng)時(shí)鐘的時(shí)鐘源
0x00:HSI 0x04:HSE 0x08:PLL */
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_AFIO |
RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//U2 U3 時(shí)鐘在APB1
//打開(kāi)GPIO時(shí)鐘,復(fù)用功能,串口1的時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1時(shí)鐘
//好奇怪,是因?yàn)楣俜降膸?kù)函數(shù)更新?
//不是說(shuō)F10X系列只有一個(gè)CAN,而F4有CAN1 CAN2 嗎?
//怎么他的系統(tǒng)配置文件里面是can1?????
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //時(shí)鐘使能
/*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)
enable 或 disable apb2 外設(shè)時(shí)鐘
RCC_APB2Periph_AFIO 功能復(fù)用IO 時(shí)鐘
RCC_APB2Periph_GPIOA/B/C/D/E GPIOA/B/C/D/E 時(shí)鐘
RCC_APB2Periph_ADC1/ADC2 ADC1/2 時(shí)鐘
RCC_APB2Periph_TIM1
RCC_APB2Periph_SPI1
RCC_APB2Periph_USART1
RCC_APB2Periph_ALL 全部APB2外設(shè)時(shí)鐘*/
}
IIC
#include “myIIC.h”
unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address); //從24c02的地址address中讀取一個(gè)字節(jié)數(shù)據(jù)
void I2C_WriteByte(unsigned char DeviceAddr,unsigned char address,unsigned char info);
void I2C_NoAddr_WriteByte(unsigned char DeviceAddr,unsigned char info);
void I2C_Read_MultiBytes(unsigned char DeviceAddr,unsigned char address,unsigned char BytesNum,unsigned char * OutDate );
uint16_t I2C_Read_2Bytes(unsigned char DeviceAddr,unsigned char address);
uint32_t I2C_Read_3Bytes(unsigned char DeviceAddr,unsigned char address);
void delay_nop(void);
void delay2(unsigned int x);
void iic_start(void);
void iic_stop(void);
void iic_writex(unsigned char j);
unsigned char iic_readx(void);
void iic_check_ACK(void);
void iic_SDA_Set_Dir(unsigned char io_set);
void I2C_GPIO_Configuration(void);
void delay2(unsigned int x)
{
unsigned int i;
for(i=0;i《x;i++);
}
void delay_nop(void)
{
unsigned int i=10; //i=10延時(shí)1.5us//這里可以優(yōu)化速度 ,經(jīng)測(cè)試最低到5還能寫入
while(i--);
}
void iic_start(void)
{
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
//SDA=0;
GPIO_ResetBits(GPIOB, SDA);
delay_nop();
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
}
void iic_stop(void)
{
//SDA=0;
GPIO_ResetBits(GPIOB, SDA);
delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
}
void iic_writex(unsigned char j)
{
unsigned char i,temp,temp1;
temp=j;
//iic_SDA_Set_Dir(0);
for (i=0;i《8;i++)
{
temp1=temp & 0x80;
temp=temp《《1;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=CY;
if(temp1==0x80)
{GPIO_SetBits(GPIOB, SDA);}
else
{GPIO_ResetBits(GPIOB, SDA);}
delay_nop();
// SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
}
//iic_SDA_Set_Dir(0);
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
}
unsigned char iic_readx(void)
{
unsigned char i,j,k=0;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
iic_SDA_Set_Dir(1);
for (i=0;i《8;i++)
{
delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
//if (SDA==1) j=1;
if( GPIO_ReadInputDataBit(GPIOB,SDA)==1 )
{j=1;}
else
{j=0;}
k=(k《《1)|j;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
}
iic_SDA_Set_Dir(0);
delay_nop();
return(k);
}
void iic_check_ACK(void)//檢測(cè)從機(jī)應(yīng)答信號(hào)
{
unsigned int i=0;
iic_SDA_Set_Dir(1);
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
while ((GPIO_ReadInputDataBit(GPIOB,SDA)==1)&&(i《5000))i++;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
iic_SDA_Set_Dir(0);
}
void I2C_Ack(void)
{
GPIO_ResetBits(GPIOB,SCL);
delay_nop();
GPIO_ResetBits(GPIOB,SDA);
delay_nop();
GPIO_SetBits(GPIOB,SCL);
delay_nop();
GPIO_ResetBits(GPIOB,SCL);
delay_nop();
}
void I2C_NoAck(void)
{
GPIO_ResetBits(GPIOB,SCL);
delay_nop();
GPIO_SetBits(GPIOB,SDA);
delay_nop();
GPIO_SetBits(GPIOB,SCL);
delay_nop();
GPIO_ResetBits(GPIOB,SCL);
delay_nop();
}
unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address)
{
unsigned char i;
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(address);
iic_check_ACK();
iic_start();
iic_writex(DeviceAddr+1);
iic_check_ACK();
i=iic_readx();
iic_stop();
//delay2(10);
delay2(50);
return(i);
}
void I2C_WriteByte(unsigned char DeviceAddr,unsigned char address,unsigned char info)
{
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(address);
iic_check_ACK();
iic_writex(info);
iic_check_ACK();
iic_stop();
//delay2(50);
delay2(250);
}
void I2C_NoAddr_WriteByte(unsigned char DeviceAddr,unsigned char info)
{
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(info);
iic_check_ACK();
iic_stop();
//delay2(50);
delay2(250);
}
void I2C_Read_MultiBytes(unsigned char DeviceAddr,unsigned char address,unsigned char BytesNum,unsigned char * OutDate )
{
unsigned char i;
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(address);
iic_check_ACK();
iic_start();
iic_writex(DeviceAddr+1);
iic_check_ACK();
for(i=0;i《BytesNum;i++)
{
OutDate[i]=iic_readx();
if(i+1《BytesNum) I2C_Ack();else I2C_NoAck();//最后一個(gè)字節(jié)無(wú)需應(yīng)答
}
iic_stop();
delay2(250);
}
uint16_t I2C_Read_2Bytes(unsigned char DeviceAddr,unsigned char address)
{
unsigned char i,data_temp1,data_temp2;
uint16_t data16;
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(address);
iic_check_ACK();
iic_start();
iic_writex(DeviceAddr+1);
iic_check_ACK();
data_temp1=iic_readx();
I2C_Ack();
data_temp2=iic_readx();
I2C_NoAck();//最后一個(gè)字節(jié)無(wú)需應(yīng)答
iic_stop();
//delay2(10);
delay2(250);
data16=(data_temp1《《8)|data_temp2;
return data16;}
uint32_t I2C_Read_3Bytes(unsigned char DeviceAddr,unsigned char address)
{
unsigned char i,data_temp1,data_temp2,data_temp3;
uint32_t data32;
iic_start();
iic_writex(DeviceAddr);
iic_check_ACK();
iic_writex(address);
iic_check_ACK();
iic_start();
iic_writex(DeviceAddr+1);
iic_check_ACK();
data_temp1=iic_readx();
I2C_Ack();
data_temp2=iic_readx();
I2C_Ack();
data_temp3=iic_readx();
I2C_NoAck();//最后一個(gè)字節(jié)無(wú)需應(yīng)答
iic_stop();
//delay2(10);
delay2(250);
data32=data_temp1*65535+data_temp2*256+data_temp3;
return data32;}
void I2C_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = SCL; //24C02 SCL
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作為輸出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void iic_SDA_Set_Dir(unsigned char io_set) //SDA引腳輸入輸出設(shè)置
{
GPIO_InitTypeDef GPIO_InitStructure;
if(io_set==0)
{
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作為輸出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else if(io_set==1)
{
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作為輸入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else
{;}
}
DELAY
#include “delay.h”
static u8 fac_us=0; //us延時(shí)倍乘數(shù)
static u16 fac_ms=0; //ms延時(shí)倍乘數(shù),在ucos下,代表每個(gè)節(jié)拍的ms數(shù)
//初始化延遲函數(shù)
//SYSTICK的時(shí)鐘固定為HCLK時(shí)鐘的1/8
//SYSCLK:系統(tǒng)時(shí)鐘
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時(shí)鐘 HCLK/8
fac_us=SystemCoreClock/8000000; //為系統(tǒng)時(shí)鐘的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每個(gè)ms需要的systick時(shí)鐘數(shù)
}
//延時(shí)nus
//nus為要延時(shí)的us數(shù)。
void delay_us(u32 nus)
{
u32 temp;
SysTick-》LOAD=nus*fac_us; //時(shí)間加載
SysTick-》VAL=0x00; //清空計(jì)數(shù)器
SysTick-》CTRL|=SysTick_CTRL_ENABLE_Msk ; //開(kāi)始倒數(shù)
do
{
temp=SysTick-》CTRL;
}while((temp&0x01)&&?。╰emp&(1《《16))); //等待時(shí)間到達(dá)
SysTick-》CTRL&=~SysTick_CTRL_ENABLE_Msk; //關(guān)閉計(jì)數(shù)器
SysTick-》VAL =0X00; //清空計(jì)數(shù)器
}
//延時(shí)nms
//注意nms的范圍
//SysTick-》LOAD為24位寄存器,所以,最大延時(shí)為:
//nms《=0xffffff*8*1000/SYSCLK
//SYSCLK單位為Hz,nms單位為ms
//對(duì)72M條件下,nms《=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick-》LOAD=(u32)nms*fac_ms; //時(shí)間加載(SysTick-》LOAD為24bit)
SysTick-》VAL =0x00; //清空計(jì)數(shù)器
SysTick-》CTRL|=SysTick_CTRL_ENABLE_Msk ; //開(kāi)始倒數(shù)
do
{
temp=SysTick-》CTRL;
}while((temp&0x01)&&?。╰emp&(1《《16))); //等待時(shí)間到達(dá)
SysTick-》CTRL&=~SysTick_CTRL_ENABLE_Msk; //關(guān)閉計(jì)數(shù)器
SysTick-》VAL =0X00; //清空計(jì)數(shù)器
}
MS5611
#include “MS5611.h”
/*宏定義------------------------------------------------------------------*/
//定義器件在IIC總線中的從地址,根據(jù)CSB引腳不同修改
//#define MS561101BA_ADDR 0xec //CBR=1 0x76 I2C address when CSB is connected to HIGH (VCC)
#define MS561101BA_ADDR 0xee //CBR=0 0x77 I2C address when CSB is connected to LOW (GND)
// 定義MS561101BA內(nèi)部地址
// registers of the device
#define MS561101BA_D1 0x40
#define MS561101BA_D2 0x50
#define MS561101BA_RESET 0x1E
// D1 and D2 result size (bytes)
#define MS561101BA_D1D2_SIZE 3
// OSR (Over Sampling Ratio) constants
#define MS561101BA_OSR_256 0x00
#define MS561101BA_OSR_512 0x02
#define MS561101BA_OSR_1024 0x04
#define MS561101BA_OSR_2048 0x06
#define MS561101BA_OSR_4096 0x08
//#define MS561101BA_D1_OSR_256 0x40
//#define MS561101BA_D1_OSR_512 0x42
//#define MS561101BA_D1_OSR_1024 0x44
//#define MS561101BA_D1_OSR_2048 0x46
#define MS561101BA_D1_OSR_4096 0x48
//#define MS561101BA_D2_OSR_256 0x50
//#define MS561101BA_D2_OSR_512 0x52
//#define MS561101BA_D2_OSR_1024 0x54
//#define MS561101BA_D2_OSR_2048 0x56
#define MS561101BA_D2_OSR_4096 0x58
#define MS561101BA_PROM_BASE_ADDR 0xA0 // by adding ints from 0 to 6 we can read all the prom configuration values.
// C1 will be at 0xA2 and all the subsequent are multiples of 2
#define MS561101BA_PROM_REG_COUNT 6 // number of registers in the PROM
#define MS561101BA_PROM_REG_SIZE 2 // size in bytes of a prom registry.
/*變量聲明----------------------------------------------------------------*/
uint16_t Cal_C[7]; //用于存放PROM中的6組數(shù)據(jù)
uint32_t D1_Pres,D2_Temp; // 存放數(shù)字壓力和溫度
float Pressure; //溫度補(bǔ)償大氣壓
float dT,Temperature,Temperature2;//實(shí)際和參考溫度之間的差異,實(shí)際溫度,中間值
double OFF,SENS; //實(shí)際溫度抵消,實(shí)際溫度靈敏度
float Aux,OFF2,SENS2; //溫度校驗(yàn)值
uint32_t ex_Pressure; //串口讀數(shù)轉(zhuǎn)換值
uint8_t exchange_num[8];
/*函數(shù)聲明----------------------------------------------------------------*/
void MS561101BA_Reset(void);
void MS561101BA_readPROM(void);
uint32_t MS561101BA_DO_CONVERSION(u8 command);
void MS561101BA_GetTemperature(u8 OSR_Temp);
void MS561101BA_GetPressure(u8 OSR_Pres);
void MS561101BA_Init(void);
void SampleANDExchange(void);
/************************************************************
* 函數(shù)名:MS561101BA_Reset
* 描述 : 復(fù)位
* 輸入 :無(wú)
* 輸出 :無(wú)
*/
void MS561101BA_Reset(void)
{
I2C_NoAddr_WriteByte(MS561101BA_ADDR,MS561101BA_RESET);
}
/************************************************************
* 函數(shù)名:MS561101BA_readPROM
* 描述 : 從PROM讀取出廠校準(zhǔn)數(shù)據(jù)
* 輸入 :無(wú)
* 輸出 :無(wú)
*/
void MS561101BA_readPROM(void)
{ uint16_t value=0;u8 temp1[2]={0};
u8 i;
for (i=0;i《=MS561101BA_PROM_REG_COUNT;i++)
{
// I2C_Read_MultiBytes(MS561101BA_ADDR,MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE),2,temp1);
//value=temp1[0]《《8|temp1[1];
//Cal_C[i]=value;
Cal_C[i]=I2C_Read_2Bytes(MS561101BA_ADDR,MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE));
}
printf(“\n The MS561101BA is reading PROM : \r\n”);
printf(“\r\nC1 = %d\r\nC2 = %d\r\nC3 = %d\r\nC4 = %d\r\nC5 = %d\r\nC6 = %d\r\n”,Cal_C[1],Cal_C[2],Cal_C[3],Cal_C[4],Cal_C[5],Cal_C[6]);
}
/************************************************************
* 函數(shù)名:MS561101BA_DO_CONVERSION
* 描述 :
* 輸入 :無(wú)
* 輸出 :無(wú)
*/
uint32_t MS561101BA_DO_CONVERSION(uint8_t command)
{
uint32_t conversion;
I2C_NoAddr_WriteByte(MS561101BA_ADDR,command);
delay_ms(10);//延時(shí),去掉數(shù)據(jù)錯(cuò)誤
conversion=I2C_Read_3Bytes(MS561101BA_ADDR,0);
return conversion;
}
/************************************************************
* 函數(shù)名:MS561101BA_GetTemperature
* 描述 : 讀取數(shù)字溫度
* 輸入 :過(guò)采樣率
* 輸出 :無(wú)
*/
void MS561101BA_GetTemperature(u8 OSR_Temp)
{
D2_Temp= MS561101BA_DO_CONVERSION(OSR_Temp);
delay_ms(100);
dT=D2_Temp - (((uint32_t)Cal_C[5])《《8);
Temperature=2000+dT*((uint32_t)Cal_C[6])/8388608; //算出溫度值的100倍,2001表示20.01°
}
/************************************************************
* 函數(shù)名:MS561101BA_GetPressure
* 描述 : 讀取數(shù)字氣壓
* 輸入 :過(guò)采樣率
* 輸出 :無(wú)
*/
void MS561101BA_GetPressure(u8 OSR_Pres)
{
D1_Pres= MS561101BA_DO_CONVERSION(OSR_Pres);
delay_ms(100);
OFF=(uint32_t)(Cal_C[2]《《16)+((uint32_t)Cal_C[4]*dT)/128.0;
SENS=(uint32_t)(Cal_C[1]《《15)+((uint32_t)Cal_C[3]*dT)/256.0;
//溫度補(bǔ)償
if(Temperature 《 2000)// second order temperature compensation when under 20 degrees C
{
Temperature2 = (dT*dT) / 0x80000000;
Aux = (Temperature-2000)*(Temperature-2000);
OFF2 = 2.5*Aux;
SENS2 = 1.25*Aux;
if(Temperature 《 -1500)
{
Aux = (Temperature+1500)*(Temperature+1500);
OFF2 = OFF2 + 7*Aux;
SENS2 = SENS + 5.5*Aux;
}
}else //(Temperature 》 2000)
{
Temperature2 = 0;
OFF2 = 0;
SENS2 = 0;
}
Temperature = Temperature - Temperature2;
OFF = OFF - OFF2;
SENS = SENS - SENS2;
Pressure=(D1_Pres*SENS/2097152.0-OFF)/32768.0;
}
/************************************************************
* 函數(shù)名:MS561101BA_Init
* 描述 : MS561101BA初始化
* 輸入 :無(wú)
* 輸出 :無(wú)
*/
void MS561101BA_Init(void)
{
MS561101BA_Reset();
delay_ms(100);
MS561101BA_readPROM();
delay_ms(100);
}
/************************************************************
* 函數(shù)名:SampleANDExchange
* 描述 : 讀取數(shù)據(jù)并轉(zhuǎn)換串口發(fā)送
* 輸入 :無(wú)
* 輸出 :無(wú)
*/
void SampleANDExchange(void)
{
uint8_t i=0;
MS561101BA_GetTemperature(MS561101BA_D2_OSR_4096);//0x58
MS561101BA_GetPressure(MS561101BA_D1_OSR_4096); //0x48
ex_Pressure=(long)(Pressure);
if(Pressure《0)
{
ex_Pressure=-ex_Pressure;
exchange_num[0]=‘-’;
}
else exchange_num[0]=‘\0’;
exchange_num[1]=ex_Pressure/100000+0x30;
ex_Pressure=ex_Pressure%100000;
exchange_num[2]=ex_Pressure/10000+0x30;
ex_Pressure=ex_Pressure%10000;
exchange_num[3]=ex_Pressure/1000+0x30;
ex_Pressure=ex_Pressure%1000;
exchange_num[4]=ex_Pressure/100+0x30;
ex_Pressure=ex_Pressure%100;
exchange_num[5]=‘?!?
exchange_num[6]=ex_Pressure/10+0x30;
ex_Pressure=ex_Pressure%10;
exchange_num[7]=ex_Pressure+0x30;
printf(“\nP : %c%c%c%c%c%c%c%c mbar \r\n”,exchange_num[0],exchange_num[1],exchange_num[2],exchange_num[3],exchange_num[4],exchange_num[5],exchange_num[6],exchange_num[7]);
// for(i=0;i《8;i++)
// {
// printf(“%c”,exchange_num[i]);
// }
// printf(“ mbar \r\n”);
printf(“T : %4.3f °C\r\n ”,Temperature/100);
}
評(píng)論
查看更多