Hi guys..
I am trying to interface BMP085 pressure sensor from BOSCH with msp430g2553. The data sheet for the sensor is here
www.adafruit.com/datasheets/BMP085_DataSheet_Rev.1.0_01July2008.pdf
It works on I2c protocol....
I am using CCS v5 as IDE. Below is my code..... But its not perfect.... It gets stuck in the middle......
#include<msp430g2553.h>
#include<inttypes.h>
#include "lcd.h"
#define True 1
#define False 0
char *I2c_Rx_Field,I2c_Tx;
signed char I2cByteCnt;
char ReadWriteN,RepStart,AddSent,Register,ByteSent,oversampling_setting_;
int16_t AC1, AC2, AC3, B1, B2, MB, MC, MD;
uint16_t AC4, AC5, AC6,UT;
int32_t temperature, pressure;
int32_t UP,X1,X2,B5,X3,B3,B6;
char oss_bit_;
uint32_t B4,B7;
void init_I2C(void);
int i2c_notready();
int16_t read_int16(char);
uint16_t read_uint16(char);
void bmp085_get_cal_param();
void set_OSS(int);
void get_ut();
void get_up();
void writei2c(char, char);
void readi2c(char, char* , char);
void initbmp085(void);
int32_t get_temperature();
int32_t get_pressure();
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1Mhz
DCOCTL = CALDCO_1MHZ;
P1SEL |= BIT1 + BIT2 + BIT6 + BIT7; // Assign I2C pins to USCI_B0 // Assign Uart pins to USCI_A0
P1SEL2 |= BIT1 + BIT2 + BIT6 + BIT7; // Assign I2C pins to USCI_B0 // Assign Uart pins to USCI_A0
init_I2C(); // initialize i2c
//initUart();//initialise uart mode
//_delay_cycles(1000000);
lcd_Init();
lcd_clear();
lcd_setCursor(0,0);
lcd_write("temperture");
lcd_setCursor(1,0);
lcd_write("pressure");
while(i2c_notready());
initbmp085();
while(1){
temperature=get_temperature();
pressure=get_pressure();
lcd_setCursor(0,10);
lcd_write("tempe");
lcd_setCursor(1,10);
lcd_write("press");
}
}
void init_I2C(void)
{
USICTL1 = USII2C;
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 10; // fSCL = 1Mhz/10 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA=0x77;
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
// UCB0I2CIE = UCNACKIE;
IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);
IE2 |= UCB0RXIE + UCB0TXIE; // Enable RX and TX interrupt
}
int i2c_notready(){
if(UCB0STAT & UCBBUSY) return 1;
else return 0;
}
void initbmp085(void)
{
bmp085_get_cal_param();
set_OSS(8);
get_ut();
get_up();
}
int16_t read_int16(char address)
{
char RXbf[16];
readi2c (address,RXbf,2);
return((int16_t)RXbf) ;
}
uint16_t read_uint16(char address)
{
char RXXbf[16];
readi2c(address,RXXbf,2);
return((uint16_t)RXXbf) ;
}
void bmp085_get_cal_param()
{
AC1 = read_int16(0xAA);
AC2 = read_int16(0xAC);
/*this is where the program flow stops...... I checked it using break points... it executes uptill here and stops..*/
AC3 = read_int16(0xAE);
AC4 = read_uint16(0xB0);
AC5 = read_uint16(0xB2);
AC6 = read_uint16(0xB4);
B1 = read_int16(0xB6);
B2 = read_int16(0xB8);
MB = read_int16(0xBA);
MC = read_int16(0xBC);
MD = read_int16(0xBE);
}
void set_OSS(int oss)
{
oss_bit_ = 3;
}
void get_ut()
{
char ut[16];
writei2c(0xF4,0x2E);
_delay_cycles(5000);
readi2c(0xF6,ut,2);
UT=(int16_t)ut;
}
void get_up()
{
char msb[16],lsb[16],xlsb[16];
writei2c(0xF4,0x34+(oss_bit_<<6));
_delay_cycles(5000);
readi2c(0xF6,msb,1);
readi2c(0xF7,lsb,1);
readi2c(0xF8,xlsb,1);
// up= (msb<<16+lsb<<8+xlsb);
UP=((int32_t)msb<<+(int32_t)lsb<<8+(int32_t)xlsb)>>(8-oss_bit_);
}
void writei2c(char address, char data)
{
// Reset variables prior to Start of Transmission
AddSent = False;
ReadWriteN = False;
ByteSent = False;
I2c_Tx = data; // Load Byte to be written to MPU
Register = address; // Load Internal Register Address
UCB0CTL1 |= UCTR + UCTXSTT; // send I2C start condition
__bis_SR_register(CPUOFF + GIE);
}
void readi2c(char address, char* value, char bytecnt)
{
// Reset variables prior to Start of Transmission
RepStart = False;
AddSent = False;
ReadWriteN = True;
I2cByteCnt = bytecnt; // Load number of byte to be read to Global variable
I2c_Rx_Field = value; // Copy pointer for String to be Read
Register=address;
UCB0CTL1 |= UCTR + UCTXSTT; // send I2C start condition
__bis_SR_register(CPUOFF + GIE);
}
int32_t get_temperature()
{
get_ut(); // uncompressed temperature
get_up(); // uncompressed pressure
long x1,x2;
//Start temperature calculation
x1 = ((UT - AC6) * AC5) >> 15;
x2 = (MC << 11) / (x1 + MD);
B5 = x1 + x2;
temperature = ((B5 + 8) >> 4);
return temperature;
}
int32_t get_pressure()
{
get_up(); // get uncompressed pressure (uncompressed temperature must be called recently)
B6 = B5 - 4000;
X1 = (B2 * ((B6 * B6) >> 12)) >> 11;
X2 = (AC2 * B6) >> 11;
X3 = X1 + X2;
B3 = ((((((long)(AC1) * 4) + X3) << oss_bit_) + 2) >> 2);
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_bit_));
if (B7 < 0x80000000)
pressure = (B7 << 1) / B4;
else
pressure = (B7 / B4) << 1;
X1 = (pressure >> 8);
X1 *= X1;
X1 = (X1 * 3038) >>16;
X2 = (-7357 * pressure) >>16;
pressure += (X1 + X2 + 3791)>>4;
return pressure;
}
// USCIAB0RX Interrupt Service Routine
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
if (UCB0STAT & UCNACKIFG)
{ // send STOP if slave sends NACK
UCB0CTL1 |= UCTXSTP;
UCB0STAT &= ~UCNACKIFG;
}
else
{
return;
}
}
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
static unsigned char Index = 0;
// If ReadWriteN = True
// Read Operation
if (ReadWriteN)
{
if(RepStart == True && AddSent == True)
{
// If Index is not equal to last byte to read
// Keep reading
if(Index != I2cByteCnt)
{
*I2c_Rx_Field++ = UCB0RXBUF;
Index++;
if(Index==1)
{
Register = Register+1;
AddSent = False;
}
}
// Else Read Last byte and send stop condition
else
{
*I2c_Rx_Field = UCB0RXBUF;
UCB0CTL1 |= UCTXSTP; // send stop condition
while(UCB0CTL1 & UCTXSTP);
IFG2 &= ~(UCB0RXIFG|UCB0TXIFG);
Index = 0;
__bic_SR_register_on_exit(CPUOFF);
}
}
// Send the Register address Followed by the Repeated Start
else
{
// If Register Address has not been sent. Send Register Address
if(AddSent == False)
{
UCB0TXBUF = Register;
AddSent = True;
}
// If Register Address have been sent. Send Repeated Start.
else
{
IFG2 &= ~UCB0TXIFG;
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
RepStart = True;
}
}
}
// If ReadWriteN = False
// Write Operation
else
{
// Check if Register Address has been sent
// If True Start Writing to UCB0TXBUF
if(AddSent == True)
{
// Check if Data has been Written to UCB0TXBUF
// If True the send STOP condition
if(ByteSent == True)
{
UCB0CTL1 |= UCTXSTP; // send stop condition
IFG2 &= ~(UCB0TXIFG|UCB0RXIFG); // clear Tx flag
__bic_SR_register_on_exit(CPUOFF);
}
// Else Write Data to UCB0TXBUF
else
{
UCB0TXBUF = I2c_Tx;
ByteSent = True;
}
}
// If Register Address has not been sent. Send it
else
{
UCB0TXBUF = Register;
AddSent = True;
}
}
}
Can somebody help me......