STM32+MS5611 detailed routine for measuring air pressure and temperature, test correct

Publisher:SereneMeadow7Latest update time:2018-07-06 Source: eefocusKeywords:STM32  MS5611 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Hardware platform: STM32F10X + MS5611 + JLink 

Software platform: Keil 4 

1. Basic knowledge

First of all, what is MS5611?

The MS5611 air pressure sensor is a high-resolution air pressure sensor that integrates SPI and I²C (up to 20 MHz) bus interfaces, with a resolution of up to 10 cm. It has a high-linearity pressure sensor and an ultra-low power 24-bit AD inside.

MS5611 is mainly used in smart phones, altitude measurement and navigation assistance, and friends who work with quad-axis are generally familiar with it.

Secondly, for the attitude control of the aircraft, we use the GY-86 10DOF module, which has MS5611 + MPU6050 + HMC5883, and reads data through the IIC protocol for operation. The MS5611 is hung on the slave I2C interface of the MPU5060. The I2C address of the MS5611 is 0b111011Cx, where the C bit is determined by the CSB pin and is the complement value of the CSB pin (inverted). The CSB pin of the MS5611 on the GY-86 is grounded, so the CSB pin value is 0, the 8-bit I2C address is 0b1110111x (0xEE), and the 7-bit I2C address is 0b1110111 (0x77).



Here, 0b indicates binary, 0x indicates hexadecimal, and a leading 0 indicates octal. For example:

  '\077' // is octal representation of ' ', 0 can be omitted, because C and C++ do not allow the use of slash plus decimal numbers to represent characters;

  '\0x3F' // is the hexadecimal representation. These are the basics of C language. If you don't understand, please search Baidu.

2. Operation Results



3. Corresponding modules

The modules involved in the program are:

RCC: reset and clock control module, used to initialize the STM32 USART peripheral clock and IO port multiplexing clock;

IIC: Simulate the IIC protocol. Many people say that the STM32 hardware IIC module cannot be used. This is mainly because the STM32 hardware IIC module has a natural BUG, ​​which is that it cannot be interrupted, that is, IIC must be at the highest level of interruption. ST has confirmed this in its later DataSheet.

Delay: Delay module written using the system clock SysTick, also known as "tick";

USART: serial port module;

MS5611: MS5611 module configuration.

Four: Code

