用IIC通信读不出BMP085寄存器里的数据

2019-03-24 17:11发布

做毕设要用到气压传感器,所以买了bmp085和bmp180模块。用CC2430芯片作为控制器。晶振为32MHz。目前的程序是基于stc51的基础上修改的,针对晶振的不同修改了延时程序。另外对IO配置也做了改动。已经查了几天错,确认IO口没有问题,买的传感器没问题,VCC及IO口电压用电压表测得为3V。求懂行的大神指教。

以下程序在调用short Multiple_read(uchar ST_Address)函数时独出的值始终未257,另外接不接传感器他的值都不会发生变化。


/#include "app_ex_main.h"

#include "app_ex_util.h"

#include"temp.h"

#include  <math.h>    //Keil library  

#include  <stdlib.h>  //Keil library  

#include  <stdio.h>   //Keil library       

#define   uchar unsigned char

#define   uint unsigned int       

#define   DataPort P0    //LCD1602数据端口

#define   SCL  P1_3    //IIC时钟引脚定义

#define   SDA  P0_4

#define   LCM_RS P2_0  //LCD1602命令端口               

#define   LCM_RW P2_1   //LCD1602命令端口               

#define   LCM_EN P2_2   //LCD1602命令端口

#define CL_SDA P0_4=0

#define SET_SDA P0_4=1

#define IN_SDA P0_4

#define SET_OUT P0DIR|=0x10

#define SET_IN P0DIR&=~0x10

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

#define CL_DQ P0_4=0

#define SET_DQ P0_4=1

#define SET_OUT P0DIR|=0x10

#define SET_IN P0DIR&=~0x10

#define IN_DQ P0_4                          



#define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)

                                                          



uchar ge,shi,bai,qian,wan,shiwan;           //显示变量

int  dis_data;                              //变量



short ac1;

short ac2;

short ac3;

unsigned short ac4;

unsigned short ac5;

unsigned short ac6;

short b1;

short b2;

short mb;

short mc;

short md;



void delay(unsigned int k);

void InitLcd();                            //初始化lcd1602



void WriteDataLCM(uchar dataW);

void WriteCommandLCM(uchar CMD,uchar Attribc);

void DisplayOneChar(uchar X,uchar Y,uchar DData);

void conversion(long temp_data);



void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据

uchar Single_Read(uchar REG_Address);                                      //单个读取内部寄存器数据

void  Multiple_Read(uchar,uchar);                                          //连续的读取内部寄存器数据

//------------------------------------

void Delay5us();

void Delay5ms();

void BMP085_Start();

void BMP085_Stop();

void BMP085_SendACK(int ack);

int  BMP085_RecvACK();

void BMP085_SendByte(BYTE dat);

BYTE BMP085_RecvByte();

void BMP085_ReadPage();

void BMP085_WritePage();

//-----------------------------------



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



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

void delay(unsigned int k)       

{                                               

unsigned int i,j;                               

for(i=0;i<k;i++)

{                       

for(j=0;j<121;j++)                       

{;}}                                               

}

                       

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

                       

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



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

               

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



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

延时5微秒(STC90C52RC@12M)

不同的工作环境,需要调整此函数,注意时钟过快时需要修改

当改用1T的MCU时,请调整此延时函数

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

void Delay5us()

{int s;

    s=4;

while (s--)

{

    asm("NOP");

    asm("NOP");

    asm("NOP");

}

}



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

延时5毫秒(STC90C52RC@12M)

不同的工作环境,需要调整此函数

当改用1T的MCU时,请调整此延时函数

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

void Delay5ms()

{

    WORD n = 1600;



    while (n--);

}



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

起始信号

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

void BMP085_Start()

{

    SET_OUT ;

    SET_DQ;                   //拉高数据线

    SCL = 1;                    //拉高时钟线

    Delay5us();                 //延时

    CL_DQ;                    //产生下降沿

    Delay5us();                 //延时

    SCL = 0;                    //拉低时钟线

}



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

停止信号

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

void BMP085_Stop()

{   

    SET_OUT ;

    CL_DQ;                    //拉低数据线

    SCL = 1;                    //拉高时钟线

    Delay5us();                 //延时

    SET_DQ ;                    //产生上升沿

    Delay5us();                    //延时

}



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

发送应答信号

入口参数:ack (0:ACK 1:NAK)

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

void BMP085_SendACK(int ack)

{

    SET_OUT ;

    IN_DQ = ack;                  //写应答信号

    SCL = 1;                    //拉高时钟线

     Delay5us();                 //延时

    SCL = 0;                    //拉低时钟线

  Delay5us();                    //延时

}



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

接收应答信号

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

int BMP085_RecvACK()

{

    SET_OUT ;

    SCL = 1;                    //拉高时钟线

    SET_IN;

    Delay5us();                 //延时



    CY = IN_DQ;                   //读应答信号

    SET_OUT;



    SCL = 0;                    //拉低时钟线

    Delay5us();                     //延时



    return CY;

}



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

向IIC总线发送一个字节数据

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

void BMP085_SendByte(BYTE dat)

{

    BYTE i;

    SET_OUT ;

    for (i=0; i<8; i++)         //8位计数器

    {

        dat <<= 1;              //移出数据的最高位

        IN_DQ = CY;               //送数据口

        SCL = 1;                //拉高时钟线

        Delay5us();             //延时

        SCL = 0;                //拉低时钟线

        Delay5us();             //延时

    }

    BMP085_RecvACK();

}



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

从IIC总线接收一个字节数据

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

BYTE BMP085_RecvByte()

