STM32+MS5611测气压温度例程详解

嵌入式设计应用

127人已加入

描述

  一、基础知识

  首先,MS5611是什么

  MS5611气压传感器是由MEAS(瑞士)推出的一款SPI和I²C总线接口的新一代高分辨率气压传感器,分辨率可达到10cm。该传感器模块包括一个高线性度的压力传感器和一个超低功耗的24位Σ模数转换器(工厂校准系数)。

  计算温度:

  D2 = MS5611_DO_Conversion(OSR_Temp);

  delay_ms(10);

  dT = D2 - (((u32)c5)*256) ;

  Temperature = 2000 + dT*((float)c6)/8388608 ;

  计算大气压:

  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) //µ±Î¶ÈÖµTEMPСÓÚ2000ʱÐèÒª×öζȲ¹³¥

  {

  T2 = (float)(dT*dT)/0x80000000 ;

  Aux = (Temperature - 2000)*(Temperature - 2000) ;

  OFF2 = 2.5f*Aux ;

  SENS2 = 1.25f*Aux ;

  if(Temperature 《 -1500) //µ±Î¶ÈÖµTEMPСÓÚ-1500ʱÐèÒª×öζȲ¹³¥

  {

  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 ;

  海拔计算:

  Altitude = (44330.0f*(1.0f - pow((float)Pressure/101325.0f, 0.190295f))) ;

  MS5611主要用于智能手机、海拔高度测量和导航辅助,做四轴的朋友一般都了解。

  其次,对于飞行器的姿态控制,我们使用GY-86 10DOF 的模块,里面带有MS5611 + MPU6050 + HMC5883,通过IIC协议读取数据进行操作。MS5611挂在MPU5060的从I2C接口上。MS5611的I2C地址为0b111011Cx,其中C比特位由CSB引脚决定,为CSB引脚的补码值(取反)。GY-86上 MS5611的CSB引脚接地,所以CSB引脚值为0,8位I2C地址为0b1110111x(0xEE),7位I2C地址为 0b1110111(0x77)。

 STM32

  这里,0b表示二进制,0x表示十六进制,数字前加0表示八进制。例如:

  ‘\077’ //是8进制表示‘ ’,0可以省略,因为C,C++规定不允许使用斜杠加10进制数来表示字符;

  ‘\0x3F’ //是16进制表示。这些都是C语言中的基础

  二、运行结果

 STM32

  三、相应模块

  程序涉及的模块有:

  RCC:复位及时钟控制模块,用于初始化STM32 USART外设时钟及IO口复用时钟;

  IIC:模拟IIC 协议,好多人都说STM32的硬件IIC模块用不了,主要是因为STM32 的硬件 IIC 模块有个天生的 BUG,就是不能被中断,也就是IIC要处于中断的最高级,ST在自己后来的 DataSheet 中已经证实了这一点。

  Delay:利用系统时钟SysTick,也号称“滴答”,写的延时模块;

  USART:串口模块;

  MS5611:MS5611模块配置。

  四:代码

  RCC

  #include “Rcc.h”

  void RCC_Init(void)

  {

  ErrorStatus HSEStartUpStatus;

  //定义枚举类型错误状态变量

  RCC_DeInit();//复位系统时钟设置

  RCC_HSEConfig(RCC_HSE_ON);

  //打开外部高速时钟晶振,使能HSE

  /*RCC_HSE_ON 开

  _off 关 _bypass hse晶振被外部时钟旁路*/

  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  /*RCC_WaitForHSEStartUp()返回一个ErrorStatus枚举值,

  success好,error未好*/

  if(HSEStartUpStatus == SUCCESS)//HES就绪

  {

  RCC_HCLKConfig(RCC_SYSCLK_Div1);

  //AHB时钟(HCLK)=系统时钟

  RCC_PCLK1Config(RCC_HCLK_Div2);

  //设置低速AHB时钟(APB1)为HCLK的2分频

  RCC_PCLK2Config(RCC_HCLK_Div1);

  //设置高速AHB时钟(APB2)=HCLK时钟

  FLASH_SetLatency(FLASH_Latency_2);

  //设置FLASH延时周期数为2

  //使能领取指缓存

  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

  //设置PLL时钟源及倍频系数,为HSE的9倍频 8MHz * 9 = 72MHz

  /*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul)

  RCC_PLLSource_HSI_Div2 pll输入时钟=hsi/2;

  RCC_PLLSource_HSE_Div1 pll输入时钟 =hse

  RCC_PLLSource_HSE_Div2 pll输入时钟=hse/2

  RCC_PLLMul_2 ------_16 pll输入时钟*2---16

  pll输出时钟不得超过72MHZ*/

  RCC_PLLCmd(ENABLE);

  //ENABLE / DISABLE

  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待PLL输出稳定

  /*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG) 检查指定RCC标志位

  返回SET OR RESET

  RCC_FLAG_HSIRDY HSI晶振就绪

  RCC_FLAG_HSERDY

  RCC_FLAG_PLLRDY

  RCC_FLAG_LSERDY

  RCC_FLAG_LSIRDY.。。。。。.*/

  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  //设置PLL为系统时钟源

  /*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) 设置系统时钟

  RCC_SYSCLKSource_HSI

  RCC_SYSCLKSource_HSE

  RCC_SYSCLKSource_PLLCLK 选HSI HSE PLL 作为系统时钟*/

  while(RCC_GetSYSCLKSource() != 0x08);

  //判断PLL是否是系统时钟

  /*u8 RCC_GetSYSCLKSource(void) 返回用作系统时钟的时钟源

  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 时钟在APB1

  //打开GPIO时钟,复用功能,串口1的时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟

  //好奇怪,是因为官方的库函数更新?

  //不是说F10X系列只有一个CAN,而F4有CAN1 CAN2 吗?

  //怎么他的系统配置文件里面是can1?????

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

  /*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)

  enable 或 disable apb2 外设时钟

  RCC_APB2Periph_AFIO 功能复用IO 时钟

  RCC_APB2Periph_GPIOA/B/C/D/E GPIOA/B/C/D/E 时钟

  RCC_APB2Periph_ADC1/ADC2 ADC1/2 时钟

  RCC_APB2Periph_TIM1

  RCC_APB2Periph_SPI1

  RCC_APB2Periph_USART1

  RCC_APB2Periph_ALL 全部APB2外设时钟*/

  }

  IIC

  #include “myIIC.h”

  unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address); //从24c02的地址address中读取一个字节数据

  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延时1.5us//这里可以优化速度 ,经测试最低到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)//检测从机应答信号

  {

  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();//最后一个字节无需应答

  }

  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();//最后一个字节无需应答

  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();//最后一个字节无需应答

  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引脚输入输出设置

  {

  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延时倍乘数

  static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数

  //初始化延迟函数

  //SYSTICK的时钟固定为HCLK时钟的1/8

  //SYSCLK:系统时钟

  void delay_init()

  {

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8

  fac_us=SystemCoreClock/8000000; //为系统时钟的1/8

  fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数

  }

  //延时nus

  //nus为要延时的us数。

  void delay_us(u32 nus)

  {

  u32 temp;

  SysTick-》LOAD=nus*fac_us; //时间加载

  SysTick-》VAL=0x00; //清空计数器

  SysTick-》CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数

  do

  {

  temp=SysTick-》CTRL;

  }while((temp&0x01)&&!(temp&(1《《16))); //等待时间到达

  SysTick-》CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器

  SysTick-》VAL =0X00; //清空计数器

  }

  //延时nms

  //注意nms的范围

  //SysTick-》LOAD为24位寄存器,所以,最大延时为:

  //nms《=0xffffff*8*1000/SYSCLK

  //SYSCLK单位为Hz,nms单位为ms

  //对72M条件下,nms《=1864

  void delay_ms(u16 nms)

  {

  u32 temp;

  SysTick-》LOAD=(u32)nms*fac_ms; //时间加载(SysTick-》LOAD为24bit)

  SysTick-》VAL =0x00; //清空计数器

  SysTick-》CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数

  do

  {

  temp=SysTick-》CTRL;

  }while((temp&0x01)&&!(temp&(1《《16))); //等待时间到达

  SysTick-》CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器

  SysTick-》VAL =0X00; //清空计数器

  }

  MS5611

  #include “MS5611.h”

  /*宏定义------------------------------------------------------------------*/

  //定义器件在IIC总线中的从地址,根据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内部地址

  // 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组数据

  uint32_t D1_Pres,D2_Temp; // 存放数字压力和温度

  float Pressure; //温度补偿大气压

  float dT,Temperature,Temperature2;//实际和参考温度之间的差异,实际温度,中间值

  double OFF,SENS; //实际温度抵消,实际温度灵敏度

  float Aux,OFF2,SENS2; //温度校验值

  uint32_t ex_Pressure; //串口读数转换值

  uint8_t exchange_num[8];

  /*函数声明----------------------------------------------------------------*/

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

  /************************************************************

  * 函数名:MS561101BA_Reset

  * 描述 : 复位

  * 输入 :无

  * 输出 :无

  */

  void MS561101BA_Reset(void)

  {

  I2C_NoAddr_WriteByte(MS561101BA_ADDR,MS561101BA_RESET);

  }

  /************************************************************

  * 函数名:MS561101BA_readPROM

  * 描述 : 从PROM读取出厂校准数据

  * 输入 :无

  * 输出 :无

  */

  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]);

  }

  /************************************************************

  * 函数名:MS561101BA_DO_CONVERSION

  * 描述 :

  * 输入 :无

  * 输出 :无

  */

  uint32_t MS561101BA_DO_CONVERSION(uint8_t command)

  {

  uint32_t conversion;

  I2C_NoAddr_WriteByte(MS561101BA_ADDR,command);

  delay_ms(10);//延时,去掉数据错误

  conversion=I2C_Read_3Bytes(MS561101BA_ADDR,0);

  return conversion;

  }

  /************************************************************

  * 函数名:MS561101BA_GetTemperature

  * 描述 : 读取数字温度

  * 输入 :过采样率

  * 输出 :无

  */

  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°

  }

  /************************************************************

  * 函数名:MS561101BA_GetPressure

  * 描述 : 读取数字气压

  * 输入 :过采样率

  * 输出 :无

  */

  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;

  //温度补偿

  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;

  }

  /************************************************************

  * 函数名:MS561101BA_Init

  * 描述 : MS561101BA初始化

  * 输入 :无

  * 输出 :无

  */

  void MS561101BA_Init(void)

  {

  MS561101BA_Reset();

  delay_ms(100);

  MS561101BA_readPROM();

  delay_ms(100);

  }

  /************************************************************

  * 函数名:SampleANDExchange

  * 描述 : 读取数据并转换串口发送

  * 输入 :无

  * 输出 :无

  */

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

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分