搜索
bottom↓
回复: 22

有没有人用过MS5611这个气压计?

[复制链接]

出0入10汤圆

发表于 2013-7-18 09:11:15 | 显示全部楼层 |阅读模式
我在使用IIC调试MS5611的时候,使用资料上提供的时序可以复位MS5611, 也可以读取PROM  但是当我读取 压力值和温度值 的时候发送地址后芯片就没响应了,
那位大神知道是什么情况么?  


求51或stm32 程序...

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-7-22 00:15:40 | 显示全部楼层
D1,D2 转换需要时间



IICWriteByte(MS5611_ADDRESS, 0x58);
delay_us(10);
IICReadBytes(MS5611_ADDRESS, 0x00, 3, data);

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入10汤圆

 楼主| 发表于 2013-7-22 08:42:51 | 显示全部楼层
sxjclike 发表于 2013-7-22 00:15
D1,D2 转换需要时间

大侠呀  终于等到你了   求源程序。。。

我从开始转换后延时了10MS不过还是没能读出来   

把你的程序让小弟参考一下吧  谢谢了  

QQ:348611093@qq.com

出0入0汤圆

发表于 2013-7-22 14:28:50 | 显示全部楼层
小乔123 发表于 2013-7-22 08:42
大侠呀  终于等到你了   求源程序。。。

我从开始转换后延时了10MS不过还是没能读出来   

#include "MS5611.h"


///////////////////////////////////////

//#define OSR  256  // 0.60 mSec conversion time (1666.67 Hz)
//#define OSR  512  // 1.17 mSec conversion time ( 854.70 Hz)
//#define OSR 1024  // 2.28 mSec conversion time ( 357.14 Hz)
//#define OSR 2048  // 4.54 mSec conversion time ( 220.26 Hz)
  #define OSR 4096  // 9.04 mSec conversion time ( 110.62 Hz)

///////////////////////////////////////

uint16_t c1, c2, c3, c4,c5, c6;

int32_t d1;

int32_t d2;

int64_t dT;

void readTemperatureRequestPressure(void)
{
    uint8_t data[3];

    IICreadBytes2(MS5611_ADDRESS, 0x00, 3, data);    // Request temperature read

        d2 = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8)        | data[2];


    #if   (OSR ==  256)
            IICwriteByte2(MS5611_ADDRESS, 0x40);  // Request pressure conversion
        #elif (OSR ==  512)
            IICwriteByte2(MS5611_ADDRESS, 0x42);
        #elif (OSR == 1024)
            IICwriteByte2(MS5611_ADDRESS, 0x44);
        #elif (OSR == 2048)
            IICwriteByte2(MS5611_ADDRESS, 0x46);
        #elif (OSR == 4096)
            IICwriteByte2(MS5611_ADDRESS, 0x48);
    #endif
}

void readPressureRequestPressure(void)
{
    uint8_t data[3];

    IICreadBytes2(MS5611_ADDRESS, 0x00, 3, data);    // Request pressure read

           d1 = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8)        | data[2];

    #if   (OSR ==  256)
            IICwriteByte2(MS5611_ADDRESS, 0x40);  // Request pressure conversion
        #elif (OSR ==  512)
            IICwriteByte2(MS5611_ADDRESS, 0x42);
        #elif (OSR == 1024)
            IICwriteByte2(MS5611_ADDRESS, 0x44);
        #elif (OSR == 2048)
            IICwriteByte2(MS5611_ADDRESS, 0x46);
        #elif (OSR == 4096)
            IICwriteByte2(MS5611_ADDRESS, 0x48);
    #endif
}
void readPressureRequestTemperature(void)
{
    uint8_t data[3];

    IICreadBytes2(MS5611_ADDRESS, 0x00, 3, data);    // Request pressure read

        d1 = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8)        | data[2];

    #if   (OSR ==  256)
            IICwriteByte2(MS5611_ADDRESS, 0x50);  // Request pressure conversion
        #elif (OSR ==  512)
            IICwriteByte2(MS5611_ADDRESS, 0x52);
        #elif (OSR == 1024)
            IICwriteByte2(MS5611_ADDRESS, 0x54);
        #elif (OSR == 2048)
            IICwriteByte2(MS5611_ADDRESS, 0x56);
        #elif (OSR == 4096)
            IICwriteByte2(MS5611_ADDRESS, 0x58);
    #endif
}

///////////////////////////////////////////////////////////////////////////////
// Calculate Temperature
///////////////////////////////////////////////////////////////////////////////

