在msp430上使用BMP085

本文详细介绍了如何在msp430微控制器上使用BMP085气压传感器,包括软件实现IIC通信的具体代码和注意事项。通过实例讲解了如何读取温度和压力数据,并进行大气压强和海拔高度的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在msp430上使用BMP085


属于msp430的软件实现IIC的应用。记得当初调试的时候,对着示波器看了好久的时钟。在不同单片机上使用时一定要注意时钟大小,注意SDK与SDA是否按手册上给出的波形变化。

使用器件型号:msp430F169/msp430F149,BMP085@BOSCH
典型应用电路:

bmp.c

#include <msp430x16x.h>
#include "BMP.h"
#include <math.h>
//大气压强传感器
//参数定义
long  pressure,temperature;
float altitude;
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_ms(unsigned long nValue)
{
    unsigned long nCount=106;
    int i;
    unsigned long j;
    for(i = nValue;i > 0;i--)
    {
    	for(j = nCount;j > 0;j--);
    }
}

 
/**************************************
起始信号
**************************************/
void Start()
{
    pSCL_OUT;   
    pSDA_OUT;
    
    pSCL_H; 
	pSDA_H;                 
    Delay_ms(4);               
    pSDA_L;                  
   	Delay_ms(4);                
   	pSCL_L;   
}
//
//void Start()
//{
//    SCL_OUT;   
//    SDA_OUT;
//    
//    SCL_H;                
//    Delay_ms(2);
//    SDA_H;                   
//    Delay_ms(2);               
//    SDA_L;                  
//   	Delay_ms(2);                
//   	SCL_L;
//	Delay_ms(2);     
//}

/**************************************
停止信号
**************************************/
void Stop()
{
	pSDA_OUT;
	pSCL_H;
//  	SCL_L; 
	pSDA_L;
	Delay_ms(4);
	pSCL_H;
	pSDA_H;
	Delay_ms(4);
}

/**************************************
发送应答信号 
**************************************/
void SendACK(void)
{   
  	pSCL_L;
  	pSDA_OUT;
  	
    pSDA_L;
    Delay_ms(2);
	pSCL_H;
    Delay_ms(2);
  	pSDA_L;
}
void SendNoACK(void)
{   
  	pSCL_L;
  	pSDA_OUT;
  	
    pSDA_H;
	Delay_ms(2);
	pSCL_H;
    Delay_ms(2);
    pSCL_L;
   
}

/**************************************
接收应答信号
**************************************/
uint8_t RecvACK()
{
	char ucErrTime=0;
	
	pSCL_L;Delay_ms(2);/////////////////////
        pSDA_IN; 
	pSCL_H;Delay_ms(2);
	
	while(pSDA_RIN)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			Stop();
			return 1;
		}
	}
	pSCL_L;
	Delay_ms(2);
	return 0;
//	SDA_IN;
//	Delay_ms(2);
//	_NOP();
//    _NOP();
//    _NOP();
//    _NOP();
//	t=SDA_RIN;
//	Delay_ms(2);
//	_NOP();
//   _NOP();
//    _NOP();
//    _NOP();
    
//	SCL_L;
//	Delay_ms(2);
}

 

/**************************************
向IIC总线发送一个字节数据
**************************************/ 
//void SendByte(uint8_t dat)
//{
//  uint8_t i;
// 
//  SDA_OUT;
//  
//   for (i=0; i<8; i++)         //8位计数器
//    {
//    	if((dat& 0x80)>>7)
//        	SDA_H;
//    	else
//       		SDA_L;
//       	dat<<=1;
//       	Delay_ms(2);
//    	SCL_H;
//     	Delay_ms(2);
//     	SCL_L;
//     	Delay_ms(2);
//    }
//   RecvACK();
// 
//}

void SendByte(uint8_t dat)
{
  uint8_t i;
 
  pSDA_OUT;
  
   for (i=0; i<8; i++)         //8位计数器
    {
    	pSCL_L;
     	Delay_ms(2);
    	if((dat& 0x80)>>7)
        	pSDA_H;
    	else
       		pSDA_L;
       	dat<<=1;
       	Delay_ms(2);
    	pSCL_H;
     	Delay_ms(2);
     	
    }
    pSCL_L;
    Delay_ms(2);
    pSDA_H;
    Delay_ms(2);
   	RecvACK();
 
}


uint8_t RecvByte()
{
	uint8_t i,dat=0;
  
	pSDA_IN;
	Delay_ms(2);
  	for(i=0;i<8;i++)
  	{
  		pSCL_L;
    	Delay_ms(2);
    	pSCL_H;
    	dat<<=1;
    	if(pSDA_RIN)dat++;
    	Delay_ms(1);
  	}

	pSDA_OUT;
  	return dat;
}