{

    SET_OUT ;

    BYTE i;

    BYTE dat = 0;



    SET_DQ ;                    //使能内部上拉,准备读取数据,

    SET_IN;

    for (i=0; i<8; i++)         //8位计数器

    {

        dat <<= 1;

        SCL = 1;                //拉高时钟线

        Delay5us();             //延时

        dat |= IN_DQ;             //读数据               

        SCL = 0;                //拉低时钟线

        Delay5us();             //延时

    }

    SET_OUT;

    return dat;

}

/*

//单字节写入BMP085内部数据*******************************



void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)

{

    BMP085_Start();                  //起始信号

    BMP085_SendByte(SlaveAddress);   //发送设备地址+写信号

    BMP085_SendByte(REG_Address);    //内部寄存器地址

    BMP085_SendByte(REG_data);       //内部寄存器数据

    BMP085_Stop();                   //发送停止信号

}

*/

/*

//单字节读取BMP085内部数据********************************

uchar Single_Read(uchar REG_Address)

{  uchar REG_data;

    BMP085_Start();                          //起始信号

    BMP085_SendByte(BMP085_SlaveAddress);           //发送设备地址+写信号

    BMP085_SendByte(REG_Address);            //发送存储单元地址       

    BMP085_Start();                          //起始信号

    BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号

    REG_data=BMP085_RecvByte();              //读出寄存器数据

        BMP085_SendACK(1);   

        BMP085_Stop();                           //停止信号

    return REG_data;

}

*/

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

//读出BMP085内部数据,连续两个

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

short Multiple_read(uchar ST_Address)

{   

    uchar msb, lsb;

    short _data;

    BMP085_Start();                          //起始信号

    BMP085_SendByte(BMP085_SlaveAddress);    //发送设备地址+写信号

    BMP085_SendByte(ST_Address);             //发送存储单元地址

    BMP085_Start();                          //起始信号

    BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号



    msb = BMP085_RecvByte();                 //BUF[0]存储

    BMP085_SendACK(0);                       //回应ACK

    lsb = BMP085_RecvByte();     

        BMP085_SendACK(1);                       //最后一个数据需要回NOACK

    BMP085_Stop();                           //停止信号

    Delay5ms();

    _data = msb << 8;

        _data |= lsb;       

        return _data;



}

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

long bmp085ReadTemp(void)

{



    BMP085_Start();                  //起始信号

    BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号

    BMP085_SendByte(0xF4);                  // write register address

    BMP085_SendByte(0x2E);               // write register data for temp

    BMP085_Stop();                   //发送停止信号

        delay(50);        // max time is 4.5ms

       

        return (long) Multiple_read(0xF6);

}

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

long bmp085ReadPressure(void)

{

        long pressure = 0;



    BMP085_Start();                   //起始信号

    BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号

    BMP085_SendByte(0xF4);                  // write register address

    BMP085_SendByte(0x34);                 // write register data for pressure

    BMP085_Stop();                    //发送停止信号

        delay(50);                              // max time is 4.5ms

       

        pressure = Multiple_read(0xF6);

        pressure &= 0x0000FFFF;

       

        return pressure;       

        //return (long) bmp085ReadShort(0xF6);

}



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



//初始化BMP085,根据需要请参考pdf进行修改**************

void Init_BMP085()

{

        ac1 = Multiple_read(0xAA);

        ac2 = Multiple_read(0xAC);

        ac3 = Multiple_read(0xAE);

        ac4 = Multiple_read(0xB0);

        ac5 = Multiple_read(0xB2);

        ac6 = Multiple_read(0xB4);

        b1 =  Multiple_read(0xB6);

        b2 =  Multiple_read(0xB8);

        mb =  Multiple_read(0xBA);

        mc =  Multiple_read(0xBC);

        md =  Multiple_read(0xBE);

}

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

long bmp085Convert()

{

        Init_BMP085();                //初始化BMP085

        long ut;

        long up;

        long x1, x2, b5, b6, x3, b3, p;

        unsigned long b4, b7;

        long  temperature;

        long  pressure;

       

        ut = bmp085ReadTemp();           // 读取温度

        up = bmp085ReadPressure();  // 读取压强

       

        x1 = ((long)ut - ac6) * ac5 >> 15;

        x2 = ((long) mc << 11) / (x1 + md);

        b5 = x1 + x2;

        temperature = (b5 + 8) >> 4;



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



       

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

       

        b6 = b5 - 4000;

        x1 = (b2 * (b6 * b6 >> 12)) >> 11;

        x2 = ac2 * b6 >> 11;

        x3 = x1 + x2;

        b3 = (((long)ac1 * 4 + x3) + 2)/4;

        x1 = ac3 * b6 >> 13;

        x2 = (b1 * (b6 * b6 >> 12)) >> 16;

        x3 = ((x1 + x2) + 2) >> 2;

        b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;

        b7 = ((unsigned long) up - b3) * (50000 >> OSS);

        if( b7 < 0x80000000)

             p = (b7 * 2) / b4 ;

           else  

                    p = (b7 / b4) * 2;

        x1 = (p >> 8) * (p >> 8);

        x1 = (x1 * 3038) >> 16;

        x2 = (-7357 * p) >> 16;

         pressure = p + ((x1 + x2 + 3791) >> 4);



        return pressure;

}



此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
徐淑琴
1楼-- · 2019-03-24 23:56
哇塞    好棒啊    我想问问这个用了很多函数吗
jishuaihu
2楼-- · 2019-03-25 04:36
 精彩回答 2  元偷偷看……
ienglgge
3楼-- · 2019-03-25 06:59
看看传感器的外围电路是否正确。测量引脚的信号。保证硬件正确。再分析一下,读写数据的时序。最好用示波器看看传感器有没有应答。

一周热门 更多>