int32_t calculateTemperature(void)
{
        int32_t dd;

    dT = d2 - ((int32_t)c5 << 8);

           dd =  2000 + (int32_t)((dT * c6 ) >> 23);

        return dd/10;
}

///////////////////////////////////////////////////////////////////////////////
// Calculate Pressure Altitude
///////////////////////////////////////////////////////////////////////////////

int32_t calculatePressureAltitude(void)
{
        int64_t offset;
        int32_t pressureAlt;
        int64_t sens;
        int32_t p;
//        int32_t d1Average = 110;

    offset  = ((uint32_t)c2 << 16) + ((c4 * (int64_t)dT) >> 7);
    sens    = ((uint32_t)c1 << 15) + ((c3 * (int64_t)dT) >> 8);
    p = (((d1 * sens) >> 21) - offset) >> 15;

    pressureAlt = (44330.0f * (1.0f - pow((float)p / 101325.0f, 0.190295f)));

        return p;
}

void MS5611_init(void)
{
    uint8_t data[2];

    IICwriteByte2(MS5611_ADDRESS, 0x1E);      // Reset Device

    delay_us(10);

    IICreadBytes2(MS5611_ADDRESS, 0xA2, 2, data);    // Read Calibration Data C1
        c1 = ((uint16_t)data[0] << 8) | data[1];

    IICreadBytes2(MS5611_ADDRESS, 0xA4, 2, data);    // Read Calibration Data C2
        c2 = ((uint16_t)data[0] << 8) | data[1];

    IICreadBytes2(MS5611_ADDRESS, 0xA6, 2, data);    // Read Calibration Data C3
        c3 = ((uint16_t)data[0] << 8) | data[1];

    IICreadBytes2(MS5611_ADDRESS, 0xA8, 2, data);    // Read Calibration Data C4
        c4 = ((uint16_t)data[0] << 8) | data[1];

    IICreadBytes2(MS5611_ADDRESS, 0xAA, 2, data);    // Read Calibration Data C5
        c5 = ((uint16_t)data[0] << 8) | data[1];

    IICreadBytes2(MS5611_ADDRESS, 0xAC, 2, data);    // Read Calibration Data C6
        c6 = ((uint16_t)data[0] << 8) | data[1];

    #if   (OSR ==  256)
        IICwriteByte2(MS5611_ADDRESS, 0x50);  // Request temperature conversion
    #elif (OSR ==  512)
        IICwriteByte2(MS5611_ADDRESS, 0x52);
    #elif (OSR == 1024)
        IICwriteByte2(MS5611_ADDRESS, 0x54);
    #elif (OSR == 2048)
        IICwriteByte2(MS5611_ADDRESS, 0x56);
    #elif (OSR == 4096)
        IICwriteByte2(MS5611_ADDRESS, 0x58);
    #endif

    delay_us(10);

        readTemperatureRequestPressure();
}

出0入0汤圆

发表于 2013-7-22 14:30:09 | 显示全部楼层
u8 IICwriteByte2(u8 dev, u8 data){
  
        IIC_Start();
        IIC_Send_Byte(dev<<1);           //发送写命令
        IIC_Wait_Ack();
        IIC_Send_Byte(data);   //发送地址
    IIC_Wait_Ack();          
       
        IIC_Stop();//产生一个停止条件

    return 1; //status == 0;
}
u8 IICreadBytes2(u8 dev, u8 cmd, u8 length, u8 *data){
    u8 count = 0;
       
        IIC_Start();
        IIC_Send_Byte(dev<<1);           //发送写地址
        IIC_Wait_Ack();
        IIC_Send_Byte(cmd);   //发送命令
    IIC_Wait_Ack();       
//        IIC_Stop();
          
        IIC_Start();
        IIC_Send_Byte(dev<<1|1);  //进入接收模式       
        IIC_Wait_Ack();
       
    for(count=0;count<length;count++){
                 
                 if(count!=length-1)data[count]=IIC_Read_Byte(1);  //带ACK的读数据
                         else  data[count]=IIC_Read_Byte(0);         //最后一个字节NACK
        }
    IIC_Stop();//产生一个停止条件
    return count;
}

出0入0汤圆