short Multiple_read(uint8_t ST_Address)
{
    
uint8_t msb, lsb;
short _data;
    Start();                          //起始信号
    SendByte(0xEE);    //发送设备地址+写信号
    SendByte(ST_Address);             //发送存储单元地址
    Start();                          //起始信号
    SendByte(0xEF);         //发送设备地址+读信号
    msb = RecvByte();                 //BUF[0]存储
    SendACK();                       //回应ACK
    lsb = RecvByte();    
    SendNoACK();                      //最后一个数据需要回NOACK
    Stop();                           //停止信号
    Delay_ms(5);
    
    _data = ((short)msb) << 8;
    _data |= lsb;
   return _data;
 }
  
  long bmp085ReadTemp(void)
{
 
 
    Start();                  //起始信号
    SendByte(0xEE);   //发送设备地址+写信号
    SendByte(0xF4);          // write register address
    SendByte(0x2E);       // write register data for temp
    Stop();                   //发送停止信号
    Delay_ms(5);
   // max time is 4.5ms
 
return (long) Multiple_read(0xF6);
 
 
}
 
long bmp085ReadPressure(void)
{
 
long pressure = 0;
 
    Start();                   //起始信号
    SendByte(0xEE);   //发送设备地址+写信号
    SendByte(0xF4);          // write register address
    SendByte(0x34);         // write register data for pressure
    Stop();                    //发送停止信号
    Delay_ms(5);           // max time is 4.5ms
    
pressure = (long) Multiple_read(0xF6);
pressure &= 0x0000FFFF;
 
return pressure;
 
}
 

void Init_BMP085(void)
{
  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 bmp085_calc_pressure

void bmp085Convert()
{
 
unsigned int ut;
unsigned long up;
long x1, x2, b5, b6, x3, b3, p;
unsigned long b4, b7;

ut = bmp085ReadTemp();    
ut = bmp085ReadTemp();   // 读取温度
up = bmp085ReadPressure();  // 读取压强

  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long) mc << 11) / (x1 + md);
  b5 = x1 + x2;
  temperature = ((b5 + 8) >> 4);
  
  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
   
  // Calculate B4
  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<<1)/b4;
  else
    p = (b7/b4)<<1;
     
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  pressure = p+((x1 + x2 + 3791)>>4);
  altitude=44330 * (1-pow((p/ 101325.0),(1.0/5.255)));  
}

void uint_uart(void)
{
  P5SEL = 0x00;
  //P5SEL |=BIT2;
 // P5SEL &=~ BIT1;
 // P5DIR &=~BIT1;
  P5DIR |= BIT1+BIT2;
  BCSCTL1=(XT2OFF+RSEL2);
  DCOCTL=DCO2;
  pSCL_OUT;
  pSDA_OUT;
  pSCL_H;
  pSDA_H;
}

/***FUNC+*********************************************************************/
/* Name   : Init_CLK                                                         */
/* Descrp : Set PLL Clock.                                                   */
/* Input  : None.                                                            */   
/* Output : None.                                                            */
/* Return : None.                                                            */   
/***FUNC-*********************************************************************/
void Init_CLK(void)
{
    unsigned int iq0;
   //BCSCTL1&=~0X00;                      //打开XT2振荡器
   BCSCTL1 &= ~XT2OFF;         //打开XT振荡器
   do
   {
      IFG1 &= ~OFIFG;                   // 清除振荡器失效标志
      for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振
    }
    while ((IFG1 & OFIFG) != 0);        // 判断XT2是否起振
    //BCSCTL2 =SELM_2+SELS;               //选择MCLK、SMCLK为XT2
    BCSCTL2 |= SELM1+SELS;      //MCLK为8MHZ,SMCLK为8MHZ
}
int main()
{
 
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
	Init_CLK();//时钟初始化

   
	P5SEL = 0;
    // 将P1.4 P1.5 P1.6 P1.7设置为输出方向
    pSDA_OUT;
    pSCL_OUT;	
       Init_BMP085();
   while(1){
    bmp085Convert();
    //Delay_ms(5000);
   }
}

bmp.h

#ifndef _BMP_H_
#define _BMP_H_
/******************************** BMP085 **********************************************/	

#define BMP085_ADDRESS 		0xEE     //发送模块地址+W(表示写操作)					
#define BMP085_PROM_START__ADDR 0xAA
#define BMP085_CTRL_MEAS_REG    0xF4    //发送命令控制方式:发送寄存器地址  向固定的寄存器(0xF4)写特定值
#define BMP085_T_MEASURE        0x2E      // temperature measurent	
#define BMP085_P_MEASURE        0x34      // pressure measurement
#define BMP085_ADC_OUT_MSB_REG  0xF6     //读取数据方式:送寄存器地址     从特定的寄存器(Tab4.2的寄存器地址)读返回值
		
#define OSS 0   // 大气压的转换时间,有0-3可选值 								 
//类比温湿度传感器宏定义及其封装
#define pSDA_OUT  P5DIR |= BIT1
#define pSCL_OUT  P5DIR |= BIT0

#define pSDA_IN   P5DIR &=~BIT1
#define pSDA_RIN  (P5IN & BIT1)

#define pSDA_H P5OUT |= BIT1  //DATA <---> P2.2
#define pSDA_L P5OUT &=~ BIT1 

#define pSCL_H  P5OUT |= BIT0  //SCL  <---> P2.1
#define pSCL_L  P5OUT &=~ BIT0						 

typedef unsigned long  uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char  uint8_t;

//----------------------------------------------------------------
//Functions Declare
void Init_CLK(void);
/******************************** End of BMP085 **********************************************/	
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值