单片机/MCU论坛
直播中

ben111

12年用户 2732经验值
擅长:MEMS/传感技术 嵌入式技术 模拟技术
私信 关注
[文章]

STM32F10X + MS5611 + JLink 测气压温度例程详解

硬件平台:STM32F10X + MS5611 + JLink
软件平台:Keil 4
一、基础知识
首先,MS5611是什么?
MS5611气压传感器是集合SPI和I²C(高达20 MHz)总线接口的高分辨率气压传感器,分辨率可达到10cm。内部有一个高线性度的压力传感器和一个超低功耗的24位AD。
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)。


这里,0b表示二进制,0x表示十六进制,数字前加0表示八进制。例如:
  '77' //是8进制表示' ',0可以省略,因为C,C++规定不允许使用斜杠加10进制数来表示字符;
  'x3F' //是16进制表示。这些都是C语言中的基础,不懂得请自行百度。
二、运行结果


三、相应模块
程序涉及的模块有:
RCC:复位及时钟控制模块,用于初始化STM32 USART外设时钟及IO口复用时钟;
IIC:模拟IIC 协议,好多人都说STM32的硬件IIC模块用不了,主要是因为STM32 的硬件 IIC 模块有个天生的 BUG,就是不能被中断,也就是IIC要处于中断的最高级,ST在自己后来的 DataSheet 中已经证实了这一点。
Delay:利用系统时钟Systick,也号称“滴答”,写的延时模块;
USART:串口模块;
MS5611:MS5611模块配置。
四:代码
RCC

[html] view plain copy


  • #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

[html] view plain copy


  • #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
  • }  
  •   
  • 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
  •     {  
  •    OutDate=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();//最后一个字节无需应答  
  •    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

[html] view plain copy


  • #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;                          //清空计数器           



回帖(3)

ben111

2017-8-18 13:31:14

MS5611
[html] view plain copy
#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 : rn");  
  printf("rnC1 = %drnC2 = %drnC3 = %drnC4 = %drnC5 = %drnC6 = %drn",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]='';  
  
    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 rn",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   rn");  
    printf("T : %4.3f      °Crn ",Temperature/100);  
      
}  

欢迎讨论,共同进步
举报

王栋春

2017-8-18 21:18:03
好资料 学习收藏一下              
举报

落伍的狼

2021-8-21 14:27:27

好资料 学习收藏一下
举报

更多回帖

×
20
完善资料,
赚取积分