RCC

  #include "Rcc.h"

  

  void RCC_Init(void)

  {  

   ErrorStatus HSEStartUpStatus;

   //Define enumeration type error status variable

    

   RCC_DeInit(); //Reset system clock settings

  

   RCC_HSEConfig(RCC_HSE_ON);

   //Turn on the external high-speed clock crystal and enable HSE

   /*RCC_HSE_ON on

   _off _bypass hse crystal oscillator is bypassed by external clock*/

    

   HSEStartUpStatus = RCC_WaitForHSEStartUp();

   /*RCC_WaitForHSEStartUp() returns an ErrorStatus enumeration value,

   Success is good, error is not good*/

  

   if(HSEStartUpStatus == SUCCESS) //HES is ready

   {  

   RCC_HCLKConfig(RCC_SYSCLK_Div1);

   //AHB clock (HCLK) = system clock

  

   RCC_PCLK1Config(RCC_HCLK_Div2);

   //Set the low-speed AHB clock (APB1) to 2 times the frequency of HCLK  

    

   RCC_PCLK2Config(RCC_HCLK_Div1);

   //Set high-speed AHB clock (APB2) = HCLK clock

    

   FLASH_SetLatency(FLASH_Latency_2);

   //Set the FLASH delay cycle number to 2

    

   // Enable receiving finger cache

   FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    

   RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

   //Set the PLL clock source and frequency multiplication factor to 9 times the HSE frequency 8MHz * 9 = 72MHz

   /*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul)

   RCC_PLLSource_HSI_Div2 pll input clock = hsi/2;

   RCC_PLLSource_HSE_Div1 PLL Input Clock = HSE

   RCC_PLLSource_HSE_Div2 PLL input clock = hse/2

    

   RCC_PLLMul_2 ------_16 pll input clock*2---16

   PLL output clock must not exceed 72MHZ*/  

    

   RCC_PLLCmd(ENABLE);

   //ENABLE  / DISABLE

    

   while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait for PLL output to stabilize

   /*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG) Check the specified RCC flag

   Return SET OR RESET

   RCC_FLAG_HSIRDY HSI crystal oscillator ready

   RCC_FLAG_HSERDY

   RCC_FLAG_PLLRDY

   RCC_FLAG_LSERDY 

   RCC_FLAG_LSIRDY.......*/  

    

   RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

   //Set PLL as system clock source

   /*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) Set the system clock

   RCC_SYSCLKSource_HSI 

   RCC_SYSCLKSource_HSE 

   RCC_SYSCLKSource_PLLCLK selects HSI HSE PLL as system clock*/  

    

   while(RCC_GetSYSCLKSource() != 0x08);

   //Judge whether PLL is the system clock

   /*u8 RCC_GetSYSCLKSource(void) Returns the clock source used as the system clock

   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 clock is in APB1

   //Turn on the GPIO clock, multiplexing function, the clock of serial port 1              

  

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable CAN1 clock

   //How strange, is it because the official library function is updated?

   //Doesn't it mean that the F10X series only has one CAN, while the F4 has CAN1 CAN2?

   //Why is can1 in his system configuration file? ? ? ? ?

    

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Clock enable

    

   /*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState) 

   Enable or disable apb2 peripheral clock

   RCC_APB2Periph_AFIO function multiplexing IO clock

   RCC_APB2Periph_GPIOA/B/C/D/E GPIOA/B/C/D/E Clock

   RCC_APB2Periph_ADC1/ADC2 ADC1/2 clock

   RCC_APB2Periph_TIM1 

   RCC_APB2Periph_SPI1

   RCC_APB2Periph_USART1 

   RCC_APB2Periph_ALL All APB2 peripheral clocks*/

  }


IIC

  #include "myIIC.h"

  

  

  unsigned char I2C_ReadByte(unsigned char DeviceAddr,unsigned char address); //Read a byte of data from the address address of 24c02

  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

  }

  

  void delay_nop(void)

  {

    unsigned int i=10; //i=10 delay 1.5us//The speed can be optimized here. After testing, it can still be written when the minimum is 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)//Detect slave response signal

  {

     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

   {

     OutDate[i]=iic_readx();

   if(i+1

   }

     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(); //The last byte does not need to be responded

     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(); //The last byte does not need to be responded

     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 as output

    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 pin input and output settings

  {

   GPIO_InitTypeDef  GPIO_InitStructure;

      if(io_set==0)

    {

    GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA as output

    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 as input

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Pull-up input

    GPIO_Init(GPIOB, &GPIO_InitStructure); 

    }

   else

    {;}

  }


DELAY

  #include "delay.h"

  

  static u8 fac_us=0; //us delay multiplier   

  static u16 fac_ms=0; //ms delay multiplier, under ucos, represents the number of ms per beat

  

     

  // Initialize delay function

  //SYSTICK clock is fixed to 1/8 of HCLK clock

  //SYSCLK: system clock

  void delay_init()

  {

   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //Select external clock HCLK/8

   fac_us=SystemCoreClock/8000000; //1/8 of the system clock 

  

   fac_ms=(u16)fac_us*1000; //Non-OS, represents the number of systick clocks required for each ms 

  }    

  

  //Delay nus

  //nus is the number of us to be delayed.       

  void delay_us(u32 nus)

  {

   u32 temp;      

   SysTick->LOAD=nus*fac_us; //Time loading    

   SysTick->VAL=0x00; //Clear the counter

   SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown  

   do

   {

   temp=SysTick->CTRL;

   }while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive   

   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter

   SysTick->VAL =0X00; //Clear the counter  

  }

  //Delay nms

  //Note the range of nms

  //SysTick->LOAD is a 24-bit register, so the maximum delay is:

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

  //SYSCLK is in Hz, nms is in ms

  //Under 72M conditions, nms<=1864 

  void delay_ms(u16 nms)

  {    

   u32 temp;   

   SysTick->LOAD=(u32)nms*fac_ms; //Time loading (SysTick->LOAD is 24bit)

   SysTick->VAL =0x00; //Clear the counter

   SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown  

   do

   {

   temp=SysTick->CTRL;

   }while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive   

   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter

   SysTick->VAL =0X00; //Clear the counter      


MS5611

  #include "MS5611.h"

  

  

  /*Macro definition------------------------------------------------------------------*/

  //Define the slave address of the device in the IIC bus and modify it according to the different CSB pins

  //#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)

  

  //Define the internal address of 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.

  

  

  /*Variable declaration----------------------------------------------------------------*/

  uint16_t Cal_C[7]; //Used to store 6 groups of data in PROM

  uint32_t D1_Pres,D2_Temp; //Store digital pressure and temperature

  float Pressure; //Temperature compensation atmospheric pressure

  float dT,Temperature,Temperature2; //Difference between actual and reference temperature, actual temperature, intermediate value

  double OFF,SENS; //actual temperature offset, actual temperature sensitivity

  float Aux,OFF2,SENS2; //temperature calibration value

  

  uint32_t ex_Pressure; //Serial port reading conversion value

  uint8_t  exchange_num[8];

  

  

  /*Function declaration----------------------------------------------------------------*/

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

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

  * Function name:MS561101BA_Reset   

  * Description: Reset  

  * Input: None   

  * Output: None    

  */ 

  void MS561101BA_Reset(void)

  {

   I2C_NoAddr_WriteByte(MS561101BA_ADDR,MS561101BA_RESET);

  }

  

  

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

  * Function name:MS561101BA_readPROM   

  * Description: Read factory calibration data from PROM

  * Input: None   

  * Output: None    

  */ 

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

  }

  

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

  * Function name:MS561101BA_DO_CONVERSION   

  * describe:  

  * Input: None   

  * Output: None    

  */

  uint32_t MS561101BA_DO_CONVERSION(uint8_t command)

  {

   uint32_t conversion;

  

   I2C_NoAddr_WriteByte(MS561101BA_ADDR,command);

    

   delay_ms(10); //delay, remove data errors

   

   conversion=I2C_Read_3Bytes(MS561101BA_ADDR,0);

  

     return conversion;

  

  }

  

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

  * Function name:MS561101BA_GetTemperature   

  * Description: Read digital temperature

  * Input: Oversampling rate   

  * Output: None    

  */

  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; //Calculate 100 times the temperature value, 2001 means 20.01°

  

  

  }

  

  

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

  * Function name:MS561101BA_GetPressure   

  * Description: Read digital air pressure

  * Input: Oversampling rate   

  * Output: None    

  */

  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;

   //Temperature compensation

   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;

   MEANING = MEANING - MEANING2;

  

   Pressure=(D1_Pres*SENS/2097152.0-OFF)/32768.0;

  

  }

  

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

  * Function name:MS561101BA_Init   

  * Description: MS561101BA initialization

  * Input: None   

  * Output: None    

  */ 

  void MS561101BA_Init(void)

  {

   MS561101BA_Reset();

   delay_ms(100);

   MS561101BA_readPROM();

   delay_ms(100);

  } 

  

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

  * Function name:SampleANDExchange   

  * Description: Read data and convert it to send via serial port

  * Input: None   

  * Output: None    

  */ 

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

    

  }



Keywords:STM32  MS5611 Reference address:STM32+MS5611 detailed routine for measuring air pressure and temperature, test correct

Previous article:stm32F4 encoder measures speed and prints through serial port --- program source code
Next article:stm32 timer pwm mode input capture

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号