发表于 2013-7-22 14:31:20 | 显示全部楼层
sxjclike 发表于 2013-7-22 14:30
u8 IICwriteByte2(u8 dev, u8 data){
  
        IIC_Start();

        if((micros()-system_micrsecond)>upload_time)
        {
                frameCounter++;
                if (frameCounter > 5)
            frameCounter = 1;
                          
        if (frameCounter == 1)
        {
                    readPressureRequestTemperature();
        }
                else if (frameCounter == 2)
                {
            readTemperatureRequestPressure();
                }
        else if (frameCounter == 5)
        {           
                        Temperature = calculateTemperature(); //读取最近的温度值
                        Altitude = calculatePressureAltitude();//读取最近的高度值
        }
        else
        {
            readPressureRequestPressure();
        }
}

出0入10汤圆

 楼主| 发表于 2013-7-22 14:36:48 | 显示全部楼层
本帖最后由 小乔123 于 2013-7-22 14:41 编辑
sxjclike 发表于 2013-7-22 14:31
if((micros()-system_micrsecond)>upload_time)
        {
                frameCounter++;


你这什么单片机  晶振多少呢?  我先试试看

出0入0汤圆

发表于 2013-7-22 14:39:25 | 显示全部楼层
本帖最后由 sxjclike 于 2013-7-22 14:40 编辑

STM32F103 72M upload_time时间超过10ms就行

出0入10汤圆

 楼主| 发表于 2013-7-22 15:52:18 | 显示全部楼层
sxjclike 发表于 2013-7-22 14:39
STM32F103 72M upload_time时间超过10ms就行

你用的是正点原子的板子么   能不能直接给我发一下工程?
QQ:348611093

出0入10汤圆

 楼主| 发表于 2013-7-22 20:22:48 | 显示全部楼层
sxjclike 发表于 2013-7-22 14:39
STM32F103 72M upload_time时间超过10ms就行

哎  弄了半天  那天还能读出来PROM的值   现在只能复位芯片了

出0入10汤圆

 楼主| 发表于 2013-7-22 21:35:05 | 显示全部楼层
sxjclike 发表于 2013-7-22 14:39
STM32F103 72M upload_time时间超过10ms就行

你好  现在能读出来数据了 PROM的数据能读出来   RAM数据也能读出来  但是RAM中的数据一直在变化
哪一位都不是很稳定的那种  感觉一会减一会又变大 从60000多到20000多变化

请问你遇到这种情况么?

出0入0汤圆

发表于 2013-11-24 14:53:58 | 显示全部楼层
你好楼主,请问你的问题解决了吗,我也在弄5611,发现设置OSR不同时,输出的P也不同

出0入10汤圆

 楼主| 发表于 2013-11-24 19:23:02 | 显示全部楼层
PANGKUN 发表于 2013-11-24 14:53
你好楼主,请问你的问题解决了吗,我也在弄5611,发现设置OSR不同时,输出的P也不同 ...

你好  我QQ:348611093

出0入0汤圆

发表于 2013-11-24 20:10:55 | 显示全部楼层
我在百度文库搜到一个MS5611中文资料,把里面的51程序移植到1768上一切正常

出0入0汤圆

发表于 2013-11-24 21:34:51 | 显示全部楼层
#include "ms5611.h"

#define        MS561101BA_SlaveAddress   0xee          //定义器件在IIC总线中的从地址

#define        MS561101BA_D1      0x40
#define        MS561101BA_D2      0x50
#define        MS561101BA_RST     0x1E

#define        MS561101BA_D1_OSR_4096   0x48
#define        MS561101BA_D2_OSR_4096   0x58

#define MS561101BA_ADC_RD     0x00
#define        MS561101BA_PROM_RD           0xA0
#define MS561101BA_PROM_CRC   0xAE

u16 Cal_C[8];                                //存放PROM中的8个数据
u32 D1_Pres,D2_Temp;                //存放压力和温度
int32_t dTT,TEMP;                               
int64_t OFF_,SENS;
int64_t tPressure;                                //大气压
int64_t TEMP2,Aux,OFF2,SENS2,T2;        //温度校验

void MS5611_Reset(void)
{
        IIC_Start();
        IIC_Send_Byte(MS561101BA_SlaveAddress);
        IIC_Wait_Ack();
        IIC_Send_Byte(MS561101BA_RST);
        IIC_Wait_Ack();
        IIC_Stop();
}


void MS5611_PROM_Read(void)
{
        u8 d1,d2,i;
        for(i = 0;i <= 6;i ++)
        {
                IIC_Start();
                IIC_Send_Byte(MS561101BA_SlaveAddress);
                IIC_Wait_Ack();
                IIC_Send_Byte(MS561101BA_PROM_RD + i*2);
                IIC_Wait_Ack();
                //IIC_Stop();

                IIC_Start();
                IIC_Send_Byte(MS561101BA_SlaveAddress + 1);
                IIC_Wait_Ack();
                d1 = IIC_Read_Byte(1);        //OVER SEND ACK
                d2 = IIC_Read_Byte(0);        //OVER SEND NACK
                IIC_Stop();
                delay_ms(5);
                Cal_C[i] = ((u16)d1 << 8) | d2;
        }
}

u32 MS5611_DO_Conversion(u8 command)
{
        u32 conversion = 0;
        u32 conv1,conv2,conv3;

        IIC_Start();
        IIC_Send_Byte(MS561101BA_SlaveAddress);
        IIC_Wait_Ack();
        IIC_Send_Byte(command);
        IIC_Wait_Ack();
        IIC_Stop();
       
        delay_ms(100);
       
        IIC_Start();
        IIC_Send_Byte(MS561101BA_SlaveAddress);
        IIC_Wait_Ack();
        IIC_Send_Byte(0);
        IIC_Wait_Ack();

        IIC_Start();
        IIC_Send_Byte(MS561101BA_SlaveAddress + 1);
        IIC_Wait_Ack();
        conv1 = IIC_Read_Byte(1);                //ACK
        conv2 = IIC_Read_Byte(1);                //ACK
        conv3 = IIC_Read_Byte(0);                //NACK
        IIC_Stop();
        conversion = conv1 << 16 | conv2 << 8 | conv3;
        return conversion;
}


int64_t MS5611_GetTemperature(u8 OSR_Temp)
{
        D2_Temp = MS5611_DO_Conversion(OSR_Temp);
        delay_ms(10);
        dTT = D2_Temp - (((u32)Cal_C[5]) << 8);
        TEMP = 2000 + (dTT*((u32)Cal_C[6]) >> 23);
        return TEMP;
}

int64_t MS5611_GetPressure(u8 OSR_Pres)
{
        D1_Pres = MS5611_DO_Conversion(OSR_Pres);
        delay_ms(10);
        OFF_ = ((u32)Cal_C[2] << 16) + (((u32)Cal_C[4]*dTT) >> 7);
        SENS = ((u32)Cal_C[1] << 15) + (((u32)Cal_C[3]*dTT) >> 8);
        if(TEMP < 2000)                //温度小于20判定为低温区 采用二阶温度补偿
        {
                T2 = (dTT*dTT) >> 31;
                Aux = TEMP*TEMP;
                OFF2 = 2.5*Aux;
                SENS2 = 1.25*Aux;
                TEMP = TEMP - TEMP2;
                OFF_ = OFF_ - OFF2;
                SENS = SENS - SENS2;
        }
        tPressure = ((D1_Pres * SENS >> 21) - OFF_) >> 15;
        return         tPressure;
}
int64_t MS5611_GetAltitude()
{
   return         (44330.0f * (1.0f - pow((float)tPressure / 101325.0f, 0.190295f)));;
}
void MS5611_Init(void)
{
        //IIC_Init();
        MS5611_Reset();
        delay_ms(1000);
        MS5611_PROM_Read();
        delay_ms(1000);
}

出0入0汤圆

发表于 2014-2-15 15:28:56 | 显示全部楼层
你好。我能请教一下你IIC读取MS5611气压计值时候,使用到了带有ACK的函数IIC_Read_Byte();这个是你自己写的,还是库里带的,能参考一下嘛

出0入10汤圆

 楼主| 发表于 2014-2-15 16:51:33 | 显示全部楼层
xbcoastline 发表于 2014-2-15 15:28
你好。我能请教一下你IIC读取MS5611气压计值时候,使用到了带有ACK的函数IIC_Read_Byte();这个是你自己写的 ...

参考以前的IIC程序写的 ,就郭天祥的51程序

出0入0汤圆

发表于 2014-2-15 17:06:12 | 显示全部楼层
只有计算出温度和压强值才能看出对不对。

出0入0汤圆

发表于 2014-2-17 20:29:31 | 显示全部楼层
我现在用IIC读气压计的值还有问题。现在连MS5611的PROM值都读不出来,我的IIC还是不行

出0入0汤圆

发表于 2014-5-19 21:55:39 | 显示全部楼层
mark学习一下

出0入0汤圆

发表于 2014-10-26 14:18:03 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2014-11-11 16:58:35 | 显示全部楼层
正要学习  看一下   

出0入0汤圆

发表于 2014-11-18 17:11:36 | 显示全部楼层
没用过,帮顶
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-8 22:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表